예제 #1
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            this.FailOn(condition: () => !this.Comp.CanDrillNow());
            yield return(Toils_Goto.GotoThing(ind: TargetIndex.A, peMode: PathEndMode.Touch).FailOnDespawnedNullOrForbidden(ind: TargetIndex.A));

            Toil mine = new Toil();

            mine.WithEffect(effectDef: EffecterDefOf.Drill, ind: TargetIndex.A);
            mine.WithProgressBar(ind: TargetIndex.A, progressGetter: () => this.Comp.Progress);
            mine.tickAction = delegate
            {
                Pawn minePawn = mine.actor;
                this.Comp.Drill(miningPoints: minePawn.GetStatValue(stat: StatDefOf.MiningSpeed) / TICKS);
                minePawn.skills.Learn(sDef: SkillDefOf.Mining, xp: 0.125f);
                if (!(this.Comp.Progress >= 1))
                {
                    return;
                }
                this.Comp.DrillWorkDone(driller: minePawn);
                this.EndJobWith(condition: JobCondition.Succeeded);
                minePawn.records.Increment(def: RecordDefOf.CellsMined);
            };
            mine.WithEffect(effectDef: this.TargetThingA.def.repairEffect, ind: TargetIndex.A);
            mine.defaultCompleteMode = ToilCompleteMode.Never;
            yield return(mine);
        }
예제 #2
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            this.FailOn(() => {
                if (this.Comp.CanDrillNow())
                {
                    return(false);
                }
                return(true);
            });
            yield return(Toils_Reserve.Reserve(TargetIndex.A).FailOnDespawnedNullOrForbidden(TargetIndex.A));

            yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch).FailOnDespawnedNullOrForbidden(TargetIndex.A));

            Toil mine = new Toil();

            mine.WithEffect(EffecterDefOf.Drill, TargetIndex.A);
            mine.WithProgressBar(TargetIndex.A, () => this.Comp.Progress);
            mine.tickAction = delegate
            {
                Pawn pawn = mine.actor;
                this.Comp.Drill(pawn.GetStatValue(StatDefOf.MiningSpeed) / ticks);
                pawn.skills.Learn(SkillDefOf.Mining, 0.125f);
                if (this.Comp.Progress >= 1)
                {
                    this.Comp.DrillWorkDone(pawn);
                    EndJobWith(JobCondition.Succeeded);
                    pawn.records.Increment(RecordDefOf.CellsMined);
                }
            };
            mine.WithEffect(this.TargetThingA.def.repairEffect, TargetIndex.A);
            mine.defaultCompleteMode = ToilCompleteMode.Never;
            yield return(mine);
        }
        protected override IEnumerable <Toil> MakeNewToils()
        {
            this.FailOnDespawnedNullOrForbidden(TargetIndex.A);
            this.FailOnBurningImmobile(TargetIndex.A);
            this.FailOnThingHavingDesignation(TargetIndex.A, DesignationDefOf.Deconstruct);
            this.FailOn(delegate()
            {
                CompMineShaft compMiningPlatform = this.job.targetA.Thing.TryGetComp <CompMineShaft>();
                return(!compMiningPlatform.CanMine());
            });
            yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell));

            Toil work = new Toil();

            work.tickAction = delegate()
            {
                Pawn          actor    = work.actor;
                Building      building = (Building)actor.CurJob.targetA.Thing;
                CompMineShaft comp     = building.GetComp <CompMineShaft>();

                var hungerOnPawn = work.actor?.health?.hediffSet?.GetFirstHediffOfDef(OreDefOf.MinersHunger);

                if (hungerOnPawn == null)
                {
                    Hediff hediff = HediffMaker.MakeHediff(OreDefOf.MinersHunger, work.actor, null);
                    hediff.Severity = 0.01f;
                    work.actor.health.AddHediff(hediff, null, null);
                }
                else
                {
                    hungerOnPawn.Severity += 0.01f;
                }

                /*
                 * if (comp.ProspectMode)
                 * {
                 *  comp.Prospecting(actor);
                 * }
                 * else
                 * {
                 *  comp.MiningWorkDone(actor);
                 * }
                 */
                actor.skills.Learn(SkillDefOf.Mining, 0.065f, false);
            };


            work.defaultCompleteMode = ToilCompleteMode.Never;
            work.WithEffect(EffecterDefOf.Drill, TargetIndex.A);
            work.WithEffect(EffecterDefOf.Mine, TargetIndex.B);
            work.FailOnCannotTouch(TargetIndex.A, PathEndMode.InteractionCell);
            work.activeSkill = (() => SkillDefOf.Mining);
            yield return(work);

            yield break;
        }
예제 #4
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            this.FailOnDespawnedNullOrForbidden(TargetIndex.A);
            yield return(Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.Touch).FailOnDespawnedNullOrForbidden(TargetIndex.B).FailOnSomeonePhysicallyInteracting(TargetIndex.B));

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

            yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch).FailOnDespawnedOrNull(TargetIndex.A));

            Toil toil = new Toil().FailOnDespawnedOrNull(TargetIndex.A);

            toil.defaultDuration = 15 * TargetB.Thing.stackCount;
            toil.WithEffect(EffecterDefOf.ConstructWood, TargetIndex.A);
            toil.WithProgressBarToilDelay(TargetIndex.A, false, -0.5f);
            toil.defaultCompleteMode = ToilCompleteMode.Delay;
            yield return(toil);

            yield return(new Toil
            {
                initAction = delegate
                {
                    this.TargetA.Thing.HitPoints = this.TargetA.Thing.HitPoints + this.Cloth.stackCount;
                    if (this.TargetA.Thing.HitPoints > this.TargetA.Thing.MaxHitPoints)
                    {
                        this.TargetA.Thing.HitPoints = this.TargetA.Thing.MaxHitPoints;
                    }
                    this.Cloth.Destroy(DestroyMode.Vanish);
                }
            });

            yield break;
        }
예제 #5
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            this.FailOnDespawnedNullOrForbidden(TargetIndex.A);
            yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch));

            Toil repair = new Toil();

            repair.initAction = delegate
            {
                this.$this.ticksToNextRepair = 80f;
            };
            repair.tickAction = delegate
            {
                Pawn actor = repair.actor;
                actor.skills.Learn(SkillDefOf.Construction, 0.275f, false);
                float statValue = actor.GetStatValue(StatDefOf.ConstructionSpeed, true);
                this.$this.ticksToNextRepair -= statValue;
                if (this.$this.ticksToNextRepair <= 0f)
                {
                    this.$this.ticksToNextRepair += 20f;
                    this.$this.TargetThingA.HitPoints++;
                    this.$this.TargetThingA.HitPoints = Mathf.Min(this.$this.TargetThingA.HitPoints, this.$this.TargetThingA.MaxHitPoints);
                    this.$this.Map.listerBuildingsRepairable.Notify_BuildingRepaired((Building)this.$this.TargetThingA);
                    if (this.$this.TargetThingA.HitPoints == this.$this.TargetThingA.MaxHitPoints)
                    {
                        actor.records.Increment(RecordDefOf.ThingsRepaired);
                        actor.jobs.EndCurrentJob(JobCondition.Succeeded, true);
                    }
                }
            };
            repair.FailOnCannotTouch(TargetIndex.A, PathEndMode.Touch);
            repair.WithEffect(base.TargetThingA.def.repairEffect, TargetIndex.A);
            repair.defaultCompleteMode = ToilCompleteMode.Never;
            yield return(repair);
        }
예제 #6
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            this.FailOnDespawnedNullOrForbidden(TargetIndex.A);
            yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell));

            Toil research = new Toil();

            research.tickAction = delegate
            {
                Pawn  actor     = research.actor;
                float statValue = actor.GetStatValue(StatDefOf.ResearchSpeed);
                statValue *= base.TargetThingA.GetStatValue(StatDefOf.ResearchSpeedFactor);
                Find.ResearchManager.ResearchPerformed(statValue, actor);
                actor.skills.Learn(SkillDefOf.Intellectual, 0.1f);
                actor.GainComfortFromCellIfPossible(chairsOnly: true);
            };
            research.FailOn(() => Project == null);
            research.FailOn(() => !Project.CanBeResearchedAt(ResearchBench, ignoreResearchBenchPowerStatus: false));
            research.FailOnCannotTouch(TargetIndex.A, PathEndMode.InteractionCell);
            research.WithEffect(EffecterDefOf.Research, TargetIndex.A);
            research.WithProgressBar(TargetIndex.A, () => Project?.ProgressPercent ?? 0f);
            research.defaultCompleteMode = ToilCompleteMode.Delay;
            research.defaultDuration     = 4000;
            research.activeSkill         = () => SkillDefOf.Intellectual;
            yield return(research);

            yield return(Toils_General.Wait(2));
        }
        // Token: 0x06000393 RID: 915 RVA: 0x000245C8 File Offset: 0x000229C8
        protected override IEnumerable <Toil> MakeNewToils()
        {
            this.FailOnIncapable(PawnCapacityDefOf.Manipulation);
            yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch));

            Toil prepare = Toils_General.Wait(this.useDuration, TargetIndex.None);

            prepare.NPCWithProgressBarToilDelay(TargetIndex.A, false, -0.5f);
            prepare.FailOnDespawnedNullOrForbidden(TargetIndex.A);
            prepare.FailOnCannotTouch(TargetIndex.A, PathEndMode.Touch);
            prepare.WithEffect(EffecterDefOf.Vomit, TargetIndex.A);
            prepare.PlaySustainerOrSound(() => SoundDefOf.Vomit);
            yield return(prepare);

            Toil use = new Toil();

            use.initAction = delegate()
            {
                Pawn actor = use.actor;
                base.Map.roofGrid.SetRoof(TargetA.Cell, RoofDefOf.RoofConstructed);
                MoteMaker.PlaceTempRoof(TargetA.Cell, base.Map);
            };
            use.defaultCompleteMode = ToilCompleteMode.Instant;
            yield return(use);

            yield break;
        }
        // Token: 0x06000393 RID: 915 RVA: 0x000245C8 File Offset: 0x000229C8
        protected override IEnumerable <Toil> MakeNewToils()
        {
            this.FailOnIncapable(PawnCapacityDefOf.Manipulation);
            yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch));

            Toil prepare = Toils_General.Wait(this.useDuration, TargetIndex.None);

            prepare.NPCWithProgressBarToilDelay(TargetIndex.A, false, -0.5f);
            prepare.FailOnDespawnedNullOrForbidden(TargetIndex.A);
            prepare.FailOnCannotTouch(TargetIndex.A, PathEndMode.Touch);
            prepare.WithEffect(EffecterDefOf.Vomit, TargetIndex.A);
            prepare.PlaySustainerOrSound(() => SoundDefOf.Vomit);
            yield return(prepare);

            Toil use = new Toil();

            use.initAction = delegate()
            {
                Pawn actor = use.actor;
                MyDef = XenomorphDefOf.RRY_Xenomorph_Hive;
                Thing    thing = ThingMaker.MakeThing(MyDef);
                HiveLike hive  = (HiveLike)thing;
                GenSpawn.Spawn(thing, TargetA.Cell, actor.Map, Rot4.South, WipeMode.FullRefund, false);
            };
            use.defaultCompleteMode = ToilCompleteMode.Instant;
            yield return(use);

            yield break;
        }
        // Token: 0x06000373 RID: 883 RVA: 0x0001EF58 File Offset: 0x0001D358
        protected override IEnumerable <Toil> MakeNewToils()
        {
            this.FailOnIncapable(PawnCapacityDefOf.Manipulation);
            yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell));

            Toil prepare = Toils_General.Wait(this.useDuration, TargetIndex.A);

            prepare.NPCWithProgressBarToilDelay(TargetIndex.A, false, -0.5f);
            prepare.FailOnDespawnedNullOrForbidden(TargetIndex.A);

            prepare.WithEffect(EffecterDefOf.Vomit, TargetIndex.A);
            prepare.PlaySustainerOrSound(() => SoundDefOf.Vomit);
            yield return(prepare);

            Toil use = new Toil();

            use.initAction = delegate()
            {
                Pawn actor      = use.actor;
                Pawn Infectable = (Pawn)actor.CurJob.targetA.Thing;
                Infectable.health.AddHediff(heCocDeff);
            };
            use.defaultCompleteMode = ToilCompleteMode.Instant;
            yield return(use);

            yield break;
        }
예제 #10
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            this.FailOnDespawnedNullOrForbidden(TargetIndex.A);
            yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell));

            Toil research = new Toil();

            research.tickAction = delegate
            {
                Pawn  actor = research.actor;
                float num   = 1.1f * actor.GetStatValue(StatDefOf.ResearchSpeed, true);
                num *= this.$this.TargetThingA.GetStatValue(StatDefOf.ResearchSpeedFactor, true);
                Find.ResearchManager.ResearchPerformed(num, actor);
                actor.skills.Learn(SkillDefOf.Intellectual, 0.11f, false);
                actor.GainComfortFromCellIfPossible();
            };
            research.FailOn(() => this.$this.Project == null);
            research.FailOn(() => !this.$this.Project.CanBeResearchedAt(this.$this.ResearchBench, false));
            research.FailOnCannotTouch(TargetIndex.A, PathEndMode.InteractionCell);
            research.WithEffect(EffecterDefOf.Research, TargetIndex.A);
            research.WithProgressBar(TargetIndex.A, delegate
            {
                ResearchProjectDef project = this.$this.Project;
                if (project == null)
                {
                    return(0f);
                }
                return(project.ProgressPercent);
            }, false, -0.5f);
            research.defaultCompleteMode = ToilCompleteMode.Delay;
            research.defaultDuration     = 4000;
            yield return(research);

            yield return(Toils_General.Wait(2));
        }
예제 #11
0
    protected override IEnumerable <Toil> MakeNewToils()
    {
        this.FailOnDespawnedNullOrForbidden(TargetIndex.A);
        this.FailOnBurningImmobile(TargetIndex.A);
        this.FailOnThingHavingDesignation(TargetIndex.A, DesignationDefOf.Uninstall);
        this.FailOn(delegate
        {
            var compManualDrill = job.targetA.Thing.TryGetComp <CompManualDrill>();
            return(compManualDrill == null || compManualDrill.prospected || !compManualDrill.windOk);
        });
        yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell));

        var work = new Toil();

        work.tickAction = delegate
        {
            var actor    = work.actor;
            var building = (Building)actor.CurJob.targetA.Thing;
            building.GetComp <CompManualDrill>().ManualProspectWorkDone(actor, building);
            actor.skills.Learn(SkillDefOf.Mining, 0.07f);
        };
        work.defaultCompleteMode = ToilCompleteMode.Never;
        if (Controller.Settings.AllowManualSound)
        {
            work.WithEffect(ProspectDef.PrsManualDrillEff, TargetIndex.A);
        }

        work.FailOnCannotTouch(TargetIndex.A, PathEndMode.InteractionCell);
        work.activeSkill = () => SkillDefOf.Mining;
        yield return(work);
    }
        protected override IEnumerable <Toil> MakeNewToils()
        {
            this.FailOnDespawnedNullOrForbidden(TargetIndex.A);
            yield return(Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.Touch).FailOnDespawnedNullOrForbidden(TargetIndex.B).FailOnSomeonePhysicallyInteracting(TargetIndex.B));

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

            yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch).FailOnDespawnedOrNull(TargetIndex.A));

            Toil repair = Toils_General.Wait(1000, TargetIndex.None);

            repair.FailOnDespawnedOrNull(TargetIndex.A);
            repair.FailOnCannotTouch(TargetIndex.A, PathEndMode.Touch);
            repair.WithEffect(this.Building.def.repairEffect, TargetIndex.A);
            repair.WithProgressBarToilDelay(TargetIndex.A, false, -0.5f);
            yield return(repair);

            yield return(new Toil
            {
                initAction = delegate
                {
                    this.$this.Components.Destroy(DestroyMode.Vanish);
                    if (Rand.Value > this.$this.pawn.GetStatValue(StatDefOf.FixBrokenDownBuildingSuccessChance, true))
                    {
                        Vector3 loc = (this.$this.pawn.DrawPos + this.$this.Building.DrawPos) / 2f;
                        MoteMaker.ThrowText(loc, this.$this.Map, "TextMote_FixBrokenDownBuildingFail".Translate(), 3.65f);
                    }
                    else
                    {
                        this.$this.Building.GetComp <CompBreakdownable>().Notify_Repaired();
                    }
                }
            });
        }
예제 #13
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            yield return(Toils_Goto.GotoCell(TargetIndex.A, PathEndMode.Touch));

            Toil clearToil = new Toil();

            clearToil.tickAction = delegate
            {
                Pawn  actor     = clearToil.actor;
                float statValue = actor.GetStatValue(StatDefOf.UnskilledLaborSpeed, true);
                float num       = statValue;
                this.$this.workDone += num;
                if (this.$this.workDone >= this.$this.TotalNeededWork)
                {
                    this.$this.Map.snowGrid.SetDepth(this.$this.TargetLocA, 0f);
                    this.$this.ReadyForNextToil();
                    return;
                }
            };
            clearToil.defaultCompleteMode = ToilCompleteMode.Never;
            clearToil.WithEffect(EffecterDefOf.ClearSnow, TargetIndex.A);
            clearToil.PlaySustainerOrSound(() => SoundDefOf.Interact_CleanFilth);
            clearToil.WithProgressBar(TargetIndex.A, () => this.$this.workDone / this.$this.TotalNeededWork, true, -0.5f);
            clearToil.FailOnCannotTouch(TargetIndex.A, PathEndMode.Touch);
            yield return(clearToil);
        }
예제 #14
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            this.FailOnDespawnedNullOrForbidden(TargetIndex.A);
            yield return(Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.Touch).FailOnDespawnedNullOrForbidden(TargetIndex.B).FailOnSomeonePhysicallyInteracting(TargetIndex.B));

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

            yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch).FailOnDespawnedOrNull(TargetIndex.A));

            Toil toil = Toils_General.Wait(1000);

            toil.FailOnDespawnedOrNull(TargetIndex.A);
            toil.FailOnCannotTouch(TargetIndex.A, PathEndMode.Touch);
            toil.WithEffect(Building.def.repairEffect, TargetIndex.A);
            toil.WithProgressBarToilDelay(TargetIndex.A);
            toil.activeSkill = () => SkillDefOf.Construction;
            yield return(toil);

            Toil toil2 = new Toil();

            toil2.initAction = delegate
            {
                Components.Destroy();
                if (Rand.Value > pawn.GetStatValue(StatDefOf.FixBrokenDownBuildingSuccessChance))
                {
                    MoteMaker.ThrowText((pawn.DrawPos + Building.DrawPos) / 2f, base.Map, "TextMote_FixBrokenDownBuildingFail".Translate(), 3.65f);
                }
                else
                {
                    Building.GetComp <CompBreakdownable>().Notify_Repaired();
                }
            };
            yield return(toil2);
        }
예제 #15
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            this.FailOnDespawnedNullOrForbidden(TargetIndex.A);
            yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch));

            Toil work = new Toil();

            work.tickAction = delegate()
            {
                Pawn actor = work.actor;
                if (!Vehicle.CompUpgradeTree.CurrentlyUpgrading)
                {
                    actor.jobs.EndCurrentJob(JobCondition.Succeeded, true);
                    return;
                }
                actor.skills.Learn(SkillDefOf.Construction, 0.08f, false);
                float statValue = actor.GetStatValue(StatDefOf.ConstructionSpeed, true);
                if (statValue < 1)
                {
                    statValue = 1;
                }
                Vehicle.CompUpgradeTree.NodeUnlocking.Ticks -= (int)statValue;
            };
            work.FailOnCannotTouch(TargetIndex.A, PathEndMode.Touch);
            work.WithEffect(TargetThingA.def.repairEffect, TargetIndex.A);
            work.defaultCompleteMode = ToilCompleteMode.Never;
            work.activeSkill         = (() => SkillDefOf.Construction);
            yield return(work);
        }
예제 #16
0
        // Token: 0x0600004C RID: 76 RVA: 0x00004148 File Offset: 0x00002348
        protected override IEnumerable <Toil> MakeNewToils()
        {
            this.FailOnDespawnedNullOrForbidden(TargetIndex.A);
            this.FailOnBurningImmobile(TargetIndex.A);
            this.FailOn(delegate()
            {
                CompDeepDrill compDeepDrill = this.job.targetA.Thing.TryGetComp <CompDeepDrill>();
                return(!compDeepDrill.CanDrillNow());
            });
            yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell));

            Toil work = new Toil();

            work.tickAction = delegate()
            {
                Pawn          actor    = work.actor;
                Building      building = (Building)actor.CurJob.targetA.Thing;
                CompDeepDrill comp     = building.GetComp <CompDeepDrill>();
                comp.DrillWorkDone(actor);
            };
            work.defaultCompleteMode = ToilCompleteMode.Never;
            work.WithEffect(EffecterDefOf.Drill, TargetIndex.A);
            work.FailOnCannotTouch(TargetIndex.A, PathEndMode.InteractionCell);
            yield return(work);

            yield break;
        }
        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 Toil Cultivate()
        {
            var targetCell = CurJob.targetA.Cell;

            var toil = new Toil();
            toil.initAction = () =>
            {
                workTicks = Mathf.RoundToInt(terrainReplacements[targetCell.GetTerrain()].GetStatValueAbstract(StatDefOf.WorkToMake) * pawn.GetStatValue(StatDefOf.PlantWorkSpeed));
                pawn.jobs.curDriver.ticksLeftThisToil = workTicks;
            };
            toil.tickAction = () =>
            {
                if (--pawn.jobs.curDriver.ticksLeftThisToil < 0)
                {
                    // remove designation
                    var designation = Find.DesignationManager.DesignationAt(targetCell,
                        DefDatabase<DesignationDef>.GetNamed("CultivateLand"));
                    if (designation != null)
                    {
                        Find.DesignationManager.RemoveDesignation(designation);
                    }

                    // replace terrain
                    Find.TerrainGrid.SetTerrain(targetCell, terrainReplacements[targetCell.GetTerrain()]);

                    ReadyForNextToil();
                }
            };
            toil.defaultCompleteMode = ToilCompleteMode.Never;
            toil.FailOnCellMissingDesignation(CellInd, DefDatabase<DesignationDef>.GetNamed("CultivateLand"));
            toil.WithEffect(() => EffecterDef.Named("CutStone"), CellInd);
            toil.PlaySustainerOrSound(() => DefDatabase<SoundDef>.GetNamedSilentFail("Recipe_Surgery"));
            toil.WithProgressBar(CellInd, () => 1f - (float) pawn.jobs.curDriver.ticksLeftThisToil/workTicks);
            return toil;
        }
    public void AddIngestionEffects(Toil toil, Pawn chewer, TargetIndex ingestibleInd, TargetIndex eatSurfaceInd)
    {
        //Log.Message("3");
        if (Victim == null)
        {
            EndJobWith(JobCondition.Incompletable);
        }

        toil.WithEffect(delegate
        {
            var target = toil.actor.CurJob.GetTarget(ingestibleInd);
            if (!target.HasThing)
            {
                return(null);
            }

            var result = target.Thing.def.ingestible.ingestEffect;
            if (chewer.RaceProps.intelligence < Intelligence.ToolUser &&
                target.Thing.def.ingestible.ingestEffectEat != null)
            {
                result = target.Thing?.def?.ingestible?.ingestEffectEat ?? null;
            }

            return(result);
        }, delegate
        {
            if (!toil.actor.CurJob.GetTarget(ingestibleInd).HasThing)
            {
                return(null);
            }

            var thing = toil.actor.CurJob.GetTarget(ingestibleInd).Thing;
            if (chewer != toil.actor)
            {
                return(chewer);
            }

            if (eatSurfaceInd != TargetIndex.None && toil.actor.CurJob.GetTarget(eatSurfaceInd).IsValid)
            {
                return((LocalTargetInfo)toil.actor?.CurJob?.GetTarget(eatSurfaceInd));
            }

            return(thing);
        });
        toil.PlaySustainerOrSound(delegate
        {
            if (!chewer.RaceProps.Humanlike)
            {
                return(null);
            }

            var target = toil.actor.CurJob.GetTarget(ingestibleInd);
            if (!target.HasThing)
            {
                return(null);
            }

            return(target.Thing.def.ingestible.ingestSound);
        });
    }
        protected override IEnumerable <Toil> MakeNewToils()
        {
            this.FailOnDespawnedOrNull(TargetIndex.B);
            yield return(Toils_Goto.Goto(TargetIndex.B, this.PathEndMode));

            Toil doWork = new Toil();

            doWork.initAction = delegate()
            {
                this.workLeft = 65f;
            };
            doWork.tickAction = delegate()
            {
                float statValue = doWork.actor.GetStatValue(StatDefOf.ConstructionSpeed, true);
                this.workLeft -= statValue;
                if (this.workLeft <= 0f)
                {
                    this.DoEffect();
                    this.ReadyForNextToil();
                }
            };
            doWork.FailOnCannotTouch(TargetIndex.B, this.PathEndMode);
            doWork.PlaySoundAtStart(SoundDefOf.Roof_Start);
            doWork.PlaySoundAtEnd(SoundDefOf.Roof_Finish);
            doWork.WithEffect(EffecterDefOf.RoofWork, TargetIndex.A);
            doWork.FailOn(new Func <bool>(this.DoWorkFailOn));
            doWork.WithProgressBar(TargetIndex.A, () => 1f - this.workLeft / 65f, false, -0.5f);
            doWork.defaultCompleteMode = ToilCompleteMode.Never;
            yield return(doWork);

            yield break;
        }
        protected override IEnumerable <Toil> MakeNewToils()
        {
            this.FailOnDespawnedNullOrForbidden(TargetIndex.A);
            yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch).FailOnDespawnedNullOrForbidden(TargetIndex.A));

            startingDurability = Durability;
            var maintenance = new Toil();

            maintenance.tickAction = delegate
            {
                Pawn pawn = maintenance.actor;
                Durability += pawn.GetStatValue(StatDefOf.ConstructionSpeed) / fullRepairTicks;
                pawn.skills.Learn(SkillDefOf.Construction, 0.125f);

                if (Durability > .99f)
                {
                    pawn.records.Increment(RecordDefOf.ThingsRepaired);
                    pawn.jobs.EndCurrentJob(JobCondition.Succeeded);
                }
            };
            maintenance.FailOnCannotTouch(TargetIndex.A, PathEndMode.Touch);
            maintenance.WithEffect(TargetThingA.def.repairEffect, TargetIndex.A);
            maintenance.WithProgressBar(TargetIndex.A, progress, true);
            maintenance.defaultCompleteMode = ToilCompleteMode.Never;
            yield return(maintenance);
        }
예제 #22
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            yield return(Toils_Reserve.Reserve(TargetIndex.A, 4, 0, null));

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

            Toil t2 = Toils_General.Wait(6000);

            t2.AddFailCondition(() => this.Building.GetComp <CompWeatherSat>() == null);
            t2            = t2.WithEffect(EffecterDefOf.Research, TargetIndex.A);
            t2.tickAction = delegate()
            {
                float num = 0.0002f;
                num *= 1f + 0.5f * (float)base.GetActor().story.traits.DegreeOfTrait(TraitDef.Named("PsychicSensitivity"));
                CompWeatherSat comp = this.Building.GetComp <CompWeatherSat>();
                if (comp != null)
                {
                    comp.mana += num;
                    if (comp.mana < 0f)
                    {
                        comp.mana = 0f;
                    }
                    if (comp.mana > 100f)
                    {
                        comp.mana = 100f;
                    }
                }
            };
            yield return(t2);

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

            yield break;
        }
예제 #23
0
        public static Toil DrawWater(TargetIndex drawerIndex, int drawTicks)
        {
            Toil toil = new Toil();

            toil.initAction = delegate
            {
                Pawn  actor    = toil.actor;
                Thing thing    = actor.CurJob.GetTarget(drawerIndex).Thing;
                var   building = thing as IBuilding_DrinkWater;
                if (building == null ||
                    building.WaterType == WaterType.Undefined ||
                    building.WaterType == WaterType.NoWater ||
                    !building.CanDrawFor(actor))
                {
                    actor.jobs.EndCurrentJob(JobCondition.Incompletable, true);
                    return;
                }

                actor.rotationTracker.FaceCell(actor.Position);
                actor.jobs.curDriver.ticksLeftThisToil = drawTicks;
            };
            toil.tickAction = delegate
            {
                toil.actor.GainComfortFromCellIfPossible();
            };
            toil.defaultCompleteMode = ToilCompleteMode.Delay;
            toil.FailOnDestroyedOrNull(drawerIndex);

            // エフェクト追加
            toil.WithEffect(DefDatabase <EffecterDef> .GetNamed("Cook"), drawerIndex);
            toil.PlaySustainerOrSound(DefDatabase <SoundDef> .GetNamed("Recipe_CookMeal"));
            return(toil);
        }
예제 #24
0
        public static Toil MakeTableReady(TargetIndex diningSpotInd, TargetIndex chairInd)
        {
            Toil toil = new Toil {
                defaultCompleteMode = ToilCompleteMode.Delay, defaultDuration = 100
            };

            toil.WithProgressBarToilDelay(diningSpotInd, true);
            toil.AddFinishAction(() => {
                var target = toil.actor.CurJob.GetTarget(chairInd);
                IntVec3 chairPos;

                if (target.IsValid)
                {
                    chairPos = target.Cell;
                }
                else
                {
                    toil.actor.jobs.EndCurrentJob(JobCondition.Errored);
                    return;
                }

                //Log.Message($"About to make spot ready ({toil.actor.CurJob.GetTarget(diningSpotInd).Cell}) from {toil.actor.CurJob.GetTarget(diningSpotInd).Cell}.");
                if (toil.actor.CurJob.GetTarget(diningSpotInd).Thing is DiningSpot diningSpot)
                {
                    diningSpot.SetSpotReady(chairPos);
                }
            });
            toil.WithEffect(EffecterDefOf.Clean, diningSpotInd);
            toil.PlaySustainerOrSound(() => SoundDefOf.Interact_CleanFilth);
            return(toil);
        }
예제 #25
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            this.FailOnDespawnedNullOrForbidden(TargetIndex.A);
            yield return(Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.Touch).FailOnDespawnedNullOrForbidden(TargetIndex.B).FailOnSomeonePhysicallyInteracting(TargetIndex.B));

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

            yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch).FailOnDespawnedOrNull(TargetIndex.A));

            Toil repair = Toils_General.Wait(75, TargetIndex.None);

            repair.FailOnDespawnedOrNull(TargetIndex.A);
            repair.FailOnCannotTouch(TargetIndex.A, PathEndMode.Touch);
            repair.WithEffect(Gun.def.repairEffect, TargetIndex.A);
            repair.WithProgressBarToilDelay(TargetIndex.A, false, -0.5f);
            yield return(repair);

            yield return(new Toil
            {
                initAction = delegate()
                {
                    BeamColorThing.BeamColor = pawn.CurJob.maxNumMeleeAttacks;

                    var targetInfo = new TargetInfo(Gun.Position, Map, false);
                    Effecter effecter = EffecterDefOf.Deflect_Metal.Spawn();
                    effecter.Trigger(targetInfo, targetInfo);
                    effecter.Cleanup();
                    this.Prism.Destroy(DestroyMode.Vanish);
                }
            });

            yield break;
        }
        protected override IEnumerable <Toil> MakeNewToils()
        {
            this.FailOnDespawnedOrNull(TargetIndex.B);
            yield return(Toils_Goto.Goto(TargetIndex.B, PathEndMode));

            Toil doWork = new Toil();

            doWork.initAction = delegate
            {
                workLeft = 65f;
            };
            doWork.tickAction = delegate
            {
                float num = doWork.actor.GetStatValue(StatDefOf.ConstructionSpeed) * 1.7f;
                workLeft -= num;
                if (workLeft <= 0f)
                {
                    DoEffect();
                    ReadyForNextToil();
                }
            };
            doWork.FailOnCannotTouch(TargetIndex.B, PathEndMode);
            doWork.PlaySoundAtStart(SoundDefOf.Roof_Start);
            doWork.PlaySoundAtEnd(SoundDefOf.Roof_Finish);
            doWork.WithEffect(EffecterDefOf.RoofWork, TargetIndex.A);
            doWork.FailOn(DoWorkFailOn);
            doWork.WithProgressBar(TargetIndex.A, () => 1f - workLeft / 65f);
            doWork.defaultCompleteMode = ToilCompleteMode.Never;
            doWork.activeSkill         = () => SkillDefOf.Construction;
            yield return(doWork);
        }
예제 #27
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            this.FailOnDespawnedNullOrForbidden(TargetIndex.A);
            this.FailOn(delegate() { return(Chamber.CanIrradiateNow(pawn) != null); });
            //           AddFinishAction(delegate () { if (pawn.IsPrisoner) pawn.SetForbidden(false); });

            yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell).FailOnDespawnedOrNull(TargetIndex.A));

            Toil work = new Toil();

            work.defaultCompleteMode = ToilCompleteMode.Never;
            work.WithEffect(EffecterDefOf.Drill, TargetIndex.A);
            work.FailOnCannotTouch(TargetIndex.A, PathEndMode.Touch);

            work.tickAction = delegate()
            {
                if (pawn.IsHashIntervalTick(60))
                {
                    Chamber.Irradiate(work.actor, 60);
                }
            };
            yield return(work);

            yield break;
        }
예제 #28
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            yield return(Toils_Reserve.Reserve(TargetIndex.A, 1, -1, null));

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

            Toil t2 = Toils_General.Wait(1000);

            t2 = t2.WithEffect(EffecterDefOf.Research, TargetIndex.A);
            float fResearchScore = base.GetActor().GetStatValue(StatDefOf.ResearchSpeed, true);

            t2.tickAction = delegate()
            {
                if (180000f * Rand.Value < fResearchScore)
                {
                    this.TriggerFindStargate();
                    this.EndJobWith(JobCondition.Succeeded);
                }
            };
            yield return(t2);

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

            yield break;
        }
        protected override IEnumerable <Toil> MakeNewToils()
        {
            yield return(Toils_Goto.GotoCell(TargetIndex.A, PathEndMode.Touch).FailOn(() => PlantUtility.AdjacentSowBlocker(this.job.plantDefToSow, this.TargetA.Cell, this.Map) != null).FailOn(() => !this.job.plantDefToSow.CanEverPlantAt(this.TargetLocA, this.Map)));

            Toil sowToil = new Toil();

            sowToil.initAction = delegate()
            {
                this.TargetThingA = GenSpawn.Spawn(this.job.plantDefToSow, this.TargetLocA, this.Map, WipeMode.Vanish);
                this.pawn.Reserve(this.TargetThingA, sowToil.actor.CurJob, 1, -1, null, true);
                Plant plant = (Plant)this.TargetThingA;
                plant.Growth = 0f;
                plant.sown   = true;
            };
            sowToil.tickAction = delegate()
            {
                Pawn actor = sowToil.actor;
                if (actor.skills != null)
                {
                    actor.skills.Learn(SkillDefOf.Plants, 0.085f, false);
                }
                float statValue = actor.GetStatValue(StatDefOf.PlantWorkSpeed, true);
                float num       = statValue;
                Plant plant     = this.Plant;
                if (plant.LifeStage != PlantLifeStage.Sowing)
                {
                    Log.Error(this.$this + " getting sowing work while not in Sowing life stage.", false);
                }
                this.sowWorkDone += num;
                if (this.sowWorkDone >= plant.def.plant.sowWork)
                {
                    plant.Growth = 0.05f;
                    this.Map.mapDrawer.MapMeshDirty(plant.Position, MapMeshFlag.Things);
                    actor.records.Increment(RecordDefOf.PlantsSown);
                    this.ReadyForNextToil();
                    return;
                }
            };
            sowToil.defaultCompleteMode = ToilCompleteMode.Never;
            sowToil.FailOnDespawnedNullOrForbidden(TargetIndex.A);
            sowToil.FailOnCannotTouch(TargetIndex.A, PathEndMode.Touch);
            sowToil.WithEffect(EffecterDefOf.Sow, TargetIndex.A);
            sowToil.WithProgressBar(TargetIndex.A, () => this.sowWorkDone / this.Plant.def.plant.sowWork, true, -0.5f);
            sowToil.PlaySustainerOrSound(() => SoundDefOf.Interact_Sow);
            sowToil.AddFinishAction(delegate
            {
                if (this.TargetThingA != null)
                {
                    Plant plant = (Plant)sowToil.actor.CurJob.GetTarget(TargetIndex.A).Thing;
                    if (this.sowWorkDone < plant.def.plant.sowWork && !this.TargetThingA.Destroyed)
                    {
                        this.TargetThingA.Destroy(DestroyMode.Vanish);
                    }
                }
            });
            sowToil.activeSkill = (() => SkillDefOf.Plants);
            yield return(sowToil);

            yield break;
        }
예제 #30
0
        // I wanted them to repair forbidden doors, but can't get it working.
        static bool Prefix(JobDriver_Repair __instance, ref IEnumerable <Toil> __result)
        {
            JobDriver_Repair new_this = __instance;

            List <Toil> new_result = new List <Toil>();

            BindingFlags bindFlags = BindingFlags.Instance | BindingFlags.NonPublic;

            FieldInfo field_ticksToNextRepair = typeof(JobDriver_Repair).GetField("ticksToNextRepair", bindFlags);
            float     new_ticksToNextRepair   = (float)field_ticksToNextRepair.GetValue(__instance);

            PropertyInfo field_baseTargetThingA = typeof(JobDriver_Repair).GetProperty("TargetThingA", bindFlags);
            Thing        new_baseTargetThingA   = (Thing)field_baseTargetThingA.GetValue(__instance);

            PropertyInfo field_baseMap = typeof(JobDriver_Repair).GetProperty("Map", bindFlags);
            Map          new_baseMap   = (Map)field_baseMap.GetValue(__instance);


            //new_this.FailOnDespawnedOrNull(TargetIndex.A);
            new_result.Add(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch));
            Toil repair = new Toil();

            repair.initAction = delegate
            {
                //ticksToNextRepair = 80f;
                field_ticksToNextRepair.SetValue(__instance, 80f);
            };
            repair.tickAction = delegate
            {
                Pawn actor = repair.actor;
                actor.skills.Learn(SkillDefOf.Construction, 0.05f);
                float num = actor.GetStatValue(StatDefOf.ConstructionSpeed) * 1.7f;
                //ticksToNextRepair -= num;
                field_ticksToNextRepair.SetValue(__instance, ((float)field_ticksToNextRepair.GetValue(__instance)) - num);

                if (((float)field_ticksToNextRepair.GetValue(__instance)) <= 0f)
                {
                    //ticksToNextRepair += 20f;
                    field_ticksToNextRepair.SetValue(__instance, ((float)field_ticksToNextRepair.GetValue(__instance)) + 20f);

                    new_baseTargetThingA.HitPoints++;
                    new_baseTargetThingA.HitPoints = Mathf.Min(new_baseTargetThingA.HitPoints, new_baseTargetThingA.MaxHitPoints);
                    new_baseMap.listerBuildingsRepairable.Notify_BuildingRepaired((Building)new_baseTargetThingA);
                    if (new_baseTargetThingA.HitPoints == new_baseTargetThingA.MaxHitPoints)
                    {
                        actor.records.Increment(RecordDefOf.ThingsRepaired);
                        actor.jobs.EndCurrentJob(JobCondition.Succeeded);
                    }
                }
            };
            repair.FailOnCannotTouch(TargetIndex.A, PathEndMode.Touch);
            repair.WithEffect(new_baseTargetThingA.def.repairEffect, TargetIndex.A);
            repair.defaultCompleteMode = ToilCompleteMode.Never;
            repair.activeSkill         = (() => SkillDefOf.Construction);
            new_result.Add(repair);
            __result = new_result.AsEnumerable <Toil>();
            return(false);
        }
        protected override IEnumerable<Toil> MakeNewToils()
        {
            this.FailOnDestroyedOrForbidden<JobDriver_PlantHarvestWithSeeds>(TargetIndex.A);
            yield return Toils_Reserve.Reserve(TargetIndex.A, 1);
            yield return Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch);

            var toil = new Toil();
            toil.tickAction = () =>
            {
                Pawn actor = toil.actor;
                if (actor.skills != null)
                    actor.skills.Learn(SkillDefOf.Growing, 0.154f);
                float num = actor.GetStatValue(StatDefOf.PlantWorkSpeed, true);
                Plant plant = (Plant)actor.jobs.curJob.GetTarget(TargetIndex.A).Thing;
                harvestWorkDone += num;
                if (harvestWorkDone >= plant.def.plant.harvestWork)
                {
                    if (plant.def.plant.harvestedThingDef != null)
                    {
                        int num2 = plant.YieldNow();
                        if (plant is PlantWithSeeds)
                            num2 = ((PlantWithSeeds)plant).YieldNow();
                        if (num2 > 0)
                        {
                            Thing t = ThingMaker.MakeThing(plant.def.plant.harvestedThingDef, null);
                            t.stackCount = num2;
                            if (actor.Faction != Faction.OfColony)
                                t.SetForbidden(true, true);
                            GenPlace.TryPlaceThing(t, actor.Position, ThingPlaceMode.Near);
                        }
                        if (plant is PlantWithSeeds)
                        {
                            PlantWithSeeds seeds = plant as PlantWithSeeds;
                            float num3 = Mathf.Max(Mathf.InverseLerp(seeds.def.plant.harvestMinGrowth, 1.2f, seeds.growth), 1f);
                            if (seeds.m_CustomPlantDef != null && seeds.m_CustomPlantDef.SeedDef != null && Rand.Value < (seeds.genome.baseSeedChance * num3))
                            {
                                Thing thing = ThingMaker.MakeThing(seeds.m_CustomPlantDef.SeedDef, null);
                                if (Rand.Value < (seeds.genome.addSeedChance * num3))
                                    thing.stackCount = 2;
                                else
                                    thing.stackCount = 1;
                                GenPlace.TryPlaceThing(thing, actor.Position, ThingPlaceMode.Near);
                            }
                        }
                    }
                    plant.PlantCollected();
                    plant.def.plant.soundHarvestFinish.PlayOneShot(actor);
                    harvestWorkDone = 0f;
                    ReadyForNextToil();
                }
            };
            toil.FailOnDestroyedOrForbidden<Toil>(TargetIndex.A);
            toil.defaultCompleteMode = ToilCompleteMode.Never;
            toil.WithEffect("Harvest", TargetIndex.A);
            toil.WithSustainer(() => toil.actor.jobs.curJob.GetTarget(TargetIndex.A).Thing.def.plant.soundHarvesting);
            yield return toil;
            yield return Toils_General.RemoveDesignationsOnThing(TargetIndex.A, DesignationDefOf.HarvestPlant);
        }
예제 #32
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            this.FailOnDespawnedNullOrForbidden(TargetIndex.A);
            yield return(Toils_Reserve.Reserve(TargetIndex.A, 1));

            //Toil 1: Go to the pruning site.
            yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch));

            //Toil 2: Begin pruning.
            Toil toil = new Toil();

            toil.defaultCompleteMode = ToilCompleteMode.Delay;
            toil.defaultDuration     = JobDriver_PruneAndRepair.remainingDuration;
            toil.WithProgressBarToilDelay(TargetIndex.A, false, -0.5f);
            toil.initAction = delegate
            {
                this.ticksToNextRepair = 80f;
            };
            toil.tickAction = delegate
            {
                Pawn actor = this.pawn;
                actor.skills.Learn(SkillDefOf.Construction, 0.5f, false);
                actor.skills.Learn(SkillDefOf.Plants, 0.5f, false);
                float statValue = actor.GetStatValue(StatDefOf.ConstructionSpeed, true);
                this.ticksToNextRepair -= statValue;
                if (this.ticksToNextRepair <= 0f)
                {
                    this.ticksToNextRepair += 16f;
                    this.TargetThingA.HitPoints++;
                    this.TargetThingA.HitPoints = Mathf.Min(this.TargetThingA.HitPoints, this.TargetThingA.MaxHitPoints);
                    //if (this.TargetThingA.HitPoints == this.TargetThingA.MaxHitPoints)
                    //{
                    //    actor.records.Increment(RecordDefOf.ThingsRepaired);
                    //    actor.jobs.EndCurrentJob(JobCondition.Succeeded, true);
                    //}
                }
            };
            toil.WithEffect(base.TargetThingA.def.repairEffect, TargetIndex.A);
            toil.defaultCompleteMode = ToilCompleteMode.Delay;
            yield return(toil);


            //Toil 3 Unreserve
            yield return(Toils_Reserve.Release(TargetIndex.A));

            //Toil 4: Transform the altar once again.
            yield return(new Toil
            {
                initAction = delegate
                {
                    PruneResult();
                },
                defaultCompleteMode = ToilCompleteMode.Instant
            });


            yield break;
        }
예제 #33
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch).FailOnDespawnedNullOrForbidden(TargetIndex.A));

            Toil build = new Toil();

            build.initAction = delegate()
            {
                GenClamor.DoClamor(build.actor, 15f, ClamorDefOf.Construction);
            };
            build.tickAction = delegate()
            {
                Pawn  actor = build.actor;
                Frame frame = this.Frame;
                if (frame.resourceContainer.Count > 0)
                {
                    actor.skills.Learn(SkillDefOf.Construction, 0.25f, false);
                }
                float num = actor.GetStatValue(StatDefOf.ConstructionSpeed, true);
                if (frame.Stuff != null)
                {
                    num *= frame.Stuff.GetStatValueAbstract(StatDefOf.ConstructionSpeedFactor, null);
                }
                float workToBuild = frame.WorkToBuild;
                if (actor.Faction == Faction.OfPlayer)
                {
                    float statValue = actor.GetStatValue(StatDefOf.ConstructSuccessChance, true);
                    if (Rand.Value < 1f - Mathf.Pow(statValue, num / workToBuild))
                    {
                        frame.FailConstruction(actor);
                        this.ReadyForNextToil();
                        return;
                    }
                }
                if (frame.def.entityDefToBuild is TerrainDef)
                {
                    this.Map.snowGrid.SetDepth(frame.Position, 0f);
                }
                frame.workDone += num;
                if (frame.workDone >= workToBuild)
                {
                    frame.CompleteConstruction(actor);
                    this.ReadyForNextToil();
                    return;
                }
            };
            build.WithEffect(() => ((Frame)build.actor.jobs.curJob.GetTarget(TargetIndex.A).Thing).ConstructionEffect, TargetIndex.A);
            build.FailOnDespawnedNullOrForbidden(TargetIndex.A);
            build.FailOnCannotTouch(TargetIndex.A, PathEndMode.Touch);
            build.FailOn(() => !GenConstruct.CanConstruct(this.Frame, this.pawn, true, false));
            build.defaultCompleteMode = ToilCompleteMode.Delay;
            build.defaultDuration     = 5000;
            build.activeSkill         = (() => SkillDefOf.Construction);
            yield return(build);

            yield break;
        }
        protected override IEnumerable<Toil> MakeNewToils()
        {
            this.FailOnDestroyedOrForbidden(TargetIndex.A);
            yield return Toils_Reserve.Reserve(TargetIndex.A);
            yield return Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch);

            var toil = new Toil();
            toil.tickAction = () =>
            {
                Pawn actor = toil.actor;
                if (actor.skills != null)
                {
                    actor.skills.Learn(SkillDefOf.Growing, 0.154f);
                }
                float statValue = actor.GetStatValue(StatDefOf.PlantWorkSpeed, true);
                Plant plant = (Plant)actor.jobs.curJob.GetTarget(TargetIndex.A).Thing;
                harvestWorkDone += statValue;
                if (harvestWorkDone >= plant.def.plant.harvestWork)
                {
                    if (plant.def.plant.harvestedThingDef != null)
                    {
                        int num3 = plant.YieldNow();
                        if (plant is PlantWithSeeds)
                        {
                            Log.Message("We harvest a PlantWithSeeds");
                            num3 = ((PlantWithSeeds)plant).YieldNow();
                        }
                        if (num3 > 0)
                        {

                            Thing thing = ThingMaker.MakeThing(plant.def.plant.harvestedThingDef, null);
                            thing.stackCount = num3;
                            if (actor.Faction != Faction.OfColony)
                            {
                                thing.SetForbidden(true, true);
                            }
                            GenPlace.TryPlaceThing(thing, actor.Position, ThingPlaceMode.Near);
                        }
                    }
                    plant.PlantCollected();
                    plant.def.plant.soundHarvestFinish.PlayOneShot(actor);
                    harvestWorkDone = 0;
                    ReadyForNextToil();
                }
            };
            toil.FailOnDestroyedOrForbidden(TargetIndex.A);
            toil.defaultCompleteMode = ToilCompleteMode.Never;
            toil.WithEffect("Harvest", TargetIndex.A);
            toil.WithSustainer(() => toil.actor.jobs.curJob.GetTarget(TargetIndex.A).Thing.def.plant.soundHarvesting);
            yield return toil;
            yield return Toils_General.RemoveDesignationsOnThing(TargetIndex.A, DesignationDefOf.HarvestPlant);
        }
        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;
        }
예제 #36
0
        protected override IEnumerable<Toil> MakeNewToils()
        {
            yield return Toils_Reserve.Reserve( TargetIndex.A ).FailOnDespawnedNullOrForbidden( TargetIndex.A );
            yield return Toils_Goto.GotoThing( TargetIndex.A, PathEndMode.Touch ).FailOnDespawnedNullOrForbidden( TargetIndex.A );

            Toil maintenance = new Toil();
            maintenance.tickAction = delegate
            {
                var pawn = maintenance.actor;
                durability += pawn.GetStatValue( StatDefOf.ConstructionSpeed ) / fullRepairTicks;

                if ( durability > .99f )
                    EndJobWith( JobCondition.Succeeded );
            };
            maintenance.WithEffect( TargetThingA.def.repairEffect, TargetIndex.A );
            maintenance.defaultCompleteMode = ToilCompleteMode.Never;
            yield return maintenance;
        }
예제 #37
0
        protected override IEnumerable<Toil> MakeNewToils()
        {
            this.FailOnDestroyed<JobDriver_AnimalEatCorpse>(TargetIndex.A);
            this.FailOnDespawnedIfNonNull<JobDriver_AnimalEatCorpse>(TargetIndex.A);
            this.FailOn<JobDriver_AnimalEatCorpse>(eaterIsKilled);
            Toil resCorpse = new Toil();
            resCorpse.initAction = new Action(() =>
            {
                Pawn actor = resCorpse.actor;
                Thing target = resCorpse.actor.CurJob.GetTarget(TargetIndex.A).Thing;
                if (!target.SpawnedInWorld || !Find.Reservations.CanReserve(actor, target, 1))
                {
                    actor.jobs.EndCurrentJob(JobCondition.Incompletable);
                }
                else
                {
                    Find.Reservations.Reserve(actor, target, 1);
                }
            });
            resCorpse.defaultCompleteMode = ToilCompleteMode.Instant;
            yield return resCorpse;

            yield return Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch);
            yield return Toils_General.Wait(60);

            Toil stripCorpse = new Toil
            {
                defaultCompleteMode = ToilCompleteMode.Instant
            };
            stripCorpse.initAction = new Action(doStripCorpse);
            yield return stripCorpse;
            yield return Toils_General.Wait(60);

            Toil chewCorpse = new Toil
            {
                defaultCompleteMode = ToilCompleteMode.Instant
            };
            chewCorpse.initAction = new Action(doChewCorpse);
            chewCorpse.WithEffect(EffecterDef.Named("EatMeat"), TargetIndex.A);
            chewCorpse.EndOnDespawned(TargetIndex.A);
            yield return chewCorpse;
        }
        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;
        }
 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;
 }
예제 #40
0
        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;
        }
예제 #41
0
        // added support for fuel burners
        public static Toil DoRecipeWork()
        {
            // research injection. initialized here to check if research project wan't change during work
            var startedResearch = Find.ResearchManager.currentProj;

            var toil = new Toil();
            toil.initAction = () =>
            {
                var actor = toil.actor;
                var curJob = actor.jobs.curJob;
                var curDriver = actor.jobs.curDriver as JobDriver_DoBill;

                var unfinishedThing = curJob.GetTarget(TargetIndex.B).Thing as UnfinishedThing;
                if (unfinishedThing != null && unfinishedThing.Initialized)
                {
                    curDriver.workLeft = unfinishedThing.workLeft;
                }
                else
                {
                    // research injection
                    var researchComp =
                        toil.actor.jobs.curJob.GetTarget(TargetIndex.A).Thing.TryGetComp<CompResearcher>();
                    if (researchComp != null)
                    {
                        curDriver.workLeft = startedResearch.CostApparent -
                                             startedResearch.ProgressApparent;
                    }
                    else
                    {
                        curDriver.workLeft = curJob.bill.recipe.WorkAmountTotal(unfinishedThing?.Stuff);
                    }

                    if (unfinishedThing != null)
                    {
                        unfinishedThing.workLeft = curDriver.workLeft;
                    }
                }
                curDriver.billStartTick = Find.TickManager.TicksGame;
                curJob.bill.Notify_DoBillStarted();
            };
            toil.tickAction = () =>
            {
                var actor = toil.actor;
                var curJob = actor.jobs.curJob;

                actor.GainComfortFromCellIfPossible();

                // burner support injection
                var burner = curJob.GetTarget(TargetIndex.A).Thing.TryGetComp<CompFueled>();
                if (burner != null && burner.internalTemp < burner.compFueled.Properties.operatingTemp)
                {
                    return;
                }

                var unfinishedThing = curJob.GetTarget(TargetIndex.B).Thing as UnfinishedThing;
                if (unfinishedThing != null && unfinishedThing.Destroyed)
                {
                    actor.jobs.EndCurrentJob(JobCondition.Incompletable);
                    return;
                }

                curJob.bill.Notify_PawnDidWork(actor);

                var billGiverWithTickAction =
                    curJob.GetTarget(TargetIndex.A).Thing as IBillGiverWithTickAction;
                billGiverWithTickAction?.BillTick();

                if (curJob.RecipeDef.workSkill != null)
                {
                    actor.skills.GetSkill(curJob.RecipeDef.workSkill)
                        .Learn(LearnRates.XpPerTickRecipeBase*curJob.RecipeDef.workSkillLearnFactor);
                }

                var workProgress = (curJob.RecipeDef.workSpeedStat != null)
                    ? actor.GetStatValue(curJob.RecipeDef.workSpeedStat)
                    : 1f;

                var curDriver = actor.jobs.curDriver as JobDriver_DoBill;
                var building_WorkTable = curDriver.BillGiver as Building_WorkTable;
                var researchComp = curJob.GetTarget(TargetIndex.A).Thing.TryGetComp<CompResearcher>();
                if (building_WorkTable != null)
                {
                    // research injection
                    workProgress *= researchComp == null
                        ? building_WorkTable.GetStatValue(StatDefOf.WorkTableWorkSpeedFactor)
                        : building_WorkTable.GetStatValue(StatDefOf.ResearchSpeedFactor);
                }

                if (DebugSettings.fastCrafting)
                {
                    workProgress *= 30f;
                }

                curDriver.workLeft -= workProgress;
                if (unfinishedThing != null)
                {
                    unfinishedThing.workLeft = curDriver.workLeft;
                }

                // research injection
                if (researchComp != null)
                {
                    if (Find.ResearchManager.currentProj != null && Find.ResearchManager.currentProj == startedResearch)
                    {
                        Find.ResearchManager.ResearchPerformed(workProgress, actor);
                    }
                    if (Find.ResearchManager.currentProj != startedResearch)
                    {
                        actor.jobs.EndCurrentJob(JobCondition.Succeeded);
                        // scatter around all ingridients
                        foreach (var cell in building_WorkTable.IngredientStackCells)
                        {
                            var ingridientsOnCell =
                                Find.ThingGrid.ThingsListAtFast(cell)?
                                    .Where(thing => thing.def.category == ThingCategory.Item)
                                    .ToList();
                            if (!ingridientsOnCell.NullOrEmpty())
                            {
                                Thing dummy;
                                // despawn thing to spawn again with TryPlaceThing
                                ingridientsOnCell.FirstOrDefault().DeSpawn();
                                if (
                                    !GenPlace.TryPlaceThing(ingridientsOnCell.FirstOrDefault(),
                                        building_WorkTable.InteractionCell,
                                        ThingPlaceMode.Near, out dummy))
                                {
                                    Log.Error("No free spot for " + ingridientsOnCell);
                                }
                            }
                        }
                    }
                }
                else if (curDriver.workLeft <= 0f)
                {
                    curDriver.ReadyForNextToil();
                }

                if (curJob.bill.recipe.UsesUnfinishedThing)
                {
                    var num2 = Find.TickManager.TicksGame - curDriver.billStartTick;
                    if (num2 >= 3000 && num2%1000 == 0)
                    {
                        actor.jobs.CheckForJobOverride();
                    }
                }
            };
            toil.defaultCompleteMode = ToilCompleteMode.Never;
            toil.WithEffect(() => toil.actor.CurJob.bill.recipe.effectWorking, TargetIndex.A);
            toil.PlaySustainerOrSound(() => toil.actor.CurJob.bill.recipe.soundWorking);
            toil.WithProgressBar(TargetIndex.A, () =>
            {
                var actor = toil.actor;
                var curJob = actor.CurJob;
                var unfinishedThing = curJob.GetTarget(TargetIndex.B).Thing as UnfinishedThing;
                var researchComp = curJob.GetTarget(TargetIndex.A).Thing.TryGetComp<CompResearcher>();
                // research injection
                return researchComp == null
                    ? 1f - ((JobDriver_DoBill) actor.jobs.curDriver).workLeft/
                      curJob.bill.recipe.WorkAmountTotal(unfinishedThing?.Stuff)
                    : startedResearch.ProgressPercent;
            });
            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;
        }
        public Toil CollectClay(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")));
                totalWork = pawn.jobs.curDriver.ticksLeftThisToil;
            };
            toil.tickAction = () =>
            {
                if (--pawn.jobs.curDriver.ticksLeftThisToil < 0)
                {
                    // remove designation
                    var designation = Find.DesignationManager.DesignationAt(targetCell,
                        DefDatabase<DesignationDef>.GetNamed("CollectClay"));
                    if (designation != null)
                    {
                        Find.DesignationManager.RemoveDesignation(designation);
                    }

                    // replace terrain
                    if (Find.TerrainGrid.TerrainAt(targetCell) == TerrainDef.Named("Mud"))
                        Find.TerrainGrid.SetTerrain(targetCell, DefDatabase<TerrainDef>.GetNamed("Soil"));
                    if (Find.TerrainGrid.TerrainAt(targetCell) == TerrainDef.Named("SoilRich"))
                        Find.TerrainGrid.SetTerrain(targetCell, DefDatabase<TerrainDef>.GetNamed("Soil"));
                    if (Find.TerrainGrid.TerrainAt(targetCell) == TerrainDef.Named("WaterShallow"))
                    {
                        Find.TerrainGrid.SetTerrain(targetCell, DefDatabase<TerrainDef>.GetNamed("WaterDeep"));

                        var list = new List<Thing>(Find.ThingGrid.ThingsListAtFast(targetCell)
                            .Where(thing => thing.def.category == ThingCategory.Item ||
                                            thing.def.category == ThingCategory.Pawn));
                        foreach (var thing in list)
                        {
                            Thing dummy;
                            // despawn thing to spawn again with TryPlaceThing
                            thing.DeSpawn();
                            if (!GenPlace.TryPlaceThing(thing, thing.Position, ThingPlaceMode.Near, out dummy))
                            {
                                Log.Error("No free spot for " + thing);
                            }
                        }
                    }

                    // spawn resources
                    var clayRed = ThingMaker.MakeThing(ThingDef.Named("ClumpClayGray"));
                    clayRed.stackCount = Rand.RangeInclusive(25, 75);
                    GenPlace.TryPlaceThing(clayRed, targetCell, ThingPlaceMode.Near);

                    // Rand.Value = Rand.Range(0, 1)
                    if (Rand.Value < RareResourceSpawnChance)
                    {
                        var clayWhite = ThingMaker.MakeThing(ThingDef.Named("ClumpClayWhite"));
                        clayWhite.stackCount = Rand.RangeInclusive(5, 10);
                        GenPlace.TryPlaceThing(clayWhite, targetCell, ThingPlaceMode.Near);
                    }

                    ReadyForNextToil();
                }
            };
            toil.defaultCompleteMode = ToilCompleteMode.Never;
            toil.FailOnCellMissingDesignation(CellInd, DefDatabase<DesignationDef>.GetNamed("CollectClay"));
            toil.WithEffect(() => EffecterDef.Named("CutStone"), CellInd);
            toil.PlaySustainerOrSound(() => DefDatabase<SoundDef>.GetNamedSilentFail("Recipe_Surgery"));
            toil.WithProgressBar(CellInd, () => 1f - (float) pawn.jobs.curDriver.ticksLeftThisToil/totalWork);
            return toil;
        }
 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;
 }