protected override IEnumerable<Toil> MakeNewToils()
        {
            //Set what will cause the job to fail:
            this.FailOnDestroyedOrForbidden(CorpseIndex);
            this.FailOnBurningImmobile(CorpseIndex);
            this.FailOn(() => !(pawn is Droid));

            //Reserve the corpse
            yield return Toils_Reserve.Reserve(CorpseIndex);
            //Go to the corpse
            yield return Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.ClosestTouch);
            Toil toil = new Toil();
            toil.initAction = () =>
                {
                    //Check if the pawn is set to strip bodies, if yes then strip it, otherwise skip this step
                    Droid droid = (Droid)pawn;
                    CremationWorker worker = droid.work.specialist.GetWorker<CremationWorker>();
                    if (worker.StripBodies)
                    {
                        Corpse corpse = (Corpse)TargetThingA;
                        if (corpse.AnythingToStrip())
                            corpse.Strip();
                    }
                };
            toil.defaultCompleteMode = ToilCompleteMode.Delay;
            toil.defaultDuration = 300;
            toil.WithEffect(() => DefDatabase<EffecterDef>.GetNamed("Cremate"), CorpseIndex);
            toil.WithSustainer(() => DefDatabase<SoundDef>.GetNamed("Recipe_Cremate"));
            toil.AddFinishAction(() => TargetA.Thing.Destroy());
            toil.FailOnBurningImmobile(CorpseIndex);
            toil.FailOnDestroyedOrForbidden(CorpseIndex);
            toil.AddEndCondition(() => this.ticksLeftThisToil <= 0 ? JobCondition.Succeeded : JobCondition.Ongoing);
            yield return toil;
        }
 public static Toil DoorUnLock( TargetIndex DoorInd )
 {
     var toil = new Toil();
     toil.defaultCompleteMode = ToilCompleteMode.Delay;
     toil.WithProgressBarToilDelay( DoorInd );
     toil.AddFinishAction( () =>
     {
         var door = toil.actor.CurJob.GetTarget( DoorInd ).Thing as Building_RestrictedDoor;
         var compLock = door.TryGetComp<CompLockable>();
         compLock.ChangeLockState( false );
     } );
     return toil;
 }
 protected override IEnumerable<Toil> MakeNewToils()
 {
     ToilFailConditions.FailOnMentalState(this, TargetIndex.A);
     Toil waitToil = new Toil();
     waitToil.initAction = delegate
     {
         waitToil.actor.pather.StopDead();
     };
     waitToil.defaultCompleteMode = ToilCompleteMode.Delay;
     waitToil.defaultDuration = this.CompReloader.reloaderProp.reloadTick;
     yield return waitToil;
     Toil toil = new Toil();
     toil.AddFinishAction(new Action(this.CompReloader.FinishReload));
     yield return toil;
     yield break;
 }
        protected override IEnumerable<Toil> MakeNewToils()
        {
            //Set what will cause the job to fail
            this.FailOnBurningImmobile(RepairStationIndex);
            this.FailOnDestroyedOrForbidden(RepairStationIndex);
            this.FailOn(delegate
            {
                return Repairee == null || !Repairee.ShouldGetRepairs;
            });

            //Reserve the repair station
            yield return Toils_Reserve.Reserve(RepairStationIndex);
            //Go to the repair station interaction cell
            yield return Toils_Goto.GotoThing(RepairStationIndex, PathEndMode.InteractionCell);
            //Make a new toil that sets the droid to repair mode, then wait until fully repaired
            Toil toil = new Toil();
            toil.FailOnDestroyedOrForbidden(RepairStationIndex);
            toil.FailOn(() =>
                {
                    return Repairee == null || RPS == null || Repairee.Pawn.Position != TargetThingA.InteractionCell || !RPS.IsAvailable(Repairee);
                });

            toil.initAction = () =>
                {
                    //Log.Message("initAction");
                    Repairee.BeingRepaired = true;
                    RPS.RegisterRepairee(Repairee);
                };
            toil.defaultCompleteMode = ToilCompleteMode.Never;
            toil.AddFinishAction(delegate
            {
                //Log.Message("Finish action");
                RPS.DeregisterRepairee(Repairee);
                Repairee.BeingRepaired = false;
            });
            toil.AddEndCondition(() =>
            {
                if (Repairee.ShouldGetRepairs)
                    return JobCondition.Ongoing;
                return JobCondition.Succeeded;
            });
            toil.WithEffect(DefDatabase<EffecterDef>.GetNamed("Repair"), TargetIndex.A);
            toil.WithSustainer(() => { return DefDatabase<SoundDef>.GetNamed("Interact_Repair"); });
            yield return toil;
        }
        public Toil CollectSand(int ticksToCollect)
        {
            var targetCell = CurJob.targetA.Cell;

            var toil = new Toil();
            toil.initAction = () =>
            {
                pawn.jobs.curDriver.ticksLeftThisToil =
                    Mathf.RoundToInt(ticksToCollect*pawn.GetStatValue(StatDef.Named("CollectingSpeed")));
            };
            toil.AddFinishAction(() =>
            {
                // remove designation
                var designation = Find.DesignationManager.DesignationAt(targetCell,
                    DefDatabase<DesignationDef>.GetNamed("CollectSand"));
                if (designation != null)
                {
                    Find.DesignationManager.RemoveDesignation(designation);
                }

                // replace terrain
                if (Find.TerrainGrid.TerrainAt(targetCell) == TerrainDef.Named("Sand"))
                    Find.TerrainGrid.SetTerrain(targetCell, DefDatabase<TerrainDef>.GetNamed("Gravel"));

                // spawn resources
                var SandYellow = ThingMaker.MakeThing(ThingDef.Named("PileSandYellow"));
                SandYellow.stackCount = Rand.RangeInclusive(20, 30);
                GenPlace.TryPlaceThing(SandYellow, targetCell, ThingPlaceMode.Near);

                // Rand.Value = Rand.Range(0, 1)
                if (Rand.Value < RareResourceSpawnChance)
                {
                    var SandWhite = ThingMaker.MakeThing(ThingDef.Named("PileSandWhite"));
                    SandWhite.stackCount = Rand.RangeInclusive(5, 10);
                    GenPlace.TryPlaceThing(SandWhite, targetCell, ThingPlaceMode.Near);
                }
            });
            toil.defaultCompleteMode = ToilCompleteMode.Delay;
            toil.FailOnCellMissingDesignation(CellInd, DefDatabase<DesignationDef>.GetNamed("CollectSand"));
            toil.WithEffect(() => EffecterDef.Named("CutStone"), CellInd);
            return toil;
        }
 protected override IEnumerable<Toil> MakeNewToils()
 {
     ICharge chargee = (ICharge)this.pawn;
     CompDroidCharger charger =TargetThingA.TryGetComp<CompDroidCharger>();
     yield return Toils_Reserve.Reserve(TargetIndex.A);
     Toil goToPad = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell);
     goToPad.AddFailCondition(() => { return !charger.IsAvailable(chargee); });
     yield return goToPad;
     Toil charge = new Toil();
     charge.initAction = () =>
         {
             if (charger.parent.InteractionCell != chargee.Parent.Position)
             {
                 pawn.jobs.EndCurrentJob(JobCondition.Errored);
             }
             else
             {
                 charger.BeginCharge(chargee);
                 chargee.ShouldUsePower = false;
             }
         };
     charge.defaultCompleteMode = ToilCompleteMode.Never;
     charge.AddFailCondition(() =>
         { return !charger.IsAvailable(chargee); });
     charge.AddEndCondition(() =>
         {
             if (!chargee.DesiresCharge)
             {
                 return JobCondition.Succeeded;
             }
             return JobCondition.Ongoing;
         });
     charge.AddFinishAction(() =>
         {
             charger.EndCharge();
             chargee.ShouldUsePower = true;
         });
     yield return charge;
 }
 private static Toil TakeFromSynthesier( TargetIndex ind, Pawn eater, Func<ThingDef,bool> validator, Func<ThingDef,ThingDef,int> sorter )
 {
     var synthesizer = (Building_AutomatedFactory) eater.jobs.curJob.GetTarget( ind ).Thing;
     var bestDef = synthesizer.BestProduct( validator, sorter );
     var takeFromSynthesizer = new Toil();
     //Log.Message( string.Format( "{0}.TakeMealFromSynthesizier( {1}, {2} )", eater == null ? "null" : eater.NameStringShort, synthesizer == null ? "null" : synthesizer.ThingID, bestDef == null ? "null" : bestDef.defName ) );
     if( bestDef == null )
     {
         takeFromSynthesizer.defaultCompleteMode = ToilCompleteMode.Delay;
         takeFromSynthesizer.AddEndCondition( () =>
             {
                 return JobCondition.Incompletable;
             }
         );
         takeFromSynthesizer.defaultDuration = 999;
     }
     else
     {
         takeFromSynthesizer.defaultCompleteMode = ToilCompleteMode.Delay;
         takeFromSynthesizer.AddFinishAction( () =>
             {
                 Thing thing = synthesizer.TryProduceThingDef( bestDef );
                 if( thing == null )
                 {
                     Log.Error( eater.Label + " unable to take " + bestDef.label + " from " + synthesizer.ThingID );
                     eater.jobs.curDriver.EndJobWith( JobCondition.Incompletable );
                 }
                 else
                 {
                     eater.carrier.TryStartCarry( thing );
                     eater.jobs.curJob.targetA = (TargetInfo) eater.carrier.CarriedThing;
                 }
             }
         );
         takeFromSynthesizer.defaultDuration = synthesizer.ProductionTicks( bestDef );
     }
     return takeFromSynthesizer;
 }
 public static Toil MonitorStation( TargetIndex StationInd, TargetIndex WardenInd )
 {
     var toil = new Toil();
     toil.defaultCompleteMode = ToilCompleteMode.Delay;
     toil.defaultDuration = Data.MonitorRemoteJobTicks;
     toil.WithProgressBarToilDelay( WardenInd );
     toil.AddFinishAction( () =>
     {
         var stationThing = toil.actor.CurJob.GetTarget( StationInd ).Thing;
         if( stationThing == null )
         {
             throw new Exception( "Target thing is null for Toils_SecurityStation.MonitorStation!" );
         }
         var stationComp = stationThing.TryGetComp<CompSecurityStation>();
         if( stationComp == null )
         {
             throw new Exception( "Target thing is missing CompSecurityStation for Toils_SecurityStation.MonitorStation!" );
         }
         stationComp.FinishMonitoring();
         Find.Reservations.Release( toil.actor.jobs.curJob.GetTarget( StationInd ), toil.actor );
     } );
     toil.tickAction = () =>
     {
         var stationThing = toil.actor.CurJob.GetTarget( StationInd ).Thing;
         if( stationThing == null )
         {
             throw new Exception( "Target thing is null for Toils_SecurityStation.MonitorStation!" );
         }
         var stationComp = stationThing.TryGetComp<CompSecurityStation>();
         if( stationComp == null )
         {
             throw new Exception( "Target thing is missing CompSecurityStation for Toils_SecurityStation.MonitorStation!" );
         }
         stationComp.UpdateMonitor();
     };
     return toil;
 }
 public static Toil DropCarriedPawnRightHere()
 {
     var toil = new Toil();
     toil.defaultCompleteMode = ToilCompleteMode.Instant;
     toil.AddFinishAction( () =>
     {
         var pawn = toil.actor;
         var carriedPawn = pawn.carrier.CarriedThing as Pawn;
         if( carriedPawn == null )
         {
             throw new Exception( string.Format( "{0} tried to drop pawn but carried thing isn't a pawn!", pawn.NameStringShort ) );
         }
         var cell = pawn.Position;
         Thing resultingThing;
         if( !pawn.carrier.TryDropCarriedThing( cell, ThingPlaceMode.Direct, out resultingThing ) )
         {
             if( !pawn.carrier.TryDropCarriedThing( cell, ThingPlaceMode.Near, out resultingThing ) )
             {
                 Log.Error( string.Format( "{0} tried to drop {1} but no free cells for placement near {2}", pawn.NameStringShort, carriedPawn.NameStringShort, cell.ToString() ) );
             }
         }
     } );
     return toil;
 }
            public bool MoveNext()
            {
                uint num = (uint)this.$PC;

                this.$PC = -1;
                switch (num)
                {
                case 0u:
                    this.EndOnDespawnedOrNull(TargetIndex.A, JobCondition.Incompletable);
                    if (base.HasChair)
                    {
                        this.EndOnDespawnedOrNull(TargetIndex.B, JobCondition.Incompletable);
                    }
                    if (base.HasDrink)
                    {
                        this.FailOnDestroyedNullOrForbidden(TargetIndex.C);
                        this.$current = Toils_Goto.GotoThing(TargetIndex.C, PathEndMode.OnCell).FailOnSomeonePhysicallyInteracting(TargetIndex.C);
                        if (!this.$disposing)
                        {
                            this.$PC = 1;
                        }
                        return(true);
                    }
                    break;

                case 1u:
                    this.$current = Toils_Haul.StartCarryThing(TargetIndex.C, false, false, false);
                    if (!this.$disposing)
                    {
                        this.$PC = 2;
                    }
                    return(true);

                case 2u:
                    break;

                case 3u:
                    chew            = new Toil();
                    chew.tickAction = delegate()
                    {
                        this.pawn.rotationTracker.FaceCell(base.ClosestGatherSpotParentCell);
                        this.pawn.GainComfortFromCellIfPossible();
                        JoyUtility.JoyTickCheckEnd(this.pawn, JoyTickFullJoyAction.GoToNextToil, 1f, null);
                    };
                    chew.handlingFacing      = true;
                    chew.defaultCompleteMode = ToilCompleteMode.Delay;
                    chew.defaultDuration     = this.job.def.joyDuration;
                    chew.AddFinishAction(delegate
                    {
                        JoyUtility.TryGainRecRoomThought(this.pawn);
                    });
                    chew.socialMode = RandomSocialMode.SuperActive;
                    Toils_Ingest.AddIngestionEffects(chew, this.pawn, TargetIndex.C, TargetIndex.None);
                    this.$current = chew;
                    if (!this.$disposing)
                    {
                        this.$PC = 4;
                    }
                    return(true);

                case 4u:
                    if (base.HasDrink)
                    {
                        this.$current = Toils_Ingest.FinalizeIngest(this.pawn, TargetIndex.C);
                        if (!this.$disposing)
                        {
                            this.$PC = 5;
                        }
                        return(true);
                    }
                    goto IL_1D9;

                case 5u:
                    goto IL_1D9;

                default:
                    return(false);
                }
                this.$current = Toils_Goto.GotoCell(TargetIndex.B, PathEndMode.OnCell);
                if (!this.$disposing)
                {
                    this.$PC = 3;
                }
                return(true);

IL_1D9:
                this.$PC = -1;
                return(false);
            }
 public static Toil Enslave( TargetIndex PrisonerInd, TargetIndex CollarInd )
 {
     var toil = new Toil();
     toil.defaultCompleteMode = ToilCompleteMode.Delay;
     toil.defaultDuration = 250;
     toil.WithProgressBarToilDelay( PrisonerInd );
     toil.AddFinishAction( () =>
     {
         try
         {
             var prisoner = toil.actor.CurJob.GetTarget( PrisonerInd ).Thing as Pawn;
             var collar = toil.actor.CurJob.GetTarget( CollarInd ).Thing as Apparel;
             var compPrisoner = prisoner.TryGetComp<CompPrisoner>();
             if(
                 ( prisoner == null ) ||
                 ( collar == null ) ||
                 ( compPrisoner == null )
             )
             {
                 throw new Exception(
                     string.Format(
                         "prisoner = {0}\n\tcollar = {1}\n\tcompPrisoner = {2}",
                         prisoner == null ? "null" : prisoner.ThingID,
                         collar == null ? "null" : collar.ThingID,
                         compPrisoner == null ? "null" : "valid" ) );
             }
             if( prisoner.apparel == null )
             {
                 throw new Exception( "Prisoner " + prisoner.Name + " is missing Pawn_ApparelTracker!" );
             }
             // Make sure the prisoner has worksettings
             if( prisoner.workSettings == null )
             {
                 prisoner.workSettings = new Pawn_WorkSettings( prisoner );
                 prisoner.workSettings.Disable( WorkTypeDefOf.Warden );
             }
             // Get the prisoners original faction and pawk kind
             compPrisoner.originalFaction = prisoner.Faction;
             compPrisoner.originalPawnKind = prisoner.kindDef;
             // Assign the prisoner faction and pawn kind then update guest status
             prisoner.SetFaction( Faction.OfPlayer );
             prisoner.kindDef = Data.PawnKindDefOf.Slave;
             prisoner.guest.SetGuestStatus( Faction.OfPlayer, true );
             // Now put the collar on the prisoner
             toil.actor.inventory.container.Remove( collar );
             compPrisoner.ForceApparelOnPawn( prisoner, collar );
             // Update the interaction mode
             prisoner.guest.interactionMode = PrisonerInteractionMode.NoInteraction;
             // Update doors
             Data.UpdateAllDoors();
         }
         catch( Exception e )
         {
             Log.Error( "Prisoners & Slaves :: Could not enslave prisoner!\n\t" + e.Message );
         }
     } );
     return toil;
 }
 public static Toil Restrain( TargetIndex PrisonerInd, TargetIndex RestraintInd )
 {
     var toil = new Toil();
     toil.defaultCompleteMode = ToilCompleteMode.Delay;
     toil.defaultDuration = 250;
     toil.WithProgressBarToilDelay( PrisonerInd );
     toil.AddFinishAction( () =>
     {
         try
         {
             var prisoner = toil.actor.CurJob.GetTarget( PrisonerInd ).Thing as Pawn;
             var restraint = toil.actor.CurJob.GetTarget( RestraintInd ).Thing as Apparel;
             var compPrisoner = prisoner.TryGetComp<CompPrisoner>();
             if(
                 ( prisoner == null ) ||
                 ( restraint == null ) ||
                 ( compPrisoner == null )
             )
             {
                 throw new Exception(
                     string.Format(
                         "prisoner = {0}\n\trestraint = {1}\n\tcompPrisoner = {2}",
                         prisoner == null ? "null" : prisoner.ThingID,
                         restraint == null ? "null" : restraint.ThingID,
                         compPrisoner == null ? "null" : "valid" ) );
             }
             if( prisoner.apparel == null )
             {
                 throw new Exception( "Prisoner " + prisoner.Name + " is missing Pawn_ApparelTracker!" );
             }
             // Put the restraint on the prisoner
             toil.actor.inventory.container.Remove( restraint );
             compPrisoner.ForceApparelOnPawn( prisoner, restraint );
         }
         catch( Exception e )
         {
             Log.Error( "Prisoners & Slaves :: Could not restrain pawn!\n\t" + e.Message );
         }
     } );
     return toil;
 }
 public static Toil FreeSlave( TargetIndex PrisonerInd, TargetIndex CollarInd )
 {
     var toil = new Toil();
     toil.defaultCompleteMode = ToilCompleteMode.Delay;
     toil.defaultDuration = 250;
     toil.WithProgressBarToilDelay( PrisonerInd );
     toil.AddFinishAction( () =>
     {
         try
         {
             var slave = toil.actor.CurJob.GetTarget( PrisonerInd ).Thing as Pawn;
             var collar = toil.actor.CurJob.GetTarget( CollarInd ).Thing as Apparel;
             var compPrisoner = slave.TryGetComp<CompPrisoner>();
             if(
                 ( slave == null ) ||
                 ( collar == null ) ||
                 ( compPrisoner == null )
             )
             {
                 throw new Exception(
                     string.Format(
                         "slave = {0}\n\tcollar = {1}\n\tcompPrisoner = {2}",
                         slave == null ? "null" : slave.ThingID,
                         collar == null ? "null" : collar.ThingID,
                         compPrisoner == null ? "null" : "valid" ) );
             }
             compPrisoner.RemoveApparelFromPawn( slave, collar, toil.actor.Position );
             if( slave.ownership != null )
             {
                 slave.ownership.UnclaimAll();
             }
             var faction = compPrisoner.originalFaction;
             if(
                 ( faction == null ) ||
                 ( faction == Faction.OfPlayer )
             )
             {   // Unknown faction or originally from the colony
                 // Pick outlander faction
                 faction = Find.FactionManager.FirstFactionOfDef( FactionDefOf.Outlander );
                 if( faction == null )
                 {   // No outlander faction, pick a random non-colony faction
                     Find.FactionManager.TryGetRandomNonColonyHumanlikeFaction( out faction, false );
                 }
             }
             // Update control flags
             compPrisoner.wasSlave = true;
             compPrisoner.freeSlave = false;
             slave.guest.released = true;
             slave.guest.interactionMode = PrisonerInteractionMode.NoInteraction;
             // Remove enslaved trait
             slave.story.traits.RemoveTrait( Data.TraitDefOf.Enslaved );
             if( slave.workSettings != null )
             {
                 slave.workSettings.Notify_GainedTrait();
             }
             // Adjust thoughts
             if(
                 ( slave.needs != null ) &&
                 ( slave.needs.mood != null ) &&
                 ( slave.needs.mood.thoughts != null )
             )
             {
                 slave.needs.mood.thoughts.memories.TryGainMemoryThought( Data.ThoughtDefOf.Freed );
             }
             // Restore faction
             slave.SetFaction( faction, null );
             // Restore PawnKindDef
             slave.kindDef = compPrisoner.originalPawnKind;
             // Update doors
             Data.UpdateAllDoors();
         }
         catch( Exception e )
         {
             Log.Error( "Prisoners & Slaves :: Could not free slave!\n\t" + e.Message );
         }
     } );
     return toil;
 }
        protected override IEnumerable <Toil> MakeNewToils()
        {
            yield return(Toils_Goto.GotoCell(TargetIndex.A, PathEndMode.Touch).FailOnForbidden(TargetIndex.A));

            var labelLoopStart = Toils_General.Label();
            var labelLoopEnd   = Toils_General.Label();

            yield return(labelLoopStart);

            yield return(Toils_General.Do(() =>
            {
                Zone_Growing zone = this.TargetA.Cell.GetZone(this.Map) as Zone_Growing;
                Thing thing = null;

                if (zone == null || !zone.AllContainedThings.Where(x => x is Plant && !x.HostileTo(this.pawn) && !x.IsForbidden(this.pawn) &&
                                                                   !((Plant)x).HarvestableNow && this.pawn.CanReserveAndReach(x, PathEndMode.Touch, Danger.None) && !listChecked.Contains(x.Position)).TryRandomElement(out thing))
                {
                    this.job.SetTarget(TargetIndex.A, LocalTargetInfo.Invalid);
                }
                else
                {
                    this.Map.reservationManager.Reserve(this.pawn, this.job, thing);
                    this.job.SetTarget(TargetIndex.A, thing);
                }
            }));

            yield return(Toils_Jump.JumpIf(labelLoopEnd, () => !this.job.targetA.IsValid || this.plantCount >= this.plantWant));

            yield return(Toils_Goto.GotoCell(TargetIndex.A, PathEndMode.Touch).FailOnDestroyedOrNull(TargetIndex.A));

            Toil gardening = new Toil().FailOnDestroyedNullOrForbidden(TargetIndex.A);

            gardening.defaultCompleteMode = ToilCompleteMode.Never;
            gardening.socialMode          = RandomSocialMode.SuperActive;
            gardening.WithProgressBar(TargetIndex.A, () => (float)workDone / workTotal);
            gardening.PlaySustainerOrSound(SoundDefOf.Interact_Sow);
            gardening.WithEffect(() => EffecterDefOf.Harvest_Plant, TargetIndex.A);
            gardening.initAction = () =>
            {
                this.workDone    = 0;
                this.reportState = Rand.Bool ? ReportStringState.A : ReportStringState.B;
            };
            gardening.tickAction = () =>
            {
                this.workDone++;
                this.pawn.skills.Learn(SkillDefOf.Plants, 0.01f);
                if (this.workDone >= workTotal)
                {
                    this.ReadyForNextToil();
                }
            };
            gardening.AddFinishAction(() =>
            {
                this.plantCount++;
                this.Map.reservationManager.Release(this.job.targetA, this.pawn, this.job);

                var plant     = this.job.targetA.Thing as Plant;
                plant.Growth += plant.GrowthRate * 2000f / (60000f * plant.def.plant.growDays);

                this.listChecked.Add(this.job.targetA.Cell);
                this.reportState = ReportStringState.None;
            });

            yield return(gardening);

            yield return(Toils_Jump.Jump(labelLoopStart));

            yield return(labelLoopEnd);

            yield break;
        }
Exemple #15
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            setup_ticks();

            //this.FailOn(() => PawnUtility.PlayerForcedJobNowOrSoon(pawn));
            this.FailOn(() => pawn.health.Downed);
            this.FailOn(() => pawn.IsBurning());
            this.FailOn(() => pawn.IsFighting());
            this.FailOn(() => pawn.Drafted);

            Toil findfapspot = new Toil
            {
                initAction = delegate
                {
                    pawn.pather.StartPath(Bed.Position, PathEndMode.OnCell);
                },
                defaultCompleteMode = ToilCompleteMode.PatherArrival
            };

            yield return(findfapspot);

            Toil fap = Toils_General.Wait(duration);

            fap.handlingFacing = true;
            fap.initAction     = delegate
            {
                Start();
            };
            fap.tickAction = delegate
            {
                --duration;
                if (pawn.IsHashIntervalTick(ticks_between_hearts))
                {
                    ThrowMetaIcon(pawn.Position, pawn.Map, ThingDefOf.Mote_Heart);
                }
                SexTick(pawn, null);
                SexUtility.reduce_rest(pawn, 1);
                if (duration <= 0)
                {
                    ReadyForNextToil();
                }
            };
            fap.AddFinishAction(delegate
            {
                End();
            });
            yield return(fap);

            yield return(new Toil
            {
                initAction = delegate
                {
                    SexUtility.Aftersex(pawn, xxx.rjwSextype.Masturbation);
                    if (!SexUtility.ConsiderCleaning(pawn))
                    {
                        return;
                    }

                    LocalTargetInfo own_cum = pawn.PositionHeld.GetFirstThing <Filth>(pawn.Map);

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

                    pawn.jobs.jobQueue.EnqueueFirst(clean);
                },
                defaultCompleteMode = ToilCompleteMode.Instant
            });
        }
 protected override IEnumerable<Toil> MakeNewToils()
 {
     // Just on the off-chance the rock is on fire...
     this.FailOnBurningImmobile( TargetIndex.A );
     // Reserve the target
     yield return Toils_Reserve.Reserve( TargetIndex.A );
     // Go to the target
     Toil toilGoto = Toils_Goto.GotoCell( TargetIndex.A, PathEndMode.Touch );
     // Fail going to the target if it becomes unreachable
     toilGoto.FailOn( ( Func< bool > )(() =>
         {
             if( pawn.CanReach( (TargetInfo)TargetLocA, PathEndMode.Touch, pawn.NormalMaxDanger() ) )
                 return false;
             return true;
         }));
     yield return toilGoto;
     // Now the work toil itself
     Toil toilWork = new Toil
     {
         // Continue until done
         defaultCompleteMode = ToilCompleteMode.Never,
         // When the job starts...
         initAction = new Action(() =>
             {
                 smoothTicks = 0;
             } ),
         // The work tick
         tickAction = new Action(() =>
             {
                 if( pawn.skills != null )
                 {
                     const float constructionXP = 0.11f / 5f;
                     const float miningXP = 0.11f / 5f;
                     const float artisticXP = 0.11f / 5f;
                     pawn.skills.Learn( SkillDefOf.Construction, constructionXP );
                     pawn.skills.Learn( SkillDefOf.Mining, miningXP );
                     pawn.skills.Learn( SkillDefOf.Artistic, artisticXP );
                 }
                 smoothTicks += 1;
                 if( smoothTicks < nextSmoothStrike ) return;
                 // Reset counter, damage rock
                 smoothTicks = 0;
                 mineable.HitPoints -= DamagePerStrike;
             } )
     };
     // When should we stop?
     toilWork.endConditions.Add( ( Func< JobCondition > )(() =>
         {
             // Go until the rock is fully damaged
             if( mineable.HitPoints > 0 ) return JobCondition.Ongoing;
             return JobCondition.Succeeded;
         } ) );
     // Do something when done
     toilWork.AddFinishAction( new Action(() =>
         {
             // If the job failed, abort
             if( mineable.HitPoints > 0 ) return;
             // Clear the designation at this cell
             Common.RemoveDesignationDefOfAt( SmoothWall.designationDef, TargetA.Cell );
             // Better have associated stone blocks...
             string blocksDef = "Blocks" + mineable.def.defName;
             ThingDef stoneBlocks = DefDatabase<ThingDef>.GetNamed( blocksDef, true );
             // Replace the rock with a stone wall
             var wallThing = ThingMaker.MakeThing( SmoothWall.thingDef, stoneBlocks );
             if( wallThing != null )
             {
                 var wall = GenSpawn.Spawn( wallThing, TargetA.Cell );
                 if( wall != null )
                 {
                 wall.SetFaction( Faction.OfPlayer );
                 }
             }
         } ) );
     // Some fun sounds while working
     toilWork.WithSustainer( ( Func< SoundDef > )(() =>
         {
             return SmoothWall.soundDef;
         } ) );
     // Some fun effects while working
     toilWork.WithEffect( "Mine", TargetIndex.A );
     yield return toilWork;
     // And we're done.
     yield break;
 }
Exemple #17
0
        Toil SowSeedToil()
        {
            var toil = new Toil();

            toil.defaultCompleteMode = ToilCompleteMode.Never;
            toil.initAction          = delegate {
                var actor = toil.actor;
                if (IsActorCarryingAppropriateSeed(actor, job.plantDefToSow))
                {
                    var plant = (Plant)GenSpawn.Spawn(job.plantDefToSow, TargetLocA, actor.Map);
                    plant.Growth = 0;
                    plant.sown   = true;

                    job.targetC = plant;

                    actor.Reserve(job.targetC, job, 1);

                    sowWorkDone = 0;
                }
                else
                {
                    EndJobWith(JobCondition.Incompletable);
                }
            };
            toil.tickAction = delegate {
                var actor = toil.actor;

                var plant = (Plant)job.targetC.Thing;

                if (actor.skills != null)
                {
                    actor.skills.Learn(SkillDefOf.Growing, 0.22f);
                }

                if (plant.LifeStage != PlantLifeStage.Sowing)
                {
                    Log.Error(this + " getting sowing work while not in Sowing life stage.");
                }

                sowWorkDone += StatExtension.GetStatValue(actor, StatDefOf.PlantWorkSpeed, true);

                if (sowWorkDone >= plant.def.plant.sowWork)
                {
                    if (!IsActorCarryingAppropriateSeed(actor, job.plantDefToSow))
                    {
                        EndJobWith(JobCondition.Incompletable);

                        return;
                    }

                    if (actor.carryTracker.CarriedThing.stackCount <= 1)
                    {
                        actor.carryTracker.CarriedThing.Destroy(DestroyMode.Cancel);
                    }
                    else
                    {
                        actor.carryTracker.CarriedThing.stackCount--;
                    }

                    if (actor.story.traits.HasTrait(TraitDefOf.GreenThumb))
                    {
                        actor.needs.mood.thoughts.memories.TryGainMemory(ThoughtDefOf.GreenThumbHappy, null);
                    }

                    plant.Growth = 0.05f;

                    plant.Map.mapDrawer.MapMeshDirty(plant.Position, MapMeshFlag.Things);

                    actor.records.Increment(RecordDefOf.PlantsSown);

                    ReadyForNextToil();
                }
            };
            toil.defaultCompleteMode = ToilCompleteMode.Never;
            toil.FailOnDespawnedNullOrForbidden(TargetIndex.A);
            toil.WithEffect(EffecterDefOf.Sow, TargetIndex.A);
            toil.WithProgressBar(TargetIndex.A, () => sowWorkDone / job.plantDefToSow.plant.sowWork, true, -0.5f);
            toil.PlaySustainerOrSound(() => SoundDefOf.Interact_Sow);
            toil.AddFinishAction(delegate {
                var actor = toil.actor;

                var thing = job.targetC.Thing;
                if (thing != null)
                {
                    var plant = (Plant)thing;
                    if (sowWorkDone < plant.def.plant.sowWork && !thing.Destroyed)
                    {
                        thing.Destroy(DestroyMode.Vanish);
                    }

                    actor.Map.reservationManager.Release(job.targetC, actor, job);

                    job.targetC = null;
                }
            });
            return(toil);
        }
Exemple #18
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
            });
        }
        /// <summary>
        /// Generates a series of actions (toils) that the pawn should perform.
        /// </summary>
        /// <returns>Ienumerable of type Toil</returns>
        /// <remarks>Remember that, in the case of jobs, effectively the entire method is executed before any actual activity occurs.</remarks>
        protected override IEnumerable <Toil> MakeNewToils()
        {
            // Error checking and 'helpful' messages for what is wrong.
            if (holder == null) // A later check will catch this (failon) but that fails silently.
            {
                Log.Error(errorBase + "TargetThingA is null.  A Pawn is required to perform a reload.");
                yield return(null);
            }
            if (weapon == null) // Required.
            {
                Log.Error(errorBase + "TargetThingB is null.  A weapon (ThingWithComps) is required to perform a reload.");
                yield return(null);
            }
            if (compReloader == null) // Required.
            {
                Log.Error(errorBase + pawn + " tried to do reload job on " + weapon.LabelCap + " which doesn't have a required CompAmmoUser.");
                yield return(null);
            }
            if (holder != pawn) // Helps restrict what this job does, not really necessary and may work fine (though possibly undesirable behavior) without this check.
            {
                Log.Error(errorBase + "TargetThingA (" + holder.Name + ") is not the same Pawn (" + pawn.Name + ") that was given the job.");
                yield return(null);
            }
            // get the state of the job (inventory vs other) at the start.
            reloadingInventory = weaponInInventory;
            reloadingEquipment = weaponEquipped;
            // A couple more more 'helpful' error check/message.
            if (!reloadingInventory && !reloadingEquipment) // prevent some bad states/behavior on FailOn and job text.
            {
                Log.Error(errorBase + "Unable to find the weapon to be reloaded (" + weapon.LabelCap + ") in the inventory nor equipment of " + pawn.Name);
                yield return(null);
            }
            if (reloadingInventory && reloadingEquipment) // prevent incorrect information on job text.  If somehow this was true may cause a FailOn to trip.
            {
                Log.Error(errorBase + "Something went spectacularly wrong as the weapon to be reloaded was found in both the Pawn's equipment AND inventory at the same time.");
                yield return(null);
            }

            // current state of equipment, want to interrupt the reload if a pawn's equipment changes.
            initEquipment = pawn.equipment?.Primary;

            // choose ammo to be loaded and set failstate for no ammo in inventory
            if (compReloader.UseAmmo)
            {
                this.FailOn(() => !compReloader.TryFindAmmoInInventory(out initAmmo));
            }

            // setup fail states, if something goes wrong with the pawn performing the reload, the weapon, or something else that we want to fail on.
            this.FailOnDespawnedOrNull(indReloader);
            this.FailOnMentalState(indReloader);
            this.FailOnDestroyedOrNull(indWeapon);
            this.FailOn(HasNoGunOrAmmo);
            this.FailOn(DisabledViolance);

            // Throw mote
            if (compReloader.ShouldThrowMote)
            {
                MoteMaker.ThrowText(pawn.Position.ToVector3Shifted(), Find.CurrentMap, string.Format("CE_ReloadingMote".Translate(), weapon.def.LabelCap));
            }

            //Toil of do-nothing
            Toil waitToil = new Toil()
            {
                actor = pawn
            };                                           // actor was always null in testing...

            waitToil.initAction          = () => waitToil.actor.pather.StopDead();
            waitToil.defaultCompleteMode = ToilCompleteMode.Delay;
            waitToil.defaultDuration     = Mathf.CeilToInt(compReloader.Props.reloadTime.SecondsToTicks() / pawn.GetStatValue(CE_StatDefOf.ReloadSpeed));
            yield return(waitToil.WithProgressBarToilDelay(indReloader));

            //Actual reloader
            Toil reloadToil = new Toil();

            reloadToil.AddFinishAction(() => compReloader.LoadAmmo(initAmmo));
            yield return(reloadToil);

            //Continue previous job if possible
            Toil continueToil = new Toil
            {
                defaultCompleteMode = ToilCompleteMode.Instant
            };

            yield return(continueToil);
        }
Exemple #20
0
        public static Toil ChewIngestible(Pawn chewer, float durationMultiplier, TargetIndex ingestibleInd, TargetIndex eatSurfaceInd = TargetIndex.None)
        {
            Toil toil = new Toil();

            toil.initAction = delegate
            {
                Pawn  actor = toil.actor;
                Thing thing = actor.CurJob.GetTarget(ingestibleInd).Thing;
                if (!thing.IngestibleNow)
                {
                    chewer.jobs.EndCurrentJob(JobCondition.Incompletable, true);
                    return;
                }
                actor.jobs.curDriver.ticksLeftThisToil = Mathf.RoundToInt((float)thing.def.ingestible.baseIngestTicks * durationMultiplier);
                if (thing.Spawned)
                {
                    thing.Map.physicalInteractionReservationManager.Reserve(chewer, actor.CurJob, thing);
                }
            };
            toil.tickAction = delegate
            {
                if (chewer != toil.actor)
                {
                    toil.actor.rotationTracker.FaceCell(chewer.Position);
                }
                else
                {
                    Thing thing = toil.actor.CurJob.GetTarget(ingestibleInd).Thing;
                    if (thing != null && thing.Spawned)
                    {
                        toil.actor.rotationTracker.FaceCell(thing.Position);
                    }
                    else if (eatSurfaceInd != TargetIndex.None && toil.actor.CurJob.GetTarget(eatSurfaceInd).IsValid)
                    {
                        toil.actor.rotationTracker.FaceCell(toil.actor.CurJob.GetTarget(eatSurfaceInd).Cell);
                    }
                }
                toil.actor.GainComfortFromCellIfPossible();
            };
            toil.WithProgressBar(ingestibleInd, delegate
            {
                Pawn actor  = toil.actor;
                Thing thing = actor.CurJob.GetTarget(ingestibleInd).Thing;
                if (thing == null)
                {
                    return(1f);
                }
                return(1f - (float)toil.actor.jobs.curDriver.ticksLeftThisToil / Mathf.Round((float)thing.def.ingestible.baseIngestTicks * durationMultiplier));
            }, false, -0.5f);
            toil.defaultCompleteMode = ToilCompleteMode.Delay;
            toil.FailOnDestroyedOrNull(ingestibleInd);
            toil.AddFinishAction(delegate
            {
                if (chewer == null)
                {
                    return;
                }
                if (chewer.CurJob == null)
                {
                    return;
                }
                Thing thing = chewer.CurJob.GetTarget(ingestibleInd).Thing;
                if (thing == null)
                {
                    return;
                }
                if (chewer.Map.physicalInteractionReservationManager.IsReservedBy(chewer, thing))
                {
                    chewer.Map.physicalInteractionReservationManager.Release(chewer, toil.actor.CurJob, thing);
                }
            });
            toil.handlingFacing = true;
            Toils_ItemBelt.AddIngestionEffects(toil, chewer, ingestibleInd, eatSurfaceInd);
            return(toil);
        }
Exemple #21
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            //--Log.Message("[RJW] JobDriver_RandomRape::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;
            bool pawnHasPenis = Genital_Helper.has_penis(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);
            }

            this.FailOnDespawnedNullOrForbidden(iTarget);
            this.FailOn(() => (!Target.health.capacities.CanBeAwake));                                  // || (!comfort_prisoners.is_designated (Prisoner)));
            this.FailOn(() => !pawn.CanReserve(Target, comfort_prisoners.max_rapists_per_prisoner, 0)); // Fail if someone else reserves the prisoner before the pawn arrives
            yield return(Toils_Goto.GotoThing(iTarget, PathEndMode.OnCell));

            Messages.Message(pawn.NameStringShort + " is trying to rape " + Target.NameStringShort + ".", pawn, MessageTypeDefOf.NegativeEvent);

            var rape = new Toil();

            rape.initAction = delegate
            {
                //pawn.Reserve(Target, comfort_prisoners.max_rapists_per_prisoner, 0);
                //if (!pawnHasPenis)
                //	Target.rotationTracker.Face(pawn.DrawPos);
                var dri = Target.jobs.curDriver as JobDriver_GettinRaped;
                if (dri == null)
                {
                    var gettin_raped = new Job(xxx.gettin_raped);
                    Target.jobs.StartJob(gettin_raped, JobCondition.InterruptForced, null, false, true, null);
                    (Target.jobs.curDriver as JobDriver_GettinRaped).increase_time(duration);
                }
                else
                {
                    dri.rapist_count += 1;
                    dri.increase_time(duration);
                }
                rape.FailOn(() => (Target.CurJob == null) || (Target.CurJob.def != xxx.gettin_raped));
            };
            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);
                }
            };
            rape.AddFinishAction(delegate
            {
                //// Trying to add some interactions and social logs
                xxx.processAnalSex(pawn, Target, ref isAnalSex, pawnHasPenis);

                if ((Target.jobs != null) &&
                    (Target.jobs.curDriver != null) &&
                    (Target.jobs.curDriver as JobDriver_GettinRaped != null))
                {
                    (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
                {
                    aftersex(pawn, Target, true, isAnalSex: isAnalSex);
                    pawn.mindState.canLovinTick = Find.TickManager.TicksGame + xxx.generate_min_ticks_to_next_lovin(pawn);
                    if (!Target.Dead)
                    {
                        Target.mindState.canLovinTick = Find.TickManager.TicksGame + xxx.generate_min_ticks_to_next_lovin(Target);
                    }
                },
                defaultCompleteMode = ToilCompleteMode.Instant
            });
        }
        protected override IEnumerable <Toil> MakeNewToils()
        {
            Pawn student     = TargetA.Thing as Pawn;
            Toil gotoStudent = new Toil()
            {
                initAction = () =>
                {
                    pawn.pather.StartPath(TargetA, PathEndMode.Touch);
                },
                defaultCompleteMode = ToilCompleteMode.PatherArrival
            };

            yield return(gotoStudent);

            Toil doTeaching = new Toil();

            doTeaching.initAction = delegate
            {
                CompAbilityUserMagic compMagic = student.GetComp <CompAbilityUserMagic>();
                CompAbilityUserMight compMight = student.GetComp <CompAbilityUserMight>();
                if (compMagic.IsMagicUser && !student.story.traits.HasTrait(TorannMagicDefOf.Faceless))
                {
                    this.isMageTeaching = true;
                }
                else if (compMight.IsMightUser)
                {
                    this.isFighterTeaching = true;
                }
                else
                {
                    Log.Message("ending teaching job due to undetected class - should never occur unless initializing verb is faulty");
                    this.EndJobWith(JobCondition.Incompletable);
                }

                if (age > duration)
                {
                    this.EndJobWith(JobCondition.Succeeded);
                }
                if (student.DestroyedOrNull() || student.Dead)
                {
                    this.EndJobWith(JobCondition.Incompletable);
                }

                this.pawn.rotationTracker.FaceTarget(TargetA);
                student.rotationTracker.FaceTarget(this.pawn);
                student.ClearAllReservations(false);
                this.pawn.ClearAllReservations(false);
            };
            doTeaching.tickAction = delegate
            {
                if (student.DestroyedOrNull() || student.Dead)
                {
                    this.EndJobWith(JobCondition.Incompletable);
                }
                if (age > (lastEffect + ticksTillEffects))
                {
                    DoTeachingEffects(student);
                    lastEffect = age;
                }
                if (!student.Drafted && student.CurJobDef != JobDefOf.Wait)
                {
                    if (student.jobs.posture == PawnPosture.Standing)
                    {
                        Job job = new Job(JobDefOf.Wait, student);
                        student.jobs.TryTakeOrderedJob(job, JobTag.Misc);
                    }
                }
                if (student.Drafted && student.CurJobDef != JobDefOf.Wait_Combat)
                {
                    this.EndJobWith(JobCondition.InterruptForced);
                }
                age++;
                ticksLeftThisToil = duration - age;
                if ((student.Position - this.pawn.Position).LengthHorizontal > 5)
                {
                    age = duration + 1;
                }
                if (age > duration)
                {
                    this.EndJobWith(JobCondition.Succeeded);
                }
            };
            doTeaching.defaultCompleteMode = ToilCompleteMode.Delay;
            doTeaching.defaultDuration     = this.duration;
            doTeaching.WithProgressBar(TargetIndex.B, delegate
            {
                if (this.pawn.DestroyedOrNull() || this.pawn.Dead)
                {
                    return(1f);
                }
                return(1f - (float)doTeaching.actor.jobs.curDriver.ticksLeftThisToil / this.duration);
            }, false, 0f);
            doTeaching.AddFinishAction(delegate
            {
                if (this.isMageTeaching)
                {
                    AssignMagicXP(student);
                }
                if (this.isFighterTeaching)
                {
                    AssignMightXP(student);
                }
                student.jobs.EndCurrentJob(JobCondition.Succeeded, false);
            });
            yield return(doTeaching);
        }
        //public override bool TryMakePreToilReservations(bool errorOnFailed)
        //{
        //    if(TargetA.Thing != null)
        //    {
        //        return true;
        //    }
        //    if (pawn.Reserve(TargetA, this.job, 1, 1, null, errorOnFailed))
        //    {
        //        return true;
        //    }
        //    return false;
        //}

        protected override IEnumerable <Toil> MakeNewToils()
        {
            yield return(Toils_Misc.ThrowColonistAttackingMote(TargetIndex.A));

            this.verb = this.pawn.CurJob.verbToUse as Verb_UseAbility;
            if (base.TargetA.HasThing && base.TargetA.Thing is Pawn && (!pawn.Position.InHorDistOf(base.TargetA.Cell, pawn.CurJob.verbToUse.verbProps.range) || !Verb.UseAbilityProps.canCastInMelee))
            {
                //if (!base.GetActor().IsFighting() ? true : !verb.UseAbilityProps.canCastInMelee && !this.job.endIfCantShootTargetFromCurPos)
                //{
                Toil toil = Toils_Combat.GotoCastPosition(TargetIndex.A);
                yield return(toil);
                //toil = null;
                //}
            }
            if (this.Context == AbilityContext.Player)
            {
                Find.Targeter.targetingSource = this.verb;
            }
            Pawn targetPawn = null;

            if (this.TargetThingA != null)
            {
                targetPawn = TargetThingA as Pawn;
            }

            if (targetPawn != null)
            {
                //yield return Toils_Combat.CastVerb(TargetIndex.A, false);
                Toil combatToil = new Toil();
                //combatToil.FailOnDestroyedOrNull(TargetIndex.A);
                //combatToil.FailOnDespawnedOrNull(TargetIndex.A);
                //combatToil.FailOnDowned(TargetIndex.A);
                //CompAbilityUserMagic comp = this.pawn.GetComp<CompAbilityUserMagic>();
                //JobDriver curDriver = this.pawn.jobs.curDriver;
                combatToil.initAction = delegate
                {
                    this.verb = combatToil.actor.jobs.curJob.verbToUse as Verb_UseAbility;
                    if (verb != null && verb.verbProps != null)
                    {
                        this.duration = (int)((this.verb.verbProps.warmupTime * 60) * this.pawn.GetStatValue(StatDefOf.AimingDelayFactor, false));

                        if (this.pawn.RaceProps.Humanlike)
                        {
                            //if (this.pawn.story.traits.HasTrait(TorannMagicDefOf.Faceless))
                            //{
                            //    RemoveMimicAbility(verb);
                            //}

                            if (this.pawn.story.traits.HasTrait(TorannMagicDefOf.TM_Psionic))
                            {
                                PsionicEnergyCost(verb);
                            }

                            if (this.pawn.story.traits.HasTrait(TorannMagicDefOf.DeathKnight))
                            {
                                HateCost(verb);
                            }

                            if (verb.Ability?.CooldownTicksLeft != -1)
                            {
                                this.EndJobWith(JobCondition.Incompletable);
                            }
                        }


                        LocalTargetInfo target = combatToil.actor.jobs.curJob.GetTarget(TargetIndex.A);
                        if (target != null)
                        {
                            verb.TryStartCastOn(target, false, true);
                        }
                        using (IEnumerator <Hediff> enumerator = this.pawn.health.hediffSet.GetHediffs <Hediff>().GetEnumerator())
                        {
                            while (enumerator.MoveNext())
                            {
                                Hediff rec = enumerator.Current;
                                if (rec.def == TorannMagicDefOf.TM_PossessionHD || rec.def == TorannMagicDefOf.TM_DisguiseHD || rec.def == TorannMagicDefOf.TM_DisguiseHD_I || rec.def == TorannMagicDefOf.TM_DisguiseHD_II || rec.def == TorannMagicDefOf.TM_DisguiseHD_III)
                                {
                                    this.pawn.health.RemoveHediff(rec);
                                }
                            }
                        }
                    }
                    else
                    {
                        this.EndJobWith(JobCondition.Errored);
                    }
                };
                combatToil.tickAction = delegate
                {
                    if (this.pawn.Downed)
                    {
                        EndJobWith(JobCondition.InterruptForced);
                    }
                    if (Find.TickManager.TicksGame % 12 == 0)
                    {
                        if (verb.Ability.Def == TorannMagicDefOf.TM_Artifact_TraitThief || verb.Ability.Def == TorannMagicDefOf.TM_Artifact_TraitInfuse)
                        {
                            float direction = Rand.Range(0, 360);
                            TM_MoteMaker.ThrowGenericMote(ThingDef.Named("Mote_Psi_Arcane"), pawn.DrawPos, pawn.Map, Rand.Range(.1f, .4f), 0.2f, .02f, .1f, 0, Rand.Range(8, 10), direction, direction);
                        }
                        else
                        {
                            TM_MoteMaker.ThrowCastingMote(pawn.DrawPos, pawn.Map, Rand.Range(1.2f, 2f));
                        }
                    }

                    this.duration--;
                    if (!wildCheck && this.duration <= 6)
                    {
                        wildCheck = true;
                        if (this.pawn.story != null && this.pawn.story.traits != null && this.pawn.story.traits.HasTrait(TorannMagicDefOf.ChaosMage) && Rand.Chance(.1f))
                        {
                            verb.Ability.PostAbilityAttempt();
                            TM_Action.DoWildSurge(this.pawn, this.pawn.GetComp <CompAbilityUserMagic>(), (MagicAbility)verb.Ability, (TMAbilityDef)verb.Ability.Def, TargetA);
                            EndJobWith(JobCondition.InterruptForced);
                        }
                    }
                };
                combatToil.AddFinishAction(delegate
                {
                    if (this.duration <= 5 && !this.pawn.DestroyedOrNull() && !this.pawn.Dead && !this.pawn.Downed)
                    {
                        //ShootLine shootLine;
                        //bool validTarg = verb.TryFindShootLineFromTo(pawn.Position, TargetLocA, out shootLine);
                        //bool inRange = (pawn.Position - TargetLocA).LengthHorizontal < verb.verbProps.range;
                        //if (inRange && validTarg)
                        //{
                        TMAbilityDef tmad = (TMAbilityDef)(verb.Ability.Def);
                        if (tmad != null && tmad.relationsAdjustment != 0 && targetPawn.Faction != null && targetPawn.Faction != this.pawn.Faction && !targetPawn.Faction.HostileTo(this.pawn.Faction))
                        {
                            targetPawn.Faction.TryAffectGoodwillWith(this.pawn.Faction, tmad.relationsAdjustment, true, false, null, null);
                        }
                        verb.Ability.PostAbilityAttempt();
                        this.pawn.ClearReservationsForJob(this.job);
                        //}
                    }
                });
                //if (combatToil.actor.CurJob != this.job)
                //{
                //    curDriver.ReadyForNextToil();
                //}
                combatToil.defaultCompleteMode = ToilCompleteMode.FinishedBusy;
                this.pawn.ClearReservationsForJob(this.job);
                yield return(combatToil);
                //Toil toil2 = new Toil()
                //{
                //    initAction = () =>
                //    {
                //        if (curJob.UseAbilityProps.isViolent)
                //        {
                //            JobDriver_CastAbilityVerb.CheckForAutoAttack(this.pawn);
                //        }
                //    },
                //    defaultCompleteMode = ToilCompleteMode.Instant
                //};
                //yield return toil2;
                //Toil toil1 = new Toil()
                //{
                //    initAction = () => curJob.Ability.PostAbilityAttempt(),
                //    defaultCompleteMode = ToilCompleteMode.Instant
                //};
                //yield return toil1;
            }
            else
            {
                if (verb != null && verb.verbProps != null && (pawn.Position - TargetLocA).LengthHorizontal < verb.verbProps.range)
                {
                    if (TargetLocA.IsValid && TargetLocA.InBounds(pawn.Map) && !TargetLocA.Fogged(pawn.Map))  //&& TargetLocA.Walkable(pawn.Map)
                    {
                        ShootLine shootLine;
                        bool      validTarg = verb.TryFindShootLineFromTo(pawn.Position, TargetLocA, out shootLine);
                        if (validTarg)
                        {
                            //yield return Toils_Combat.CastVerb(TargetIndex.A, false);
                            //Toil toil2 = new Toil()
                            //{
                            //    initAction = () =>
                            //    {
                            //        if (curJob.UseAbilityProps.isViolent)
                            //        {
                            //            JobDriver_CastAbilityVerb.CheckForAutoAttack(this.pawn);
                            //        }

                            //    },
                            //    defaultCompleteMode = ToilCompleteMode.Instant
                            //};
                            //yield return toil2;
                            this.duration = (int)((verb.verbProps.warmupTime * 60) * this.pawn.GetStatValue(StatDefOf.AimingDelayFactor, false));
                            Toil toil = new Toil();
                            toil.initAction = delegate
                            {
                                this.verb = toil.actor.jobs.curJob.verbToUse as Verb_UseAbility;
                                if (this.pawn.RaceProps.Humanlike)
                                {
                                    //if (this.pawn.story.traits.HasTrait(TorannMagicDefOf.Faceless))
                                    //{
                                    //    RemoveMimicAbility(verb);
                                    //}

                                    if (this.pawn.story.traits.HasTrait(TorannMagicDefOf.TM_Psionic))
                                    {
                                        PsionicEnergyCost(verb);
                                    }

                                    if (verb.Ability?.CooldownTicksLeft != -1)
                                    {
                                        this.EndJobWith(JobCondition.Incompletable);
                                    }
                                }
                                LocalTargetInfo target            = toil.actor.jobs.curJob.GetTarget(TargetIndex.A); //TargetLocA;  //
                                bool            canFreeIntercept2 = false;
                                if (target != null)
                                {
                                    verb.TryStartCastOn(target, false, canFreeIntercept2);
                                }
                                using (IEnumerator <Hediff> enumerator = this.pawn.health.hediffSet.GetHediffs <Hediff>().GetEnumerator())
                                {
                                    while (enumerator.MoveNext())
                                    {
                                        Hediff rec = enumerator.Current;
                                        if (rec.def == TorannMagicDefOf.TM_PossessionHD || rec.def == TorannMagicDefOf.TM_DisguiseHD || rec.def == TorannMagicDefOf.TM_DisguiseHD_I || rec.def == TorannMagicDefOf.TM_DisguiseHD_II || rec.def == TorannMagicDefOf.TM_DisguiseHD_III)
                                        {
                                            this.pawn.health.RemoveHediff(rec);
                                        }
                                    }
                                }
                            };
                            toil.tickAction = delegate
                            {
                                if (Find.TickManager.TicksGame % 12 == 0)
                                {
                                    TM_MoteMaker.ThrowCastingMote(pawn.DrawPos, pawn.Map, Rand.Range(1.2f, 2f));
                                }
                                this.duration--;
                                if (!wildCheck && this.duration <= 6)
                                {
                                    wildCheck = true;
                                    if (this.pawn.story != null && this.pawn.story.traits != null && this.pawn.story.traits.HasTrait(TorannMagicDefOf.ChaosMage) && Rand.Chance(.1f))
                                    {
                                        bool completeJob = TM_Action.DoWildSurge(this.pawn, this.pawn.GetComp <CompAbilityUserMagic>(), (MagicAbility)verb.Ability, (TMAbilityDef)verb.Ability.Def, TargetA);
                                        if (!completeJob)
                                        {
                                            verb.Ability.PostAbilityAttempt();
                                            EndJobWith(JobCondition.InterruptForced);
                                        }
                                    }
                                }
                            };
                            toil.AddFinishAction(delegate
                            {
                                if (this.duration <= 5 && !this.pawn.DestroyedOrNull() && !this.pawn.Dead && !this.pawn.Downed)
                                {
                                    verb.Ability.PostAbilityAttempt();
                                }
                                this.pawn.ClearReservationsForJob(this.job);
                            });
                            toil.defaultCompleteMode = ToilCompleteMode.FinishedBusy;
                            yield return(toil);

                            //Toil toil1 = new Toil()
                            //{
                            //    initAction = () => curJob.Ability.PostAbilityAttempt(),
                            //    defaultCompleteMode = ToilCompleteMode.Instant
                            //};
                            //yield return toil1;
                        }
                        else
                        {
                            //No LoS
                            if (pawn.IsColonist)
                            {
                                Messages.Message("TM_OutOfLOS".Translate(
                                                     pawn.LabelShort
                                                     ), MessageTypeDefOf.RejectInput);
                            }
                            pawn.ClearAllReservations(false);
                        }
                    }
                    else
                    {
                        pawn.ClearAllReservations(false);
                    }
                }
                else
                {
                    if (pawn.IsColonist)
                    {
                        //out of range
                        Messages.Message("TM_OutOfRange".Translate(), MessageTypeDefOf.RejectInput);
                    }
                }
            }
        }
        protected override IEnumerable <Toil> MakeNewToils()
        {
            Pawn mentalPawn = TargetA.Thing as Pawn;
            Toil gotoPawn   = new Toil()
            {
                initAction = () =>
                {
                    pawn.pather.StartPath(TargetA, PathEndMode.Touch);
                },
                defaultCompleteMode = ToilCompleteMode.PatherArrival
            };

            yield return(gotoPawn);

            Toil doMotivate = new Toil();

            doMotivate.initAction = delegate
            {
                if (age > duration)
                {
                    this.EndJobWith(JobCondition.Succeeded);
                }
                if (mentalPawn.DestroyedOrNull() || mentalPawn.Dead)
                {
                    this.EndJobWith(JobCondition.Incompletable);
                }

                this.pawn.rotationTracker.FaceTarget(TargetA);
                mentalPawn.rotationTracker.FaceTarget(this.pawn);
                mentalPawn.ClearAllReservations(false);
                this.pawn.ClearAllReservations(false);
            };
            doMotivate.tickAction = delegate
            {
                if (mentalPawn.DestroyedOrNull() || mentalPawn.Dead || !mentalPawn.InMentalState)
                {
                    this.EndJobWith(JobCondition.Incompletable);
                }
                if (age > (lastEffect + ticksTillEffects))
                {
                    DoSpeechEffects(mentalPawn);
                    lastEffect = age;
                }
                if (!mentalPawn.Drafted && mentalPawn.CurJobDef != JobDefOf.Wait)
                {
                    if (mentalPawn.jobs.posture == PawnPosture.Standing)
                    {
                        Job job = new Job(JobDefOf.Wait, mentalPawn);
                        mentalPawn.jobs.TryTakeOrderedJob(job, JobTag.InMentalState);
                    }
                }
                if (mentalPawn.Drafted && mentalPawn.CurJobDef != JobDefOf.Wait_Combat)
                {
                    this.EndJobWith(JobCondition.InterruptForced);
                }
                age++;
                ticksLeftThisToil = duration - age;
                if ((mentalPawn.Position - this.pawn.Position).LengthHorizontal > 5)
                {
                    age = duration + 1;
                }
                if (age > duration)
                {
                    this.EndJobWith(JobCondition.Succeeded);
                }
            };
            doMotivate.defaultCompleteMode = ToilCompleteMode.Delay;
            doMotivate.defaultDuration     = this.duration;
            doMotivate.WithProgressBar(TargetIndex.B, delegate
            {
                if (this.pawn.DestroyedOrNull() || this.pawn.Dead)
                {
                    return(1f);
                }
                return(1f - ((float)doMotivate.actor.jobs.curDriver.ticksLeftThisToil / this.duration));
            }, false, 0f);
            doMotivate.AddFinishAction(delegate
            {
                mentalPawn.MentalState.RecoverFromState();
                AssignXP();
                mentalPawn.jobs.EndCurrentJob(JobCondition.Succeeded, false);
            });
            yield return(doMotivate);
        }
        // Token: 0x06000013 RID: 19 RVA: 0x00002336 File Offset: 0x00000536
        protected override IEnumerable <Toil> MakeNewToils()
        {
            this.FailOnDestroyedNullOrForbidden(TargetIndex.A);
            bool flag = !base.TargetB.IsValid;

            if (flag)
            {
                base.AddFailCondition(() => this.energyNeed == null);
            }
            yield return(Toils_Reserve.Reserve(TargetIndex.A, 1, -1, null));

            bool isValid = base.TargetB.IsValid;

            if (isValid)
            {
                yield return(Toils_Reserve.Reserve(TargetIndex.B, 1, -1, null));
            }
            yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.ClosestTouch).FailOnSomeonePhysicallyInteracting(TargetIndex.A));

            yield return(Toils_Reserve.Release(TargetIndex.A));

            yield return(Toils_Haul.StartCarryThing(TargetIndex.A, false, true, false));

            bool isValid2 = base.TargetB.IsValid;

            if (isValid2)
            {
                yield return(Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.Touch).FailOnForbidden(TargetIndex.B));

                yield return(Toils_General.Wait(100).WithProgressBarToilDelay(TargetIndex.A, false, -0.5f));

                Toil rechargeToil = new Toil();
                rechargeToil.AddFinishAction(delegate
                {
                    Thing carriedThing = this.pawn.carryTracker.CarriedThing;
                    bool flag2         = carriedThing != null;
                    if (flag2)
                    {
                        EnergySourceComp energySourceComp = carriedThing.TryGetComp <EnergySourceComp>();
                        bool flag3 = energySourceComp != null;
                        if (flag3)
                        {
                            energySourceComp.RechargeEnergyNeed((Pawn)base.TargetB.Thing);
                        }
                        this.pawn.carryTracker.DestroyCarriedThing();
                    }
                });
                yield return(rechargeToil);

                yield return(Toils_Reserve.Release(TargetIndex.B));

                rechargeToil = null;
            }
            else
            {
                yield return(Toils_General.Wait(100).WithProgressBarToilDelay(TargetIndex.A, false, -0.5f));

                Toil rechargeToil2 = new Toil();
                rechargeToil2.AddFinishAction(delegate
                {
                    Thing carriedThing = this.pawn.carryTracker.CarriedThing;
                    bool flag2         = carriedThing != null;
                    if (flag2)
                    {
                        EnergySourceComp energySourceComp = carriedThing.TryGetComp <EnergySourceComp>();
                        bool flag3 = energySourceComp != null;
                        if (flag3)
                        {
                            energySourceComp.RechargeEnergyNeed(this.pawn);
                        }
                        this.pawn.carryTracker.DestroyCarriedThing();
                    }
                });
                yield return(rechargeToil2);

                rechargeToil2 = null;
            }
            yield break;
        }
Exemple #26
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            this.FailOnDestroyedOrNull(TargetIndex.A);


            Toil gotoThing = new Toil();

            gotoThing.initAction = delegate
            {
                this.pawn.pather.StartPath(this.TargetThingA, PathEndMode.Touch);
            };
            gotoThing.defaultCompleteMode = ToilCompleteMode.PatherArrival;
            gotoThing.FailOnDespawnedNullOrForbidden(TargetIndex.A);
            yield return(gotoThing);

            Toil enchanting = new Toil();//actions performed to enchant an item

            enchanting.FailOnCannotTouch(TargetIndex.A, PathEndMode.Touch);
            enchanting.FailOnDestroyedOrNull(TargetIndex.A);
            enchanting.initAction = delegate
            {
                actor    = enchanting.actor;
                thing    = TargetThingA;
                thingLoc = thing.Position;
                if (!(thing.def.IsMeleeWeapon || thing.def.IsRangedWeapon || thing.def.IsApparel))
                {
                    actor.jobs.EndCurrentJob(JobCondition.Incompletable, true);
                    Log.Message("Failed to initialize enchanting - invalid item type.");
                }
            };
            enchanting.tickAction = delegate
            {
                if (thing.Position != thingLoc || thing.Destroyed)
                {
                    actor.jobs.EndCurrentJob(JobCondition.Incompletable, true);
                    Log.Message("Failed to complete enchanting - item being enchanted not at enchanting location or destroyed");
                }
                if (Find.TickManager.TicksGame % 5 == 0)
                {
                    TM_MoteMaker.ThrowEnchantingMote(TargetLocA.ToVector3Shifted(), actor.Map, .6f);
                }
            };
            enchanting.WithProgressBar(TargetIndex.A, delegate
            {
                if (thing == null)
                {
                    return(1f);
                }
                return(1f - (float)enchanting.actor.jobs.curDriver.ticksLeftThisToil / 240);
            }, false, 0f);
            enchanting.defaultCompleteMode = ToilCompleteMode.Delay;
            enchanting.defaultDuration     = 240;
            enchanting.AddFinishAction(delegate
            {
                CompEnchantedItem enchantment = thing.TryGetComp <CompEnchantedItem>();
                CompEnchant enchantingItem    = actor.TryGetComp <CompEnchant>();
                CompAbilityUserMagic pawnComp = actor.TryGetComp <CompAbilityUserMagic>();
                if (enchantment != null && enchantingItem != null && enchanting.actor.jobs.curDriver.ticksLeftThisToil < 1)
                {
                    EnchantItem(enchantingItem.enchantingContainer[0], enchantment);
                    enchantingItem.enchantingContainer[0].Destroy();
                    pawnComp.Mana.CurLevel -= .5f;
                    MoteMaker.ThrowText(TargetLocA.ToVector3Shifted(), actor.Map, "TM_Enchanted".Translate(), -1);
                    SoundStarter.PlayOneShotOnCamera(TorannMagicDefOf.ItemEnchanted, null);

                    //DestroyEnchantingStone(enchantingItem.innerContainer[0]);
                }
                else
                {
                    Log.Message("Detected null enchanting comp.");
                }
            });
            yield return(enchanting);
        }
Exemple #27
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            if (spot != null && !spot.Destroyed)
            {
                Toil CallVictim = new Toil()
                {
                    initAction = () =>
                    {
                        Pawn target = TargetA.Thing as Pawn;
                        if (Prefs.DevMode)
                        {
                            Log.Message("JobDriver_AnimalGatheringOnSpot: goto spot with " + target);
                        }
                        pawn.pather.StartPath(spot.Position, PathEndMode.Touch);
                        Job gotojob = new Job(JobDefOf.GotoWander, spot.Position);
                        gotojob.locomotionUrgency = LocomotionUrgency.Sprint;
                        target.jobs.StartJob(gotojob, JobCondition.InterruptOptional, null, true, false, null, JobTag.MiscWork, false);
                    },
                    defaultCompleteMode = ToilCompleteMode.PatherArrival
                };
                CallVictim.FailOnDespawnedOrNull(TargetIndex.A);
                yield return(CallVictim);

                Toil WaitVictim = new Toil()
                {
                    defaultCompleteMode = ToilCompleteMode.Never,
                    tickAction          = () =>
                    {
                        if (Find.TickManager.TicksGame % 200 == 0)
                        {
                            Pawn target = TargetA.Thing as Pawn;
                            if (Prefs.DevMode)
                            {
                                Log.Message("JobDriver_AnimalGatheringOnSpot: waiting target " + target);
                            }
                            if (pawn.Position.DistanceToSquared(target.Position) < 32f)
                            {
                                Job waitjob = new Job(JobDefOf.Wait);
                                target.jobs.StartJob(waitjob, JobCondition.InterruptForced, null, false, true, null, JobTag.MiscWork, false);
                                this.ReadyForNextToil();
                            }
                            else
                            {
                                target.jobs.EndCurrentJob(JobCondition.InterruptForced, false);
                                Job gotojob = new Job(JobDefOf.GotoWander, spot.Position);
                                gotojob.locomotionUrgency = LocomotionUrgency.Sprint;
                                target.jobs.StartJob(gotojob, JobCondition.InterruptOptional, null, true, false, null, JobTag.MiscWork, false);
                            }
                        }
                    }
                };
                WaitVictim.AddFinishAction(() =>
                {
                    Pawn target = TargetA.Thing as Pawn;
                    target.jobs.EndCurrentJob(JobCondition.InterruptForced, true);
                });
                WaitVictim.FailOnDespawnedOrNull(TargetIndex.A);
                yield return(WaitVictim);

                Toil ReleaseVictim = new Toil()
                {
                    defaultCompleteMode = ToilCompleteMode.Instant,
                };
                ReleaseVictim.AddFinishAction(() =>
                {
                    Pawn target = TargetA.Thing as Pawn;
                    if (target != null)
                    {
                        target.ClearMind(true);
                    }
                });
                yield return(ReleaseVictim);
            }
            foreach (Toil toil in base.MakeNewToils())
            {
                yield return(toil);
            }
        }
Exemple #28
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            Toil  layDown = new Toil();
            float num     = 1.25f;

            layDown.initAction = delegate
            {
                Pawn actor = layDown.actor;
                actor.pather.StopDead();
                JobDriver curDriver = actor.jobs.curDriver;
                curDriver.layingDown = LayingDownState.LayingSurface;
                curDriver.asleep     = false;
                if (actor.mindState.applyBedThoughtsTick == 0)
                {
                    actor.mindState.applyBedThoughtsTick    = Find.TickManager.TicksGame + Rand.Range(2500, 10000);
                    actor.mindState.applyBedThoughtsOnLeave = false;
                }
                if (actor.ownership != null && actor.CurrentBed() != actor.ownership.OwnedBed)
                {
                    ThoughtUtility.RemovePositiveBedroomThoughts(actor);
                }
            };
            layDown.tickAction = delegate
            {
                Pawn      actor     = layDown.actor;
                Job       curJob    = actor.CurJob;
                JobDriver curDriver = actor.jobs.curDriver;
                actor.GainComfortFromCellIfPossible();
                if (!curDriver.asleep)
                {
                    if (actor.needs.rest != null && actor.needs.rest.CurLevel < .99f * RestUtility.WakeThreshold(actor))
                    {
                        curDriver.asleep = true;
                    }
                }
                else if ((actor.needs.rest == null || actor.needs.rest.CurLevel >= RestUtility.WakeThreshold(actor)))
                {
                    actor.mindState.priorityWork.ClearPrioritizedWorkAndJobQueue();
                    this.EndJobWith(JobCondition.Incompletable);
                }

                if (curDriver.asleep && actor.needs.rest != null)
                {
                    float num2 = RestUtility.PawnHealthRestEffectivenessFactor(actor);
                    num = 0.7f * num + 0.3f * num * num2;  //talk about convoluted calculations...
                    actor.needs.rest.TickResting(num);
                    if (actor.needs.rest.CurLevel >= .99f * RestUtility.WakeThreshold(actor))
                    {
                        curDriver.asleep = false;
                        actor.mindState.priorityWork.ClearPrioritizedWorkAndJobQueue();
                        this.EndJobWith(JobCondition.Succeeded);
                    }
                }

                if (actor.mindState.applyBedThoughtsTick != 0 && actor.mindState.applyBedThoughtsTick <= Find.TickManager.TicksGame)
                {
                    ApplyBedThoughts(actor);
                    actor.mindState.applyBedThoughtsTick   += 60000;
                    actor.mindState.applyBedThoughtsOnLeave = true;
                }
                if (actor.IsHashIntervalTick(100) && !actor.Position.Fogged(actor.Map))
                {
                    if (curDriver.asleep)
                    {
                        MoteMaker.ThrowMetaIcon(actor.Position, actor.Map, ThingDefOf.Mote_SleepZ);
                    }
                    if (actor.health.hediffSet.GetNaturallyHealingInjuredParts().Any <BodyPartRecord>())
                    {
                        MoteMaker.ThrowMetaIcon(actor.Position, actor.Map, ThingDefOf.Mote_HealingCross);
                    }
                }
            };
            layDown.defaultCompleteMode = ToilCompleteMode.Never;
            layDown.AddFinishAction(delegate
            {
                Pawn actor          = layDown.actor;
                JobDriver curDriver = actor.jobs.curDriver;
                if (actor.mindState.applyBedThoughtsOnLeave)
                {
                    ApplyBedThoughts(actor);
                }
                curDriver.layingDown = LayingDownState.NotLaying;
                curDriver.asleep     = false;
            });
            yield return(layDown);
        }
Exemple #29
0
        private static Toil DrinkSomeone(TargetIndex thingIndex, Func <Toil, Func <LocalTargetInfo> > funcGetter)
        {
            Toil toil = new Toil();

            toil.initAction = delegate
            {
                Pawn  actor = toil.actor;
                Thing thing = actor.CurJob.GetTarget(thingIndex).Thing;
                var   comp  = thing.TryGetComp <CompWaterSource>();
                if (comp == null || comp.SourceType != CompProperties_WaterSource.SourceType.Item)
                {
                    actor.jobs.EndCurrentJob(JobCondition.Incompletable, true);
                    return;
                }
                actor.rotationTracker.FaceCell(actor.Position);
                if (!thing.CanDrinkWaterNow())
                {
                    actor.jobs.EndCurrentJob(JobCondition.Incompletable, true);
                    return;
                }
                actor.jobs.curDriver.ticksLeftThisToil = comp.BaseDrinkTicks;
                if (thing.Spawned)
                {
                    thing.Map.physicalInteractionReservationManager.Reserve(actor, actor.CurJob, thing);
                }
            };
            toil.tickAction = delegate
            {
                toil.actor.GainComfortFromCellIfPossible();
            };
            toil.WithProgressBar(thingIndex, delegate
            {
                Pawn actor  = toil.actor;
                Thing thing = actor.CurJob.GetTarget(thingIndex).Thing;
                var comp    = thing.TryGetComp <CompWaterSource>();
                if (thing == null || comp == null || comp.SourceType != CompProperties_WaterSource.SourceType.Item)
                {
                    return(1f);
                }
                return(1f - (float)toil.actor.jobs.curDriver.ticksLeftThisToil / (float)comp.BaseDrinkTicks);
            }, false, -0.5f);
            toil.defaultCompleteMode = ToilCompleteMode.Delay;
            toil.FailOnDestroyedOrNull(thingIndex);
            toil.AddFinishAction(delegate
            {
                Pawn actor = toil.actor;
                if (actor == null)
                {
                    return;
                }
                if (actor.CurJob == null)
                {
                    return;
                }
                Thing thing = actor.CurJob.GetTarget(thingIndex).Thing;
                if (thing == null)
                {
                    return;
                }
                if (actor.Map.physicalInteractionReservationManager.IsReservedBy(actor, thing))
                {
                    actor.Map.physicalInteractionReservationManager.Release(actor, actor.CurJob, thing);
                }
            });

            // エフェクト追加
            toil.WithEffect(delegate
            {
                Pawn actor             = toil.actor;
                LocalTargetInfo target = toil.actor.CurJob.GetTarget(thingIndex);
                if (!target.HasThing)
                {
                    return(null);
                }
                EffecterDef effecter = null;
                var comp             = target.Thing.TryGetComp <CompWaterSource>();
                if (comp != null)
                {
                    effecter = comp.GetEffect;
                }
                return(effecter);
            }, funcGetter(toil));
            toil.PlaySustainerOrSound(delegate
            {
                Pawn actor = toil.actor;
                if (!actor.RaceProps.Humanlike)
                {
                    return(null);
                }
                LocalTargetInfo target = toil.actor.CurJob.GetTarget(thingIndex);
                if (!target.HasThing)
                {
                    return(null);
                }
                var comp = target.Thing.TryGetComp <CompWaterSource>();
                if (comp == null)
                {
                    return(null);
                }
                return(comp.Props.getSound);
            });
            return(toil);
        }
Exemple #30
0
        public static Toil LayDown(TargetIndex bedOrRestSpotIndex, bool hasBed, bool lookForOtherJobs, bool canSleep = true, bool gainRestAndHealth = true)
        {
            Toil layDown = new Toil();

            layDown.initAction = delegate()
            {
                Pawn actor = layDown.actor;
                actor.pather.StopDead();
                JobDriver curDriver = actor.jobs.curDriver;
                if (hasBed)
                {
                    Building_Bed t = (Building_Bed)actor.CurJob.GetTarget(bedOrRestSpotIndex).Thing;
                    if (!t.OccupiedRect().Contains(actor.Position))
                    {
                        Log.Error("Can't start LayDown toil because pawn is not in the bed. pawn=" + actor, false);
                        actor.jobs.EndCurrentJob(JobCondition.Errored, true);
                        return;
                    }
                    actor.jobs.posture = PawnPosture.LayingInBed;
                }
                else
                {
                    actor.jobs.posture = PawnPosture.LayingOnGroundNormal;
                }
                curDriver.asleep = false;
                if (actor.mindState.applyBedThoughtsTick == 0)
                {
                    actor.mindState.applyBedThoughtsTick    = Find.TickManager.TicksGame + Rand.Range(2500, 10000);
                    actor.mindState.applyBedThoughtsOnLeave = false;
                }
                if (actor.ownership != null && actor.CurrentBed() != actor.ownership.OwnedBed)
                {
                    ThoughtUtility.RemovePositiveBedroomThoughts(actor);
                }
            };
            layDown.tickAction = delegate()
            {
                Pawn         actor        = layDown.actor;
                Job          curJob       = actor.CurJob;
                JobDriver    curDriver    = actor.jobs.curDriver;
                Building_Bed building_Bed = (Building_Bed)curJob.GetTarget(bedOrRestSpotIndex).Thing;
                actor.GainComfortFromCellIfPossible();
                if (!curDriver.asleep)
                {
                    if (canSleep && ((actor.needs.rest != null && actor.needs.rest.CurLevel < RestUtility.FallAsleepMaxLevel(actor)) || curJob.forceSleep))
                    {
                        curDriver.asleep = true;
                    }
                }
                else if (!canSleep)
                {
                    curDriver.asleep = false;
                }
                else if ((actor.needs.rest == null || actor.needs.rest.CurLevel >= RestUtility.WakeThreshold(actor)) && !curJob.forceSleep)
                {
                    curDriver.asleep = false;
                }
                if (curDriver.asleep && gainRestAndHealth && actor.needs.rest != null)
                {
                    float restEffectiveness;
                    if (building_Bed != null && building_Bed.def.statBases.StatListContains(StatDefOf.BedRestEffectiveness))
                    {
                        restEffectiveness = building_Bed.GetStatValue(StatDefOf.BedRestEffectiveness, true);
                    }
                    else
                    {
                        restEffectiveness = 0.8f;
                    }
                    actor.needs.rest.TickResting(restEffectiveness);
                }
                if (actor.mindState.applyBedThoughtsTick != 0 && actor.mindState.applyBedThoughtsTick <= Find.TickManager.TicksGame)
                {
                    Toils_LayDown.ApplyBedThoughts(actor);
                    actor.mindState.applyBedThoughtsTick   += 60000;
                    actor.mindState.applyBedThoughtsOnLeave = true;
                }
                if (actor.IsHashIntervalTick(100) && !actor.Position.Fogged(actor.Map))
                {
                    if (curDriver.asleep)
                    {
                        MoteMaker.ThrowMetaIcon(actor.Position, actor.Map, ThingDefOf.Mote_SleepZ);
                    }
                    if (gainRestAndHealth && actor.health.hediffSet.GetNaturallyHealingInjuredParts().Any <BodyPartRecord>())
                    {
                        MoteMaker.ThrowMetaIcon(actor.Position, actor.Map, ThingDefOf.Mote_HealingCross);
                    }
                }
                if (actor.ownership != null && building_Bed != null && !building_Bed.Medical && !building_Bed.owners.Contains(actor))
                {
                    if (actor.Downed)
                    {
                        actor.Position = CellFinder.RandomClosewalkCellNear(actor.Position, actor.Map, 1, null);
                    }
                    actor.jobs.EndCurrentJob(JobCondition.Incompletable, true);
                    return;
                }
                if (lookForOtherJobs && actor.IsHashIntervalTick(211))
                {
                    actor.jobs.CheckForJobOverride();
                    return;
                }
            };
            layDown.defaultCompleteMode = ToilCompleteMode.Never;
            if (hasBed)
            {
                layDown.FailOnBedNoLongerUsable(bedOrRestSpotIndex);
            }
            layDown.AddFinishAction(delegate
            {
                Pawn actor          = layDown.actor;
                JobDriver curDriver = actor.jobs.curDriver;
                if (actor.mindState.applyBedThoughtsOnLeave)
                {
                    Toils_LayDown.ApplyBedThoughts(actor);
                }
                curDriver.asleep = false;
            });
            return(layDown);
        }
        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);
        }
 public static Toil IssueLeaveJob( TargetIndex PrisonerInd )
 {
     var toil = new Toil();
     toil.defaultCompleteMode = ToilCompleteMode.Instant;
     toil.AddFinishAction( () =>
     {
         try
         {
             var slave = toil.actor.CurJob.GetTarget( PrisonerInd ).Thing as Pawn;
             // Find an exit spot
             IntVec3 spot;
             if( !RCellFinder.TryFindBestExitSpot( slave, out spot, TraverseMode.ByPawn ) )
             {
                 Log.Warning( string.Format( "Tried to make pawn {0} leave but couldn't find an exit spot", slave.NameStringShort ) );
                 return;
             }
             // Stop any other jobs
             slave.jobs.StopAll( true );
             var newJob = new Job( JobDefOf.Goto, spot );
             newJob.exitMapOnArrival = true;
             // Assign new exit job
             slave.jobs.StartJob( newJob, JobCondition.None, (ThinkNode) null, false, true, (ThinkTreeDef) null );
         }
         catch( Exception e )
         {
             Log.Error( "Prisoners & Slaves :: Could not issue leave job to pawn!\n\t" + e.Message );
         }
     } );
     return toil;
 }
        protected override IEnumerable <Toil> MakeNewToils()
        {
            this.FailOnDestroyedNullOrForbidden(PowerDestIndex);
            if (!TargetB.IsValid)
            {
                AddFailCondition(() => energyNeed == null);
            }

            if (!isUsedFromInventory)
            {
                yield return(Toils_Reserve.Reserve(PowerDestIndex));

                if (TargetB.IsValid)
                {
                    yield return(Toils_Reserve.Reserve(OtherPawnIndex));
                }

                yield return(Toils_Goto.GotoThing(PowerDestIndex, PathEndMode.OnCell).FailOnSomeonePhysicallyInteracting(PowerDestIndex));

                yield return(Toils_Reserve.Release(PowerDestIndex));
            }
            else
            {
                yield return(new Toil()
                {
                    initAction = delegate()
                    {
                        if (!thingIsSplitOff && pawn.carryTracker.CarriedThing != TargetThingA)
                        {
                            Thing splitOffThing = TargetThingA.SplitOff(job.count);
                            thingIsSplitOff = true;
                            GenPlace.TryPlaceThing(splitOffThing, pawn.Position, pawn.Map, ThingPlaceMode.Near);

                            TargetThingA = splitOffThing;
                        }
                    }
                });
            }

            yield return(Toils_Haul.StartCarryThing(TargetIndex.A, false, true, false));

            this.AddFinishAction(delegate()
            {
                if (pawn.carryTracker is Pawn_CarryTracker carryTracker && carryTracker.CarriedThing is Thing thing)
                {
                    if (isUsedFromInventory)
                    {
                        //Thing takenThing = carryTracker.innerContainer.Take(thing);
                        pawn.inventory.innerContainer.TryAddOrTransfer(thing, true);
                    }
                    else
                    {
                        carryTracker.TryDropCarriedThing(pawn.Position, ThingPlaceMode.Near, out Thing resultThing);
                    }
                }
            });

            if (TargetB.IsValid)
            {
                //Recharge someone else.
                yield return(Toils_Goto.GotoThing(OtherPawnIndex, PathEndMode.Touch).FailOnForbidden(OtherPawnIndex));

                yield return(Toils_General.Wait(100).WithProgressBarToilDelay(TargetIndex.A, false));

                Toil rechargeToil = new Toil();
                rechargeToil.AddFinishAction(delegate()
                {
                    //Use up the carried stack
                    Thing carriedThing = pawn.carryTracker.CarriedThing;
                    if (carriedThing != null)
                    {
                        EnergySourceComp energyComp = carriedThing.TryGetComp <EnergySourceComp>();
                        if (energyComp != null)
                        {
                            energyComp.RechargeEnergyNeed((Pawn)TargetB.Thing);
                        }

                        pawn.carryTracker.DestroyCarriedThing();
                    }
                });

                yield return(rechargeToil);

                yield return(Toils_Reserve.Release(OtherPawnIndex));
            }
            else
            {
                yield return(Toils_General.Wait(100).WithProgressBarToilDelay(TargetIndex.A, false));

                //Recharge user.
                Toil rechargeToil = new Toil();
                rechargeToil.AddFinishAction(delegate()
                {
                    //Use up the carried stack
                    Thing carriedThing = pawn.carryTracker.CarriedThing;
                    if (carriedThing != null)
                    {
                        EnergySourceComp energyComp = carriedThing.TryGetComp <EnergySourceComp>();
                        if (energyComp != null)
                        {
                            energyComp.RechargeEnergyNeed(pawn);
                        }

                        pawn.carryTracker.DestroyCarriedThing();
                    }
                });

                yield return(rechargeToil);
            }
        }
 public static Toil Unrestrain( TargetIndex PrisonerInd, TargetIndex RestraintInd )
 {
     var toil = new Toil();
     toil.defaultCompleteMode = ToilCompleteMode.Delay;
     toil.defaultDuration = 250;
     toil.WithProgressBarToilDelay( PrisonerInd );
     toil.AddFinishAction( () =>
     {
         try
         {
             var slave = toil.actor.CurJob.GetTarget( PrisonerInd ).Thing as Pawn;
             var restraint = toil.actor.CurJob.GetTarget( RestraintInd ).Thing as Apparel;
             var compPrisoner = slave.TryGetComp<CompPrisoner>();
             if(
                 ( slave == null ) ||
                 ( restraint == null ) ||
                 ( compPrisoner == null )
             )
             {
                 throw new Exception(
                     string.Format(
                         "slave = {0}\n\trestraint = {1}\n\tcompPrisoner = {2}",
                         slave == null ? "null" : slave.ThingID,
                         restraint == null ? "null" : restraint.ThingID,
                         compPrisoner == null ? "null" : "valid" ) );
             }
             compPrisoner.RemoveApparelFromPawn( slave, restraint, toil.actor.Position );
         }
         catch( Exception e )
         {
             Log.Error( "Prisoners & Slaves :: Could not unrestrain pawn!\n\t" + e.Message );
         }
     } );
     return toil;
 }
        private Toil SowSeedToil()
        {
            Toil sowToil = new Toil();

            sowToil.initAction = () =>
            {
                sowToil.actor.pather.StopDead();

                if (IsActorCarryingAppropriateSeed())
                {
                    Thing newPlantThing = GenSpawn.Spawn(CurJob.plantDefToSow, CurJob.GetTarget(targetCellIndex).Cell);

                    if (newPlantThing != null)
                    {
                        // no type checking here as this job is only created for plants with this type
                        PlantWithSeeds newPlant = (PlantWithSeeds)newPlantThing;

                        newPlant.growth = 0F;
                        newPlant.genome = ((ThingDef_PlantWithSeeds)newPlant.def).genome.RandomGenome();//((Thing_PlantSeedsItem)sowToil.actor.carryHands.CarriedThing).genome;

                        CurJob.SetTarget(TargetIndex.C, new TargetInfo(newPlantThing));

                        m_fSowWorkRemaining = CurJob.plantDefToSow.plant.sowWork;

                        // effect has to be added here in the initAction so that it appears if
                        // the sow toil is repeated multiple times in a single job

                        sowToil.WithEffect("Sow", targetCellIndex);

                    }
                }
            };

            sowToil.AddFinishAction(() =>
            {
                // if the job finishes before the plant has progressed past the sowing stage, destroy it

                TargetInfo plantTargetInfo = CurJob.GetTarget(TargetIndex.C);

                if (plantTargetInfo != null)
                {
                    if (plantTargetInfo.HasThing && !plantTargetInfo.ThingDestroyed)
                    {
                        Plant plant = (Plant)plantTargetInfo.Thing;

                        if (plant.LifeStage == PlantLifeStage.Sowing)
                        {
                            plant.Destroy();
                        }
                    }

                    CurJob.SetTarget(TargetIndex.C, null);
                }
            });

            sowToil.tickAction = () =>
            {
                Pawn actor = sowToil.actor;

                TargetInfo plantTargetInfo = CurJob.GetTarget(TargetIndex.C);

                if (!IsActorCarryingAppropriateSeed() || plantTargetInfo == null || !plantTargetInfo.HasThing || plantTargetInfo.ThingDestroyed)
                {
                    // fail if the actor is no longer carrying seeds or if the plant being sowed is messed up

                    EndJobWith(JobCondition.Incompletable);
                }
                else
                {
                    SkillRecord actorsGrowingSkill = actor.skills.GetSkill(SkillDefOf.Growing);

                    if (actorsGrowingSkill != null)
                    {
                        // FCTODO: No idea if the learning rate here is appropriate.  Current value taken from Verse.AI.Toils_Recipe.DoRecipeWork()
                        // assuming a learn factor of 1 on the "recipe"
                        actorsGrowingSkill.Learn(0.11f * actorsGrowingSkill.LearningFactor);
                    }

                    m_fSowWorkRemaining -= actor.GetStatValue(StatDefOf.PlantWorkSpeed);

                    if (m_fSowWorkRemaining <= 0F)
                    {
                        if (sowToil.actor.carryHands.CarriedThing.stackCount <= 1)
                        {
                            sowToil.actor.carryHands.CarriedThing.Destroy();
                        }
                        else
                        {
                            sowToil.actor.carryHands.CarriedThing.stackCount--;
                        }

                        if (actor.needs.mood != null)
                        {
                            actor.needs.mood.thoughts.TryGainThought(DefDatabase<ThoughtDef>.GetNamed("GreenThumbHappy"));
                        }

                        Plant plant = (Plant)plantTargetInfo.Thing;

                        plant.growth = Plant.BaseGrowthPercent;

                        Find.MapDrawer.MapMeshDirty(plant.Position, MapMeshFlag.Things);

                        ReadyForNextToil();
                    }
                }
            };

            sowToil.defaultCompleteMode = ToilCompleteMode.Never;

            return sowToil;
        }
Exemple #36
0
        // Token: 0x06000063 RID: 99 RVA: 0x00004318 File Offset: 0x00002518
        protected override IEnumerable <Toil> MakeNewToils()
        {
            this.FailOnDespawnedOrNull(TargetIndex.A);
            var toilInv       = new Toil();
            var toilEquipGoto = new Toil();
            var toilEquip     = new Toil();
            var toilGoto      = new Toil();
            var toilCast      = new Toil();
            var toilTouch     = new Toil();
            var toilBeat      = new Toil();
            var toilBash      = new Toil();
            var HasPrimFE     = false;
            var HasPrimFB     = false;

            if (pawn.equipment.Primary != null)
            {
                if (pawn.equipment.Primary.def.defName == FEDefName && FWFoamUtility.HasFEFoam(pawn.equipment.Primary))
                {
                    HasPrimFE = true;
                }
                else if (pawn.equipment.Primary.def.defName == FBDefName)
                {
                    HasPrimFB = true;
                }
            }

            if (!HasPrimFE)
            {
                var fb = HasPrimFB;
                toilInv.initAction = delegate
                {
                    var            Swap            = false;
                    ThingWithComps invGearToEquip2 = null;
                    ThingWithComps primToSwap2     = null;
                    Thing          RemoveThing     = null;
                    Thing          BackupThing2    = null;
                    if (pawn.equipment.Primary != null)
                    {
                        primToSwap2 = pawn.equipment.Primary;
                    }

                    foreach (var invThing2 in pawn.inventory.innerContainer)
                    {
                        if (invThing2.def.defName != FEDefName || !FWFoamUtility.HasFEFoam(invThing2))
                        {
                            if (invThing2.def.defName == FBDefName)
                            {
                                BackupThing2 = invThing2;
                            }
                        }
                        else
                        {
                            RemoveThing     = invThing2;
                            invGearToEquip2 = (ThingWithComps)invThing2;
                            if (primToSwap2 != null)
                            {
                                Swap = true;
                            }

                            break;
                        }
                    }

                    if (invGearToEquip2 == null && !fb && BackupThing2 != null)
                    {
                        RemoveThing     = BackupThing2;
                        invGearToEquip2 = (ThingWithComps)BackupThing2;
                        if (primToSwap2 != null)
                        {
                            Swap = true;
                        }
                    }

                    if (invGearToEquip2 == null)
                    {
                        return;
                    }

                    var primDef = "";
                    if (Swap)
                    {
                        primDef = pawn.equipment.Primary.def.defName;
                        pawn.equipment.Remove(pawn.equipment.Primary);
                    }

                    pawn.inventory.innerContainer.Remove(RemoveThing);
                    pawn.equipment.MakeRoomFor(invGearToEquip2);
                    pawn.equipment.AddEquipment(invGearToEquip2);
                    if (Swap)
                    {
                        pawn.inventory.innerContainer.TryAdd(primToSwap2);
                    }

                    if (!Swap)
                    {
                        return;
                    }

                    var returnType = "SI";
                    if (pawn.equipment.Primary.def.defName != FEDefName &&
                        pawn.equipment.Primary.def.defName != FBDefName)
                    {
                        return;
                    }

                    var primary = pawn.equipment.Primary;
                    ((FireWardenData)primary).FWSwapType = returnType;
                    ((FireWardenData)primary).FWPawnID   = pawn.thingIDNumber;
                    ((FireWardenData)primary).FWPrimDef  = primDef;
                    if (!DebugFWData)
                    {
                        return;
                    }

                    var Test      = pawn.equipment.Primary;
                    var debugTest = pawn.Label + " : ";
                    debugTest = debugTest + Test.Label + " : ";
                    debugTest = debugTest + pawn.equipment.Primary.GetType() + " : ";
                    if (((FireWardenData)Test).FWSwapType != null)
                    {
                        debugTest = debugTest + ((FireWardenData)Test).FWSwapType + " : ";
                    }
                    else
                    {
                        debugTest += "null : ";
                    }

                    debugTest = debugTest + ((FireWardenData)Test).FWPawnID + " : ";
                    if (((FireWardenData)Test).FWPrimDef != null)
                    {
                        debugTest += ((FireWardenData)Test).FWPrimDef;
                    }
                    else
                    {
                        debugTest += "null";
                    }

                    Messages.Message(debugTest, pawn, MessageTypeDefOf.NeutralEvent, false);
                };
                toilInv.defaultCompleteMode = ToilCompleteMode.FinishedBusy;
                yield return(toilInv);
            }

            var FWEquipping   = Controller.Settings.EquippingDone;
            var FWSearchRange = (float)Controller.Settings.SearchRange;

            if (FWSearchRange < 25f)
            {
                FWSearchRange = 25f;
            }

            if (FWSearchRange > 75f)
            {
                FWSearchRange = 75f;
            }

            HasPrimFE = false;
            HasPrimFB = false;
            if (pawn.equipment.Primary != null)
            {
                if (pawn.equipment.Primary.def.defName == FEDefName && FWFoamUtility.HasFEFoam(pawn.equipment.Primary))
                {
                    HasPrimFE = true;
                }
                else if (pawn.equipment.Primary.def.defName == FBDefName)
                {
                    HasPrimFB = true;
                }
            }

            if (!HasPrimFE && !HasPrimFB && FWEquipping)
            {
                ThingWithComps invGearToEquip = null;
                ThingWithComps primToSwap     = null;
                Thing          BackupThing    = null;
                if (pawn.equipment.Primary != null)
                {
                    primToSwap = pawn.equipment.Primary;
                }

                foreach (var invThing in pawn.inventory.innerContainer)
                {
                    if (invThing.def.defName == FEDefName && FWFoamUtility.HasFEFoam(invThing))
                    {
                        invGearToEquip = (ThingWithComps)invThing;
                        if (primToSwap != null)
                        {
                        }

                        break;
                    }

                    if (invThing.def.defName == FBDefName)
                    {
                        BackupThing = invThing;
                    }
                }

                if (invGearToEquip == null && BackupThing != null)
                {
                    invGearToEquip = (ThingWithComps)BackupThing;
                }

                if (invGearToEquip == null)
                {
                    Thing ThingToGrab    = null;
                    var   skip           = Controller.Settings.BrawlerNotOK && pawn.story.traits.HasTrait(TraitDefOf.Brawler);
                    var   traverseParams = TraverseParms.For(pawn);

                    bool validatorFE(Thing t)
                    {
                        return(!t.IsForbidden(pawn) && pawn.CanReserve(t) && FWFoamUtility.HasFEFoam(t) &&
                               !FWFoamUtility.ReplaceFEFoam(t));
                    }

                    bool validatorFB(Thing t)
                    {
                        return(!t.IsForbidden(pawn) && pawn.CanReserve(t));
                    }

                    if (!skip)
                    {
                        var FElist = pawn.Map.listerThings.ThingsOfDef(DefDatabase <ThingDef> .GetNamed(FEDefName));
                        var FEGrab = GenClosest.ClosestThing_Global_Reachable(pawn.Position, pawn.Map, FElist,
                                                                              PathEndMode.OnCell, traverseParams, FWSearchRange, validatorFE);
                        if (FEGrab != null)
                        {
                            ThingToGrab = FEGrab;
                        }
                        else
                        {
                            var FBlist = pawn.Map.listerThings.ThingsOfDef(DefDatabase <ThingDef> .GetNamed(FBDefName));
                            var FBGrab = GenClosest.ClosestThing_Global_Reachable(pawn.Position, pawn.Map, FBlist,
                                                                                  PathEndMode.OnCell, traverseParams, FWSearchRange, validatorFB);
                            if (FBGrab != null)
                            {
                                ThingToGrab = FBGrab;
                            }
                        }
                    }
                    else
                    {
                        var FBlist2 = pawn.Map.listerThings.ThingsOfDef(DefDatabase <ThingDef> .GetNamed(FBDefName));
                        var FBGrab2 = GenClosest.ClosestThing_Global_Reachable(pawn.Position, pawn.Map, FBlist2,
                                                                               PathEndMode.OnCell, traverseParams, FWSearchRange, validatorFB);
                        if (FBGrab2 != null)
                        {
                            ThingToGrab = FBGrab2;
                        }
                    }

                    if (ThingToGrab != null)
                    {
                        toilEquipGoto.initAction = delegate
                        {
                            if (Map.reservationManager.CanReserve(pawn, ThingToGrab))
                            {
                                pawn.Reserve(ThingToGrab, job);
                            }

                            pawn.pather.StartPath(ThingToGrab, PathEndMode.OnCell);
                        };
                        toilEquipGoto.FailOn(ThingToGrab.DestroyedOrNull);
                        toilEquipGoto.AddFailCondition(() => FWHasFE(pawn) && ThingToGrab.def.defName == FEDefName);
                        toilEquipGoto.AddFailCondition(() => FWHasFB(pawn) && ThingToGrab.def.defName == FBDefName);
                        toilEquipGoto.defaultCompleteMode = ToilCompleteMode.PatherArrival;
                        yield return(toilEquipGoto);

                        toilEquip.initAction = delegate
                        {
                            var primDeEquip = pawn.equipment.Primary;
                            var primDef     = "N";
                            if (primDeEquip != null)
                            {
                                primDef = pawn.equipment.Primary.def.defName;
                                pawn.equipment.Remove(pawn.equipment.Primary);
                                pawn.inventory.innerContainer.TryAdd(primDeEquip);
                            }

                            var            FWGrabWithComps = (ThingWithComps)ThingToGrab;
                            ThingWithComps FWGrabbed;
                            if (FWGrabWithComps.def.stackLimit > 1 && FWGrabWithComps.stackCount > 1)
                            {
                                FWGrabbed = (ThingWithComps)FWGrabWithComps.SplitOff(1);
                            }
                            else
                            {
                                FWGrabbed = FWGrabWithComps;
                                FWGrabbed.DeSpawn();
                            }

                            pawn.equipment.MakeRoomFor(FWGrabbed);
                            pawn.equipment.AddEquipment(FWGrabbed);
                            var returnType = "EN";
                            if (pawn.equipment.Primary.def.defName != FEDefName &&
                                pawn.equipment.Primary.def.defName != FBDefName)
                            {
                                return;
                            }

                            var primary = pawn.equipment.Primary;
                            ((FireWardenData)primary).FWSwapType = returnType;
                            ((FireWardenData)primary).FWPawnID   = pawn.thingIDNumber;
                            ((FireWardenData)primary).FWPrimDef  = primDef;
                            if (!DebugFWData)
                            {
                                return;
                            }

                            var Test      = pawn.equipment.Primary;
                            var debugTest = pawn.Label + " : ";
                            debugTest = debugTest + Test.Label + " : ";
                            debugTest = debugTest + pawn.equipment.Primary.GetType() + " : ";
                            if ((Test as FireWardenData)?.FWSwapType != null)
                            {
                                debugTest = debugTest + ((FireWardenData)Test).FWSwapType + " : ";
                            }
                            else
                            {
                                debugTest += "null : ";
                            }

                            debugTest = debugTest + ((FireWardenData)Test).FWPawnID + " : ";
                            if (((FireWardenData)Test).FWPrimDef != null)
                            {
                                debugTest += ((FireWardenData)Test).FWPrimDef;
                            }
                            else
                            {
                                debugTest += "null";
                            }

                            Messages.Message(debugTest, pawn, MessageTypeDefOf.NeutralEvent, false);
                        };
                        toilEquip.AddFailCondition(() => FWHasFE(pawn) && ThingToGrab.def.defName == FEDefName);
                        toilEquip.AddFailCondition(() => FWHasFB(pawn) && ThingToGrab.def.defName == FBDefName);
                        toilEquip.defaultCompleteMode = ToilCompleteMode.FinishedBusy;
                        yield return(toilEquip);
                    }
                }
            }

            var HasPrimFEEq = pawn.equipment.Primary != null && pawn.equipment.Primary.def.defName == FEDefName &&
                              FWFoamUtility.HasFEFoam(pawn.equipment.Primary);

            if (HasPrimFEEq)
            {
                var FEVerbToUse  = pawn.TryGetAttackVerb(TargetFire);
                var RangeFireExt = 10f;
                if (FEVerbToUse != null)
                {
                    pawn.jobs.curJob.verbToUse = FEVerbToUse;
                    RangeFireExt  = pawn.jobs.curJob.verbToUse.verbProps.range;
                    RangeFireExt *= (float)(Controller.Settings.HowClose / 100.0);
                    if (RangeFireExt < 3f)
                    {
                        RangeFireExt = 3f;
                    }

                    if (RangeFireExt > pawn.jobs.curJob.verbToUse.verbProps.range)
                    {
                        RangeFireExt = pawn.jobs.curJob.verbToUse.verbProps.range;
                    }
                }

                toilGoto.initAction = delegate
                {
                    if (Map.reservationManager.CanReserve(pawn, TargetFire))
                    {
                        pawn.Reserve(TargetFire, job);
                    }

                    if (!CastPositionFinder.TryFindCastPosition(new CastPositionRequest
                    {
                        caster = pawn,
                        target = TargetFire,
                        verb = pawn.jobs.curJob.verbToUse,
                        maxRangeFromTarget = RangeFireExt,
                        wantCoverFromTarget = false
                    }, out var dest))
                    {
                        toilGoto.actor.jobs.EndCurrentJob(JobCondition.Incompletable);
                        return;
                    }

                    toilGoto.actor.pather.StartPath(dest, PathEndMode.OnCell);
                    pawn.Map.pawnDestinationReservationManager.Reserve(pawn, pawn.jobs.curJob, dest);
                };
                toilGoto.tickAction = delegate
                {
                    if (Controller.Settings.TooBrave)
                    {
                        return;
                    }

                    if (pawn.pather.Moving && pawn.pather.nextCell != TargetFire.Position)
                    {
                        StartTacklingFireIfAnyAt(pawn.pather.nextCell, toilCast);
                    }

                    if (pawn.Position != TargetFire.Position)
                    {
                        StartTacklingFireIfAnyAt(pawn.Position, toilCast);
                    }
                };
                toilGoto.FailOnDespawnedOrNull(TargetIndex.A);
                toilGoto.defaultCompleteMode = ToilCompleteMode.PatherArrival;
                toilGoto.atomicWithPrevious  = true;
                yield return(toilGoto);

                toilCast.initAction = delegate
                {
                    pawn.jobs.curJob.verbToUse.TryStartCastOn(TargetFire);
                    if (!TargetFire.Destroyed)
                    {
                        return;
                    }

                    pawn.records.Increment(RecordDefOf.FiresExtinguished);
                    pawn.jobs.EndCurrentJob(JobCondition.Succeeded);
                };
                toilCast.FailOnDespawnedOrNull(TargetIndex.A);
                toilCast.defaultCompleteMode = ToilCompleteMode.FinishedBusy;
                yield return(toilCast);
            }
            else
            {
                toilTouch.initAction = delegate
                {
                    if (Map.reservationManager.CanReserve(pawn, TargetFire))
                    {
                        pawn.Reserve(TargetFire, job);
                    }

                    pawn.pather.StartPath(TargetFire, PathEndMode.Touch);
                };
                toilTouch.tickAction = delegate
                {
                    if (Controller.Settings.TooBrave)
                    {
                        return;
                    }

                    if (pawn.pather.Moving && pawn.pather.nextCell != TargetFire.Position)
                    {
                        StartTacklingFireIfAnyAt(pawn.pather.nextCell, toilBeat);
                    }

                    if (pawn.Position != TargetFire.Position)
                    {
                        StartTacklingFireIfAnyAt(pawn.Position, toilBeat);
                    }
                };
                toilTouch.FailOnDespawnedOrNull(TargetIndex.A);
                toilTouch.defaultCompleteMode = ToilCompleteMode.PatherArrival;
                toilTouch.atomicWithPrevious  = true;
                yield return(toilTouch);

                toilBeat.tickAction = delegate
                {
                    if (!pawn.CanReachImmediate(TargetFire, PathEndMode.Touch))
                    {
                        JumpToToil(toilTouch);
                        return;
                    }

                    if (pawn.Position != TargetFire.Position && StartTacklingFireIfAnyAt(pawn.Position, toilBeat))
                    {
                        return;
                    }

                    if (pawn.equipment.Primary != null)
                    {
                        if (pawn.equipment.Primary.def.defName == FBDefName)
                        {
                            JumpToToil(toilBash);
                        }
                        else
                        {
                            pawn.natives.TryBeatFire(TargetFire);
                        }
                    }
                    else
                    {
                        pawn.natives.TryBeatFire(TargetFire);
                    }

                    if (!TargetFire.Destroyed)
                    {
                        return;
                    }

                    pawn.records.Increment(RecordDefOf.FiresExtinguished);
                    pawn.jobs.EndCurrentJob(JobCondition.Succeeded);
                };
                toilBeat.FailOnDespawnedOrNull(TargetIndex.A);
                toilBeat.defaultCompleteMode = ToilCompleteMode.Never;
                yield return(toilBeat);

                if (pawn.equipment.Primary == null || pawn.equipment.Primary.def.defName != FBDefName)
                {
                    yield break;
                }

                toilBash.initAction = delegate
                {
                    if (TargetFire != null && Map.reservationManager.CanReserve(pawn, TargetFire))
                    {
                        pawn.Reserve(TargetFire, job);
                    }

                    pawn.pather.StopDead();
                };
                toilBash.handlingFacing = true;
                toilBash.tickAction     = delegate
                {
                    pawn.rotationTracker.FaceTarget(pawn.CurJob.GetTarget(TargetIndex.A));
                    if (TargetFire != null)
                    {
                        pawn.Drawer.Notify_MeleeAttackOn(TargetFire);
                    }
                };
                toilBash.PlaySoundAtStart(SoundDefOf.Interact_BeatFire);
                toilBash.WithProgressBarToilDelay(TargetIndex.A);
                toilBash.AddFinishAction(delegate
                {
                    if (TargetFire != null && !TargetFire.Destroyed)
                    {
                        TargetFire.Destroy();
                    }
                });
                toilBash.FailOnDespawnedOrNull(TargetIndex.A);
                toilBash.defaultCompleteMode = ToilCompleteMode.Delay;
                var ticks     = 50;
                var WorkSpeed = pawn.GetStatValue(StatDefOf.WorkSpeedGlobal);
                if (WorkSpeed <= 0f)
                {
                    WorkSpeed = 1f;
                }

                ticks = (int)(ticks * (1f / WorkSpeed));
                if (ticks < 25)
                {
                    ticks = 25;
                }

                if (ticks > 200)
                {
                    ticks = 200;
                }

                toilBash.defaultDuration = ticks;
                yield return(toilBash);
            }
        }
Exemple #37
0
        public static Toil DoWeaponRepairWork(int duration, string soundDefName, float maxAllowedRepair)
        {
            float expPerSecond = 25f;

            FloatRange gainHitpointRange = new FloatRange(0.6f, 0.95f);  // Note: result = gainHitpointRange * skillRecord.Level / 12
            SkillDef   skillDef          = SkillDefOf.Crafting;
            int        maxSkillLevel     = 12;

            Toil toil = new Toil();

            //toil.initAction = delegate
            //{

            //};
            toil.tickAction = delegate
            {
                Pawn        actor       = toil.actor;
                Job         curJob      = actor.jobs.curJob;
                SkillRecord skillRecord = actor.skills.GetSkill(skillDef);

                // actor learns something
                actor.skills.Learn(SkillDefOf.Crafting, expPerSecond / 60);
            };

            toil.AddFinishAction(delegate
            {
                Pawn actor = toil.actor;
                Job curJob = actor.jobs.curJob;

                // Calculate possible hitpoint gain multiplicator
                SkillRecord skillRecord = actor.skills.GetSkill(skillDef);
                float gainHitpointMulti = gainHitpointRange.RandomInRange * Mathf.Clamp(skillRecord.Level, 1, maxSkillLevel) / maxSkillLevel;  //20;

                // Get the target hitpoint to use
                Thing master            = curJob.GetTarget(WeaponMasterIndex).Thing;
                int hitpointsMasterMax  = master.MaxHitPoints;
                int hitpointsMaster     = master.HitPoints;
                Thing ingredient        = curJob.GetTarget(WeaponIngredientIndex).Thing;
                int hitpointsIngredient = ingredient.HitPoints;

                // Hitpoints will only be increased to XX% of the ingredient hitpoints
                int newHitpoints = hitpointsMaster + (int)(hitpointsIngredient * gainHitpointMulti);

                if (newHitpoints > hitpointsMasterMax * maxAllowedRepair)
                {
                    newHitpoints = (int)(hitpointsMasterMax * maxAllowedRepair) + 1;
                }

                // repair master
                master.HitPoints = newHitpoints;
                // vanish ingredient
                ingredient.Destroy(DestroyMode.Vanish);
            });

            toil.handlingFacing      = true;
            toil.defaultCompleteMode = ToilCompleteMode.Delay;
            toil.defaultDuration     = duration;
            toil.WithProgressBarToilDelay(WorkbenchIndex, false, -0.5f);
            //toil.WithEffect(() => toil.actor.CurJob.bill.recipe.effectWorking, WorkbenchIndex);
            toil.PlaySustainerOrSound(() => SoundDef.Named(soundDefName));

            return(toil);
        }
Exemple #38
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            Toil meditate = new Toil
            {
                socialMode = RandomSocialMode.Off
            };

            if (FromBed)
            {
                this.KeepLyingDown(TargetIndex.B);
                meditate = Toils_LayDown.LayDown(TargetIndex.B, job.GetTarget(TargetIndex.B).Thing is Building_Bed, lookForOtherJobs: false, canSleep: false);
            }
            else
            {
                yield return(Toils_Goto.GotoCell(TargetIndex.A, PathEndMode.OnCell));

                meditate.initAction = delegate
                {
                    LocalTargetInfo target = job.GetTarget(TargetIndex.C);
                    if (target.IsValid)
                    {
                        faceDir = target.Cell - pawn.Position;
                    }
                    else
                    {
                        faceDir = (job.def.faceDir.IsValid ? job.def.faceDir : Rot4.Random).FacingCell;
                    }
                };
                if (Focus != null)
                {
                    meditate.FailOnDespawnedNullOrForbidden(TargetIndex.C);
                }
                meditate.handlingFacing = true;
            }
            meditate.defaultCompleteMode = ToilCompleteMode.Delay;
            meditate.defaultDuration     = job.def.joyDuration;
            meditate.FailOn(() => !MeditationUtility.CanMeditateNow(pawn) || !MeditationUtility.SafeEnvironmentalConditions(pawn, base.TargetLocA, base.Map));
            meditate.AddPreTickAction(delegate
            {
                if (faceDir.IsValid && !FromBed)
                {
                    pawn.rotationTracker.FaceCell(pawn.Position + faceDir);
                }
                pawn.GainComfortFromCellIfPossible();
                MeditationTick();
                if (ModLister.RoyaltyInstalled && MeditationFocusDefOf.Natural.CanPawnUse(pawn))
                {
                    int num = GenRadial.NumCellsInRadius(MeditationUtility.FocusObjectSearchRadius);
                    for (int i = 0; i < num; i++)
                    {
                        IntVec3 c = pawn.Position + GenRadial.RadialPattern[i];
                        if (c.InBounds(pawn.Map))
                        {
                            Plant plant = c.GetPlant(pawn.Map);
                            if (plant != null && plant.def == ThingDefOf.Plant_TreeAnima)
                            {
                                plant.TryGetComp <CompSpawnSubplant>()?.AddProgress(AnimaTreeSubplantProgressPerTick);
                            }
                        }
                    }
                }
            });
            meditate.AddFinishAction(delegate
            {
                if (sustainer != null)
                {
                    sustainer.End();
                }
            });
            yield return(meditate);
        }
        protected override IEnumerable <Toil> MakeNewToils()
        {
            // Error checking/input validation.
            if (turret == null)
            {
                Log.Error(string.Concat(errorBase, "TargetThingA isn't a Building_TurretGunCE"));
                yield return(null);
            }
            if (compReloader == null)
            {
                Log.Error(string.Concat(errorBase, "TargetThingA (Building_TurretGunCE) is missing it's CompAmmoUser."));
                yield return(null);
            }
            if (compReloader.UseAmmo && ammo == null)
            {
                Log.Error(string.Concat(errorBase, "TargetThingB is either null or not an AmmoThing."));
                yield return(null);
            }

            // Set fail condition on turret.
            if (pawn.Faction != Faction.OfPlayer)
            {
                this.FailOnDestroyedOrNull(TargetIndex.A);
            }
            else
            {
                this.FailOnDestroyedNullOrForbidden(TargetIndex.A);
            }

            if (compReloader.UseAmmo)
            {
                // Perform ammo system specific activities, failure condition and hauling
                if (pawn.Faction != Faction.OfPlayer)
                {
                    ammo.SetForbidden(false, false);
                    this.FailOnDestroyedOrNull(TargetIndex.B);
                }
                else
                {
                    this.FailOnDestroyedNullOrForbidden(TargetIndex.B);
                }

                // Haul ammo
                yield return(Toils_Reserve.Reserve(TargetIndex.B, 1));

                yield return(Toils_Goto.GotoCell(ammo.Position, PathEndMode.ClosestTouch));

                yield return(Toils_Haul.StartCarryThing(TargetIndex.B));

                yield return(Toils_Goto.GotoCell(turret.Position, PathEndMode.ClosestTouch));
                //yield return Toils_Haul.PlaceHauledThingInCell(TargetIndex.A, null, false);
            }
            else
            {
                // If ammo system is turned off we just need to go to the turret.
                yield return(Toils_Goto.GotoCell(turret.Position, PathEndMode.ClosestTouch));
            }

            // Wait in place
            Toil waitToil = new Toil()
            {
                actor = pawn
            };

            waitToil.initAction = delegate
            {
                // Initial relaod process activities.
                waitToil.actor.pather.StopDead();
                turret.isReloading = true;
                if (compReloader.ShouldThrowMote)
                {
                    MoteMaker.ThrowText(turret.Position.ToVector3Shifted(), turret.Map, string.Format("CE_ReloadingTurretMote".Translate(), TargetThingA.LabelCapNoCount));
                }
                Thing newAmmo;
                compReloader.TryUnload(out newAmmo);
                if (newAmmo?.CanStackWith(ammo) ?? false)
                {
                    pawn.carryTracker.TryStartCarry(newAmmo, Mathf.Min(newAmmo.stackCount, compReloader.Props.magazineSize - ammo.stackCount));
                }
            };
            waitToil.AddFinishAction(() => turret.isReloading = false);
            waitToil.defaultCompleteMode = ToilCompleteMode.Delay;
            waitToil.defaultDuration     = Mathf.CeilToInt(compReloader.Props.reloadTime.SecondsToTicks() / pawn.GetStatValue(CE_StatDefOf.ReloadSpeed));
            yield return(waitToil.WithProgressBarToilDelay(TargetIndex.A));

            //Actual reloader
            Toil reloadToil = new Toil();

            reloadToil.defaultCompleteMode = ToilCompleteMode.Instant;
            reloadToil.initAction          = delegate
            {
                compReloader.LoadAmmo(ammo);
            };
            //if (compReloader.useAmmo) reloadToil.EndOnDespawnedOrNull(TargetIndex.B);
            yield return(reloadToil);
        }
 private Toil SowSeedToil()
 {
     Toil sowToil = new Toil();
     sowToil.initAction = delegate
     {
         sowToil.actor.pather.StopDead();
         if (this.IsActorCarryingAppropriateSeed())
         {
             Thing thing = GenSpawn.Spawn(this.CurJob.plantDefToSow, this.CurJob.GetTarget(TargetIndex.A).Cell);
             if (thing != null)
             {
                 PlantWithSeeds expr_5D = (PlantWithSeeds)thing;
                 expr_5D.growth = 0f;
                 expr_5D.genome = ((ThingDef_PlantWithSeeds)expr_5D.def).genome.RandomGenome();
                 this.CurJob.SetTarget(TargetIndex.C, new TargetInfo(thing));
                 this.m_fSowWorkRemaining = this.CurJob.plantDefToSow.plant.sowWork;
                 sowToil.WithEffect("Sow", TargetIndex.A);
             }
         }
     };
     sowToil.AddFinishAction(delegate
     {
         TargetInfo target = base.CurJob.GetTarget(TargetIndex.C);
         if (target != null)
         {
             if (target.HasThing && !target.ThingDestroyed)
             {
                 Plant plant = (Plant)target.Thing;
                 if (plant.LifeStage == PlantLifeStage.Sowing)
                 {
                     plant.Destroy(DestroyMode.Vanish);
                 }
             }
             base.CurJob.SetTarget(TargetIndex.C, null);
         }
     });
     sowToil.tickAction = delegate
     {
         Pawn actor = sowToil.actor;
         TargetInfo target = this.CurJob.GetTarget(TargetIndex.C);
         if (!this.IsActorCarryingAppropriateSeed() || target == null || !target.HasThing || target.ThingDestroyed)
         {
             this.EndJobWith(JobCondition.Incompletable);
             return;
         }
         SkillRecord skill = actor.skills.GetSkill(SkillDefOf.Growing);
         if (skill != null)
         {
             skill.Learn(0.11f * skill.LearningFactor);
         }
         this.m_fSowWorkRemaining -= actor.GetStatValue(StatDefOf.PlantWorkSpeed, true);
         if (this.m_fSowWorkRemaining <= 0f)
         {
             if (sowToil.actor.carrier.CarriedThing.stackCount <= 1)
             {
                 sowToil.actor.carrier.CarriedThing.Destroy(DestroyMode.Vanish);
             }
             else
             {
                 sowToil.actor.carrier.CarriedThing.stackCount--;
             }
             if (actor.needs.mood != null)
             {
                 actor.needs.mood.thoughts.TryGainThought(DefDatabase<ThoughtDef>.GetNamed("GreenThumbHappy", true));
             }
             Plant plant = (Plant)target.Thing;
             plant.growth = 0.05f;
             Find.MapDrawer.MapMeshDirty(plant.Position, MapMeshFlag.Things);
             this.ReadyForNextToil();
         }
     };
     sowToil.defaultCompleteMode = ToilCompleteMode.Never;
     return sowToil;
 }
Exemple #41
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            CompAbilityUserMight comp = this.pawn.GetComp <CompAbilityUserMight>();
            float radius = 2.5f;

            radius += (.75f * TM_Calc.GetMightSkillLevel(pawn, comp.MightData.MightPowerSkill_PsionicBarrier, "TM_PsionicBarrier", "_ver", true));
            //if (this.pawn.story.traits.HasTrait(TorannMagicDefOf.TM_Psionic))
            //{
            //    radius = 2 + (.5f * comp.MightData.MightPowerSkill_PsionicBarrier.FirstOrDefault((MightPowerSkill x) => x.label == "TM_PsionicBarrier_ver").level);
            //}
            //else if(this.pawn.story.traits.HasTrait(TorannMagicDefOf.Faceless))
            //{
            //    radius = 2 + (.5f * comp.MightData.MightPowerSkill_Mimic.FirstOrDefault((MightPowerSkill x) => x.label == "TM_Mimic_ver").level);
            //}
            this.psiFlag = this.pawn.health.hediffSet.HasHediff(HediffDef.Named("TM_PsionicHD"), false);
            Toil psionicBarrier = new Toil();

            psionicBarrier.initAction = delegate
            {
                if (age > duration)
                {
                    this.EndJobWith(JobCondition.Succeeded);
                }
                Map map = this.pawn.Map;
                this.barrierCells = new List <IntVec3>();
                this.barrierCells.Clear();
                this.GetCellList(radius);
                ticksLeftThisToil            = 10;
                comp.shouldDrawPsionicShield = true;
            };
            psionicBarrier.tickAction = delegate
            {
                //DrawBarrier(radius);
                if (Find.TickManager.TicksGame % this.barrierSearchFrequency == 0)
                {
                    if (psiFlag)
                    {
                        if (Rand.Chance(.15f * comp.MightData.MightPowerSkill_PsionicBarrier.FirstOrDefault((MightPowerSkill x) => x.label == "TM_PsionicBarrier_pwr").level))
                        {
                            RepelProjectiles(false, radius);
                        }
                        else
                        {
                            RepelProjectiles(psiFlag, radius);
                        }
                        if (this.pawn.IsColonist)
                        {
                            HealthUtility.AdjustSeverity(this.pawn, HediffDef.Named("TM_PsionicHD"), -.004f);
                        }
                        else
                        {
                            HealthUtility.AdjustSeverity(this.pawn, HediffDef.Named("TM_PsionicHD"), -.04f);
                        }

                        psiEnergy = this.pawn.health.hediffSet.GetFirstHediffOfDef(HediffDef.Named("TM_PsionicHD"), false).Severity;
                        if (psiEnergy < 1)
                        {
                            this.EndJobWith(JobCondition.Succeeded);
                        }
                        if (this.psiFlag)
                        {
                            ticksLeftThisToil = (int)psiEnergy;
                        }
                    }
                    else
                    {
                        RepelProjectiles(false, radius);
                        comp.Stamina.CurLevel -= .00035f;
                    }
                }
                age++;
                if (!psiFlag)
                {
                    ticksLeftThisToil = Mathf.RoundToInt(((float)(duration - age) / (float)duration) * 100f);
                    if (age > duration)
                    {
                        this.EndJobWith(JobCondition.Succeeded);
                    }
                    if (comp.Stamina.CurLevel < .01f)
                    {
                        this.EndJobWith(JobCondition.Succeeded);
                    }
                }
            };
            psionicBarrier.defaultCompleteMode = ToilCompleteMode.Delay;
            psionicBarrier.defaultDuration     = this.duration;
            psionicBarrier.WithProgressBar(TargetIndex.A, delegate
            {
                if (this.pawn.DestroyedOrNull() || this.pawn.Dead || this.pawn.Downed)
                {
                    return(1f);
                }
                return(1f - (float)psionicBarrier.actor.jobs.curDriver.ticksLeftThisToil / 100);
            }, false, 0f);
            psionicBarrier.AddFinishAction(delegate
            {
                if (this.pawn.story.traits.HasTrait(TorannMagicDefOf.Faceless))
                {
                    CompAbilityUserMight mightComp = this.pawn.GetComp <CompAbilityUserMight>();
                    if (mightComp.mimicAbility != null)
                    {
                        mightComp.RemovePawnAbility(mightComp.mimicAbility);
                    }
                }
                comp.shouldDrawPsionicShield = false;
                //do soemthing?
            });
            yield return(psionicBarrier);
        }
        protected override IEnumerable<Toil> MakeNewToils()
        {
            //Set what will cause the job to fail
            this.FailOnBurningImmobile(RepairStationIndex);
            this.FailOnDestroyedOrForbidden(RepairStationIndex);
            this.FailOn(delegate
            {
                return Droid != null && !Droid.ShouldGetRepairs;
            });

            //Reserve the repair station
            yield return Toils_Reserve.Reserve(RepairStationIndex);
            //Go to the repair station interaction cell
            yield return Toils_Goto.GotoThing(RepairStationIndex, PathEndMode.InteractionCell);
            //Make a new toil that sets the droid to repair mode, then wait until fully repaired
            IRepairable droid = pawn as IRepairable;
            Building_RepairStation rps = TargetThingA as Building_RepairStation;
            Toil toil = new Toil();
            toil.FailOnDestroyedOrForbidden(RepairStationIndex);
            toil.FailOn(() =>
                {
                    Pawn p = toil.GetActor();
                    Building_RepairStation rps2 = TargetThingA as Building_RepairStation;
                    if (!(p is IRepairable))
                        return true;
                    if (p.Position != TargetThingA.InteractionCell)
                        return true;
                    if (rps2 == null || !rps2.IsAvailable(p))
                        return true;
                    return false;
                });

            toil.initAction = () =>
                {
                    //Log.Message("initAction");
                    droid.BeingRepaired = true;
                    rps.RegisterRepairee(droid);
                };
            toil.defaultCompleteMode = ToilCompleteMode.Delay;
            toil.defaultDuration = rps.Def.ticksPerRepairCycle * droid.RepairsNeededCount + 1;
            toil.tickAction = () =>
            {
                //Log.Message("Toil tick");
                if ( droid.RepairStation != null && Find.TickManager.TicksGame % droid.RepairStation.Def.ticksPerRepairCycle == 0)
                {
                    if (droid.RepairStation.Power != null && !droid.RepairStation.Power.PowerOn)
                    {
                        return;
                    }
                    //Log.Message("Repaired");
                    droid.RepairTick();
                }
            };
            toil.AddFinishAction(delegate
            {
                //Log.Message("Finish action");
                rps.DeregisterRepairee(droid);
                droid.BeingRepaired = false;
            });
            toil.WithEffect(DefDatabase<EffecterDef>.GetNamed("Repair"), TargetIndex.A);
            toil.WithSustainer(() => { return DefDatabase<SoundDef>.GetNamed("Interact_Repair"); });
            yield return toil;
        }
Exemple #43
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            this.EndOnDespawnedOrNull(TargetIndex.A, JobCondition.Incompletable);
            this.EndOnDespawnedOrNull(TargetIndex.B, JobCondition.Incompletable);
            this.FailOnForbidden(TargetIndex.A);

            yield return(Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.OnCell));

            float    statValue = TargetThingA.GetStatValue(StatDefOf.JoyGainFactor, true);
            Building building  = (Building)pawn.CurJob.targetA.Thing;
            //CompRunningGenerator comp = (CompRunningGenerator)building.GetComp<CompRunningGenerator>();
            //int storedEnergy = 0;
            //int skipTick = 0;
            //int sameValueTimes = 0;

            Toil use = new Toil();

            use.tickAction = delegate
            {
                pawn.rotationTracker.FaceCell(TargetA.Cell);
                pawn.GainComfortFromCellIfPossible();

                building.GetComp <CompMannable>().ManForATick(pawn);

                if (TargetC.IsValid)
                {
                    JoyUtility.JoyTickCheckEnd(pawn, JoyTickFullJoyAction.None, statValue);

                    //Log.Message(building + " current stored energy = " + (int)comp.PowerNet.CurrentStoredEnergy());

                    /*
                     * if (skipTick < 60)
                     * {
                     *      //Log.Message(building + " stored energy = " + storedEnergy);
                     *      if ((int)comp.PowerNet.CurrentStoredEnergy() == storedEnergy)
                     *      {
                     *              if (sameValueTimes < 60)
                     *              {
                     *                      sameValueTimes++;
                     *              }
                     *              else pawn.jobs.curDriver.EndJobWith(JobCondition.Succeeded);
                     *      }
                     *      else sameValueTimes = 0;
                     *
                     *      skipTick++;
                     * }
                     * else
                     * {
                     *      storedEnergy = (int)comp.PowerNet.CurrentStoredEnergy();
                     *      skipTick = 0;
                     * }
                     */
                }
                else
                {
                    JoyUtility.JoyTickCheckEnd(pawn, JoyTickFullJoyAction.EndJob, statValue);
                }
            };

            if (!TargetC.IsValid)
            {
                use.defaultCompleteMode = ToilCompleteMode.Delay;
                use.defaultDuration     = job.def.joyDuration;
            }
            else
            {
                use.defaultCompleteMode = ToilCompleteMode.Never;
            }

            use.handlingFacing = true;
            use.AddFinishAction(delegate
            {
                JoyUtility.TryGainRecRoomThought(pawn);
            });

            yield return(use);

            yield break;
        }
Exemple #44
0
            public bool MoveNext()
            {
                uint num = (uint)this.$PC;

                this.$PC = -1;
                switch (num)
                {
                case 0u:
                    this.EndOnDespawnedOrNull(TargetIndex.A, JobCondition.Incompletable);
                    chooseCell    = Toils_Misc.FindRandomAdjacentReachableCell(TargetIndex.A, TargetIndex.B);
                    this.$current = chooseCell;
                    if (!this.$disposing)
                    {
                        this.$PC = 1;
                    }
                    return(true);

                case 1u:
                    this.$current = Toils_Reserve.Reserve(TargetIndex.B, 1, -1, null);
                    if (!this.$disposing)
                    {
                        this.$PC = 2;
                    }
                    return(true);

                case 2u:
                    this.$current = Toils_Goto.GotoCell(TargetIndex.B, PathEndMode.OnCell);
                    if (!this.$disposing)
                    {
                        this.$PC = 3;
                    }
                    return(true);

                case 3u:
                    play            = new Toil();
                    play.initAction = delegate()
                    {
                        this.job.locomotionUrgency = LocomotionUrgency.Walk;
                    };
                    play.tickAction = delegate()
                    {
                        this.pawn.rotationTracker.FaceCell(base.TargetA.Thing.OccupiedRect().ClosestCellTo(this.pawn.Position));
                        if (this.ticksLeftThisToil == 300)
                        {
                            SoundDefOf.PlayBilliards.PlayOneShot(new TargetInfo(this.pawn.Position, this.pawn.Map, false));
                        }
                        if (Find.TickManager.TicksGame > this.startTick + this.job.def.joyDuration)
                        {
                            base.EndJobWith(JobCondition.Succeeded);
                            return;
                        }
                        Pawn     pawn      = this.pawn;
                        Building joySource = (Building)base.TargetThingA;
                        JoyUtility.JoyTickCheckEnd(pawn, JoyTickFullJoyAction.EndJob, 1f, joySource);
                    };
                    play.handlingFacing      = true;
                    play.socialMode          = RandomSocialMode.SuperActive;
                    play.defaultCompleteMode = ToilCompleteMode.Delay;
                    play.defaultDuration     = 600;
                    play.AddFinishAction(delegate
                    {
                        JoyUtility.TryGainRecRoomThought(this.pawn);
                    });
                    this.$current = play;
                    if (!this.$disposing)
                    {
                        this.$PC = 4;
                    }
                    return(true);

                case 4u:
                    this.$current = Toils_Reserve.Release(TargetIndex.B);
                    if (!this.$disposing)
                    {
                        this.$PC = 5;
                    }
                    return(true);

                case 5u:
                    this.$current = Toils_Jump.Jump(chooseCell);
                    if (!this.$disposing)
                    {
                        this.$PC = 6;
                    }
                    return(true);

                case 6u:
                    this.$PC = -1;
                    break;
                }
                return(false);
            }
Exemple #45
0
        public static Toil LayDown(TargetIndex bedOrRestSpotIndex, bool hasBed, bool lookForOtherJobs, bool canSleep = true, bool gainRestAndHealth = true)
        {
            Toil layDown = new Toil();

            layDown.initAction = delegate
            {
                Pawn actor = layDown.actor;
                actor.pather.StopDead();
                JobDriver curDriver = actor.jobs.curDriver;
                if (hasBed)
                {
                    Building_Bed t = (Building_Bed)actor.CurJob.GetTarget(bedOrRestSpotIndex).Thing;
                    if (!t.OccupiedRect().Contains(actor.Position))
                    {
                        Log.Error("Can't start LayDown toil because pawn is not in the bed. pawn=" + actor, false);
                        actor.jobs.EndCurrentJob(JobCondition.Errored, true);
                        return;
                    }
                    actor.jobs.posture = PawnPosture.LayingInBed;
                }
                else
                {
                    actor.jobs.posture = PawnPosture.LayingOnGroundNormal;
                }
                curDriver.asleep = false;
                if (actor.mindState.applyBedThoughtsTick == 0)
                {
                    actor.mindState.applyBedThoughtsTick    = Find.TickManager.TicksGame + Rand.Range(2500, 10000);
                    actor.mindState.applyBedThoughtsOnLeave = false;
                }
                if (actor.ownership != null && actor.CurrentBed() != actor.ownership.OwnedBed)
                {
                    ThoughtUtility.RemovePositiveBedroomThoughts(actor);
                }
            };

            layDown.tickAction = delegate
            {
                Pawn         actor        = layDown.actor;
                Job          curJob       = actor.CurJob;
                JobDriver    curDriver    = actor.jobs.curDriver;
                Building_Bed building_Bed = (Building_Bed)curJob.GetTarget(bedOrRestSpotIndex).Thing;
                actor.GainComfortFromCellIfPossible();

                if (actor.IsHashIntervalTick(100) && !actor.Position.Fogged(actor.Map))
                {
                    if (curDriver.asleep)
                    {
                        MoteMaker.ThrowMetaIcon(actor.Position, actor.Map, ThingDefOf.Mote_SleepZ);
                    }
                    if (gainRestAndHealth && actor.health.hediffSet.GetNaturallyHealingInjuredParts().Any <BodyPartRecord>())
                    {
                        MoteMaker.ThrowMetaIcon(actor.Position, actor.Map, ThingDefOf.Mote_HealingCross);
                    }
                }
                if (actor.ownership != null && building_Bed != null && !building_Bed.Medical && !building_Bed.OwnersForReading.Contains(actor))
                {
                    if (actor.Downed)
                    {
                        actor.Position = CellFinder.RandomClosewalkCellNear(actor.Position, actor.Map, 1, null);
                    }
                    actor.jobs.EndCurrentJob(JobCondition.Incompletable, true);
                    return;
                }
                if (lookForOtherJobs && actor.IsHashIntervalTick(211))
                {
                    actor.jobs.CheckForJobOverride();
                    return;
                }

                //Fin recharche ou pod non alimenté ou non operationel
                if (actor.needs.food.CurLevelPercentage >= 1.0f ||
                    building_Bed.Destroyed || building_Bed.IsBrokenDown() ||
                    !building_Bed.TryGetComp <CompPowerTrader>().PowerOn)
                {
                    actor.jobs.EndCurrentJob(JobCondition.Succeeded, true);
                }
            };
            layDown.defaultCompleteMode = ToilCompleteMode.Never;
            if (hasBed)
            {
                layDown.FailOnBedNoLongerUsable(bedOrRestSpotIndex);
            }
            layDown.AddFinishAction(delegate
            {
                Pawn actor          = layDown.actor;
                JobDriver curDriver = actor.jobs.curDriver;
                curDriver.asleep    = false;
            });
            return(layDown);
        }
Exemple #46
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            if (TargetA.Thing != null)
            {
                targetThing = TargetA.Thing;
            }
            Toil gotoThing = new Toil()
            {
                initAction = () =>
                {
                    pawn.pather.StartPath(TargetA, PathEndMode.Touch);
                },
                defaultCompleteMode = ToilCompleteMode.PatherArrival
            };

            yield return(gotoThing);

            Toil doSpell = new Toil();

            doSpell.initAction = delegate
            {
                if (ability != null)
                {
                    this.duration = (int)(ability.Def.MainVerb.warmupTime * 60 * this.pawn.GetStatValue(StatDefOf.AimingDelayFactor, false));
                }
                if (age > duration)
                {
                    this.EndJobWith(JobCondition.Succeeded);
                }
                if (targetThing != null && (targetThing.DestroyedOrNull() || targetThing.Map == null))
                {
                    this.EndJobWith(JobCondition.Incompletable);
                }

                if (targetThing != null)
                {
                    this.pawn.rotationTracker.FaceTarget(targetThing);
                }
            };
            doSpell.tickAction = delegate
            {
                if (targetThing != null && (targetThing.DestroyedOrNull() || targetThing.Map == null))
                {
                    this.EndJobWith(JobCondition.Incompletable);
                }
                age++;
                ticksLeftThisToil = duration - age;
                if (Find.TickManager.TicksGame % 12 == 0)
                {
                    TM_MoteMaker.ThrowCastingMote(pawn.DrawPos, pawn.Map, Rand.Range(1.2f, 2f));
                }

                if (age > duration)
                {
                    this.EndJobWith(JobCondition.Succeeded);
                }
            };
            doSpell.defaultCompleteMode = ToilCompleteMode.Never;
            doSpell.defaultDuration     = this.duration;
            doSpell.AddFinishAction(delegate
            {
                if (ability != null)
                {
                    if (ability.Def == TorannMagicDefOf.TM_Transmutate && targetThing != null)
                    {
                        bool flagRawResource = false;
                        bool flagStuffItem   = false;
                        bool flagNoStuffItem = false;
                        bool flagNutrition   = false;
                        bool flagCorpse      = false;

                        TM_Calc.GetTransmutableThingFromCell(targetThing.Position, pawn, out flagRawResource, out flagStuffItem, out flagNoStuffItem, out flagNutrition, out flagCorpse);
                        TM_Action.DoTransmutate(pawn, targetThing, flagNoStuffItem, flagRawResource, flagStuffItem, flagNutrition, flagCorpse);
                    }
                    else if (ability.Def == TorannMagicDefOf.TM_RegrowLimb)
                    {
                        AbilityUser.SpawnThings tempThing = new SpawnThings();
                        tempThing.def = ThingDef.Named("SeedofRegrowth");
                        Verb_RegrowLimb.SingleSpawnLoop(tempThing, TargetA.Cell, pawn.Map);
                    }
                    ability.PostAbilityAttempt();
                }
                //AssignXP();
            });
            yield return(doSpell);
        }
Exemple #47
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            //--Log.Message("[RJW] JobDriver_Beastiality::MakeNewToils() called");
            duration              = (int)(2500.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);

            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 (iprisoner);
            //this.FailOn (() => (!Prisoner.health.capacities.CanBeAwake) || (!comfort_prisoners.is_designated (Prisoner)));
            this.FailOn(() => !pawn.CanReserve(animal, 1, 0));              // Fail if someone else reserves the prisoner before the pawn arrives
            yield return(Toils_Reserve.Reserve(iprisoner, 1, 0));

            //--Log.Message("[RJW] JobDriver_Beastiality::MakeNewToils() - moving towards animal");
            yield return(Toils_Goto.GotoThing(iprisoner, PathEndMode.OnCell));

            Messages.Message(pawn.NameStringShort + " is trying to rape " + animal.NameStringShort + ".", pawn, MessageTypeDefOf.NeutralEvent);

            var rape = new Toil();

            rape.initAction = delegate
            {
                //--Log.Message("[RJW] JobDriver_Beastiality::MakeNewToils() - reserving animal");
                //pawn.Reserve(animal, 1, 0); // animal rapin seems like a solitary activity
                //if (!pawnHasPenis)
                //	animal.rotationTracker.Face(pawn.DrawPos);

                //--Log.Message("[RJW] JobDriver_Beastiality::MakeNewToils() - Setting animal job driver");
                var dri = animal.jobs.curDriver as JobDriver_GettinRaped;
                if (dri == null)
                {
                    var gettin_raped = new Job(xxx.gettin_raped);
                    animal.jobs.StartJob(gettin_raped, JobCondition.InterruptForced, null, true, true, null);
                    (animal.jobs.curDriver as JobDriver_GettinRaped).increase_time(duration);
                }
                else
                {
                    dri.rapist_count += 1;
                    dri.increase_time(duration);
                }
                // Try to take off the attacker's clothing
                //--Log.Message("[RJW] JobDriver_Beastiality::MakeNewToils() - stripping necro lover");

                /* Edited by nizhuan-jjr: No Dropping Clothes on attackes!
                 * worn_apparel = pawn.apparel.WornApparel.ListFullCopy<Apparel>();
                 * while (pawn.apparel != null && pawn.apparel.WornApparelCount > 0) {
                 * Apparel apparel = pawn.apparel.WornApparel.RandomElement<Apparel>();
                 * pawn.apparel.Remove(apparel);
                 * }
                 */
            };
            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, animal);
                }

                /*
                 * if (pawn.IsHashIntervalTick (ticks_between_hits))
                 *      roll_to_hit (pawn, animal);
                 */
            };
            rape.AddFinishAction(delegate
            {
                //--Log.Message("[RJW] JobDriver_Beastiality::MakeNewToils() - finished violating");
                //// Trying to add some interactions and social logs
                xxx.processAnalSex(pawn, animal, ref isAnalSex, pawnHasPenis);

                if ((animal.jobs != null) &&
                    (animal.jobs.curDriver != null) &&
                    (animal.jobs.curDriver as JobDriver_GettinRaped != null))
                {
                    (animal.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_Beastiality::MakeNewToils() - creating aftersex toil");
                    xxx.aftersex(pawn, animal, false, false, isAnalSex);
                    pawn.mindState.canLovinTick = Find.TickManager.TicksGame + xxx.generate_min_ticks_to_next_lovin(pawn);
                    if (!animal.Dead)
                    {
                        animal.mindState.canLovinTick = Find.TickManager.TicksGame + xxx.generate_min_ticks_to_next_lovin(animal);
                    }

                    //--Log.Message("[RJW] JobDriver_Beastiality::MakeNewToils() - putting clothes back on");

                    /* Edited by nizhuan-jjr: No Dropping Clothes on attackers!
                     * if (pawn.apparel != null) {
                     * foreach (Apparel apparel in worn_apparel) {
                     * pawn.apparel.Wear(apparel);//  WornApparel.Add(apparel);
                     * }
                     * }
                     */
                },
                defaultCompleteMode = ToilCompleteMode.Instant
            });
        }