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;
        }
        protected override IEnumerable <Toil> MakeNewToils()
        {
            Toil initExtractTargetFromQueue = Toils_JobTransforms.ClearDespawnedNullOrForbiddenQueuedTargets(TargetIndex.A, null);

            yield return(initExtractTargetFromQueue);

            yield return(Toils_JobTransforms.SucceedOnNoTargetInQueue(TargetIndex.A));

            yield return(Toils_JobTransforms.ExtractNextTargetFromQueue(TargetIndex.A, true));

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

            Toil clean = new Toil();

            clean.initAction = delegate
            {
                this.$this.cleaningWorkDone          = 0f;
                this.$this.totalCleaningWorkDone     = 0f;
                this.$this.totalCleaningWorkRequired = this.$this.Filth.def.filth.cleaningWorkToReduceThickness * (float)this.$this.Filth.thickness;
            };
            clean.tickAction = delegate
            {
                Filth filth = this.$this.Filth;
                this.$this.cleaningWorkDone      += 1f;
                this.$this.totalCleaningWorkDone += 1f;
                if (this.$this.cleaningWorkDone > filth.def.filth.cleaningWorkToReduceThickness)
                {
                    filth.ThinFilth();
                    this.$this.cleaningWorkDone = 0f;
                    if (filth.Destroyed)
                    {
                        clean.actor.records.Increment(RecordDefOf.MessesCleaned);
                        this.$this.ReadyForNextToil();
                        return;
                    }
                }
            };
            clean.defaultCompleteMode = ToilCompleteMode.Never;
            clean.WithEffect(EffecterDefOf.Clean, TargetIndex.A);
            clean.WithProgressBar(TargetIndex.A, () => this.$this.totalCleaningWorkDone / this.$this.totalCleaningWorkRequired, true, -0.5f);
            clean.PlaySustainerOrSound(() => SoundDefOf.Interact_CleanFilth);
            clean.JumpIfDespawnedOrNullOrForbidden(TargetIndex.A, initExtractTargetFromQueue);
            clean.JumpIfOutsideHomeArea(TargetIndex.A, initExtractTargetFromQueue);
            yield return(clean);

            yield return(Toils_Jump.Jump(initExtractTargetFromQueue));
        }
Exemple #3
0
 public static Toil AddIngestionEffects(Toil toil, Pawn chewer, TargetIndex ingestibleInd, TargetIndex eatSurfaceInd)
 {
     toil.WithEffect(delegate
     {
         LocalTargetInfo target = toil.actor.CurJob.GetTarget(ingestibleInd);
         if (!target.HasThing)
         {
             return(null);
         }
         EffecterDef result = target.Thing.def.ingestible.ingestEffect;
         if (chewer.RaceProps.intelligence < Intelligence.ToolUser && target.Thing.def.ingestible.ingestEffectEat != null)
         {
             result = target.Thing.def.ingestible.ingestEffectEat;
         }
         return(result);
     }, delegate
     {
         if (!toil.actor.CurJob.GetTarget(ingestibleInd).HasThing)
         {
             return(null);
         }
         Thing thing = toil.actor.CurJob.GetTarget(ingestibleInd).Thing;
         if (chewer != toil.actor)
         {
             return(chewer);
         }
         if (eatSurfaceInd != TargetIndex.None && toil.actor.CurJob.GetTarget(eatSurfaceInd).IsValid)
         {
             return(toil.actor.CurJob.GetTarget(eatSurfaceInd));
         }
         return(thing);
     });
     toil.PlaySustainerOrSound(delegate
     {
         if (!chewer.RaceProps.Humanlike)
         {
             return(null);
         }
         LocalTargetInfo target = toil.actor.CurJob.GetTarget(ingestibleInd);
         if (!target.HasThing)
         {
             return(null);
         }
         return(target.Thing.def.ingestible.ingestSound);
     });
     return(toil);
 }
Exemple #4
0
        // 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));

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

            Toil carryToCell = Toils_Haul.CarryHauledThingToCell(TargetIndex.B);

            yield return(carryToCell);

            yield return(new Toil
            {
                initAction = delegate()
                {
                    if (this.pawn.Position.OnEdge(this.pawn.Map) || this.pawn.Map.exitMapGrid.IsExitCell(this.pawn.Position))
                    {
                        this.pawn.ExitMap(true, CellRect.WholeMap(base.Map).GetClosestEdge(this.pawn.Position));
                    }
                },
                defaultCompleteMode = ToilCompleteMode.Instant
            });

            yield return(Toils_Haul.PlaceHauledThingInCell(TargetIndex.B, carryToCell, false));

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

            prepare.NPCWithProgressBarToilDelay(TargetIndex.A, false, -0.5f);
            prepare.FailOnDespawnedNullOrForbidden(TargetIndex.A);
            //    prepare.FailOnCannotTouch(TargetIndex.A, PathEndMode.InteractionCell);
            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;
        }
Exemple #5
0
        public static Toil makeCleanToil(TargetIndex progListIndex, TargetIndex filthListIndex, Toil nextTarget)
        {
            Toil toil = new Toil();

            toil.initAction = delegate()
            {
                Filth filth   = toil.actor.jobs.curJob.GetTarget(filthListIndex).Thing as Filth;
                var   progQue = toil.actor.jobs.curJob.GetTargetQueue(progListIndex);
                progQue[0] = new IntVec3(0, 0, (int)filth.def.filth.cleaningWorkToReduceThickness * filth.thickness);
            };
            toil.tickAction = delegate()
            {
                Filth   filth   = toil.actor.jobs.curJob.GetTarget(filthListIndex).Thing as Filth;
                var     progQue = toil.actor.jobs.curJob.GetTargetQueue(progListIndex);
                IntVec3 iv      = progQue[0].Cell;
                iv.x += 1;
                iv.y += 1;
                if (iv.x > filth.def.filth.cleaningWorkToReduceThickness)
                {
                    filth.ThinFilth();
                    iv.x = 0;
                    if (filth.Destroyed)
                    {
                        toil.actor.records.Increment(RecordDefOf.MessesCleaned);
                        toil.actor.jobs.curDriver.ReadyForNextToil();
                        return;
                    }
                }
                progQue[0] = iv;
            };
            toil.defaultCompleteMode = ToilCompleteMode.Never;
            toil.WithEffect(EffecterDefOf.Clean, filthListIndex);
            toil.WithProgressBar(filthListIndex,
                                 delegate()
            {
                var q        = toil.actor.CurJob.GetTargetQueue(progListIndex)[0];
                float result = (float)q.Cell.y / q.Cell.z;
                return(result);
            }
                                 , true, -0.5f);
            toil.PlaySustainerOrSound(() => SoundDefOf.Interact_CleanFilth);
            toil.JumpIfDespawnedOrNullOrForbidden(filthListIndex, nextTarget);
            toil.JumpIfOutsideHomeArea(filthListIndex, nextTarget);
            toil.FailOnDestroyedOrNull(TargetIndex.A);
            return(toil);
        }
        protected override IEnumerable <Toil> MakeNewToils()
        {
            this.EndOnDespawnedOrNull(TargetIndex.A);
            yield return(Toils_Reserve.Reserve(TargetIndex.A, job.def.joyMaxParticipants));

            if (TargetB != null)
            {
                yield return(Toils_Reserve.Reserve(TargetIndex.B));
            }

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

            var toil = new Toil();

            toil.PlaySustainerOrSound(DefDatabase <SoundDef> .GetNamed("Estate_SoundManualTypewriter"));
            toil.tickAction = delegate
            {
                pawn.rotationTracker.FaceCell(TargetA.Cell);
                pawn.GainComfortFromCellIfPossible();
                var statValue = TargetThingA.GetStatValue(StatDefOf.JoyGainFactor);
                JoyUtility.JoyTickCheckEnd(pawn, JoyTickFullJoyAction.EndJob, statValue);
            };
            toil.defaultCompleteMode = ToilCompleteMode.Delay;
            toil.defaultDuration     = job.def.joyDuration;
//            toil.AddFinishAction(delegate
//            {
//                if (Cthulhu.Utility.IsCosmicHorrorsLoaded())
//                {
//                    try
//                    {
//                        if (Cthulhu.Utility.HasSanityLoss(this.pawn))
//                        {
//                            Cthulhu.Utility.ApplySanityLoss(this.pawn, -sanityRestoreRate, 1);
//                            Messages.Message(this.pawn.ToString() + " has restored some sanity using the " + this.TargetA.Thing.def.label + ".", new TargetInfo(this.pawn.Position, this.pawn.Map), MessageTypeDefOf.NeutralEvent);// .Standard);
//                        }
//                    }
//                    catch
//                    {
//                        Log.Message("Error loading Sanity Hediff.");
//                    }
//                }
//
//                JoyUtility.TryGainRecRoomThought(this.pawn);
//            });
            yield return(toil);
        }
        protected override IEnumerable <Toil> MakeNewToils()
        {
            Toil toil = new Toil();

            toil.initAction = delegate
            {
                ticksLeft = Rand.Range(300, 900);
                int     num = 0;
                IntVec3 c;
                do
                {
                    c = pawn.Position + GenAdj.AdjacentCellsAndInside[Rand.Range(0, 9)];
                    num++;
                    if (num > 12)
                    {
                        c = pawn.Position;
                        break;
                    }
                }while (!c.InBounds(pawn.Map) || !c.Standable(pawn.Map));
                job.targetA = c;
                pawn.pather.StopDead();
            };
            toil.tickAction = delegate
            {
                if (ticksLeft % 150 == 149)
                {
                    FilthMaker.TryMakeFilth(job.targetA.Cell, base.Map, CultsDefOf.Cults_Filth_BileVomit, pawn.LabelIndefinite());
                    if (pawn.needs.food.CurLevelPercentage > 0.1f)                     // TODO: do other harm?
                    {
                        pawn.needs.food.CurLevel -= pawn.needs.food.MaxLevel * 0.04f;
                    }
                }
                ticksLeft--;
                if (ticksLeft <= 0)
                {
                    ReadyForNextToil();
                    TaleRecorder.RecordTale(TaleDefOf.Vomited, pawn);
                }
            };
            toil.defaultCompleteMode = ToilCompleteMode.Never;
            toil.WithEffect(CultsDefOf.Cults_Effecter_VomitBile, TargetIndex.A);
            toil.PlaySustainerOrSound(() => SoundDefOf.Vomit);
            yield return(toil);
        }
 public static Toil AddChewEffects(Toil toil, Pawn chewer, TargetIndex ind)
 {
     toil.WithEffect(delegate
     {
         Pawn actor  = toil.actor;
         Thing thing = actor.CurJob.GetTarget(ind).Thing;
         EffecterDef result;
         if (thing.def.ingestible != null)
         {
             result = thing.def.ingestible.ingestEffect;
         }
         else
         {
             result = DefDatabase <EffecterDef> .GetNamed("EatVegetarian", true);
         }
         return(result);
     }, delegate
     {
         if (!toil.actor.CurJob.GetTarget(ind).HasThing)
         {
             return(null);
         }
         Thing thing = toil.actor.CurJob.GetTarget(ind).Thing;
         if (chewer != toil.actor)
         {
             return(chewer);
         }
         return(thing);
     });
     toil.PlaySustainerOrSound(delegate
     {
         LocalTargetInfo target = toil.actor.CurJob.GetTarget(ind);
         if (!target.HasThing)
         {
             return(null);
         }
         SoundDef result = DefDatabase <SoundDef> .GetNamed("RawMeat_Eat", true);
         return(result);
     });
     return(toil);
 }
Exemple #9
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            this.FailOnDestroyedOrNull(TargetIndex.A);
            this.SetCompleteMode(ToilCompleteMode.Never);
            yield return(Toils_Reserve.Reserve(TargetIndex.A, 1));

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

            Toil      toil        = new Toil();
            Texture2D deitySymbol = ((CosmicEntityDef)DropAltar.currentOfferingDeity.def).Symbol;

            toil.PlaySustainerOrSound(CultDefOfs.RitualChanting);
            toil.initAction = delegate
            {
                this.workLeft = 2300f;
                if (deitySymbol != null)
                {
                    MoteMaker.MakeInteractionMote(this.pawn, null, ThingDefOf.Mote_Speech, deitySymbol);
                }
            };
            toil.tickAction = delegate
            {
                this.workLeft -= 1;
                if (this.workLeft <= 0f)
                {
                    //Thing thing = ThingMaker.MakeThing(ThingDefOf.Snowman, null);
                    //thing.SetFaction(this.<> f__this.pawn.Faction, null);
                    //GenSpawn.Spawn(thing, this.<> f__this.TargetLocA);
                    this.ReadyForNextToil();
                    return;
                }
                JoyUtility.JoyTickCheckEnd(this.pawn, JoyTickFullJoyAction.EndJob, 1f);
            };
            toil.WithProgressBar(TargetIndex.A, () => this.workLeft / this.BaseWorkAmount, true, -0.5f);
            toil.defaultCompleteMode = ToilCompleteMode.Never;
            //toil.FailOn(() => !JoyUtility.EnjoyableOutsideNow(this.<> f__this.pawn, null));
            yield return(toil);

            yield break;
        }
Exemple #10
0
 public static Toil AddIngestionEffects(Toil toil, Pawn chewer, TargetIndex ingestibleInd, TargetIndex eatSurfaceInd)
 {
     toil.WithEffect(delegate
     {
         LocalTargetInfo target2 = toil.actor.CurJob.GetTarget(ingestibleInd);
         if (!target2.HasThing)
         {
             return(null);
         }
         EffecterDef result = target2.Thing.GetIngestibleProperties().ingestEffect;
         if ((int)chewer.RaceProps.intelligence < 1 && target2.Thing.GetIngestibleProperties().ingestEffectEat != null)
         {
             result = target2.Thing.GetIngestibleProperties().ingestEffectEat;
         }
         return(result);
     }, delegate
     {
         if (!toil.actor.CurJob.GetTarget(ingestibleInd).HasThing)
         {
             return(null);
         }
         Thing thing = toil.actor.CurJob.GetTarget(ingestibleInd).Thing;
         if (chewer != toil.actor)
         {
             return(chewer);
         }
         return((eatSurfaceInd != 0 && toil.actor.CurJob.GetTarget(eatSurfaceInd).IsValid) ? toil.actor.CurJob.GetTarget(eatSurfaceInd) : ((LocalTargetInfo)thing));
     });
     toil.PlaySustainerOrSound(delegate
     {
         if (!chewer.RaceProps.Humanlike)
         {
             return(null);
         }
         LocalTargetInfo target = toil.actor.CurJob.GetTarget(ingestibleInd);
         return((!target.HasThing) ? null : target.Thing.GetIngestibleProperties().ingestSound);
     });
     return(toil);
 }
        protected override IEnumerable <Toil> MakeNewToils()
        {
            this.FailOnForbidden(TargetIndex.A);
            yield return(Toils_Goto.GotoCell(TargetIndex.A, PathEndMode.Touch));

            Toil doWork = new Toil();

            doWork.defaultCompleteMode = ToilCompleteMode.Never;
            doWork.FailOn(() => !JoyUtility.EnjoyableOutsideNow(this.pawn, null));
            doWork.FailOnCannotTouch(TargetIndex.A, PathEndMode.Touch);
            doWork.PlaySustainerOrSound(SoundDefOf.Interact_CleanFilth);
            doWork.initAction = () =>
            {
                this.workLeft = 600f;
            };

            doWork.tickAction = () =>
            {
                if (pawn.IsHashIntervalTick(50))
                {
                    pawn.skills.Learn(SkillDefOf.Artistic, 0.5f);
                }

                this.workLeft -= doWork.actor.GetStatValue(StatDefOf.WorkSpeedGlobal, true);
                if (this.workLeft <= 0f)
                {
                    Thing thing        = ThingMaker.MakeThing(DSFIThingDefOf.DSFI_Scribbling, null);
                    Thing spawnedThing = GenSpawn.Spawn(thing, this.TargetLocA, this.Map, WipeMode.Vanish);
                    spawnedThing.Rotation = Rot4.Random;

                    this.ReadyForNextToil();
                    return;
                }
            };

            yield return(doWork);

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

            Toil clearToil = new Toil();

            clearToil.tickAction = delegate
            {
                float statValue = clearToil.actor.GetStatValue(StatDefOf.GeneralLaborSpeed);
                workDone += statValue;
                if (workDone >= TotalNeededWork)
                {
                    base.Map.snowGrid.SetDepth(base.TargetLocA, 0f);
                    ReadyForNextToil();
                }
            };
            clearToil.defaultCompleteMode = ToilCompleteMode.Never;
            clearToil.WithEffect(EffecterDefOf.ClearSnow, TargetIndex.A);
            clearToil.PlaySustainerOrSound(() => SoundDefOf.Interact_CleanFilth);
            clearToil.WithProgressBar(TargetIndex.A, () => workDone / TotalNeededWork, interpolateBetweenActorAndTarget: true);
            clearToil.FailOnCannotTouch(TargetIndex.A, PathEndMode.Touch);
            yield return(clearToil);
        }
Exemple #13
0
        public static Toil DrinkTerrain(TargetIndex cellIndex, int baseDrinkTicksFromTerrain)
        {
            // 地形から水を飲む
            int initialTicks = 1;

            Toil toil = new Toil();

            toil.initAction = delegate
            {
                var actor      = toil.actor;
                var cell       = actor.CurJob.GetTarget(cellIndex).Cell;
                var need_water = actor.needs.water();
                if (need_water == null)
                {
                    actor.jobs.EndCurrentJob(JobCondition.Incompletable);
                    return;
                }

                var waterType = cell.GetTerrain(actor.Map).ToWaterType();
                if (waterType == WaterType.NoWater || waterType == WaterType.Undefined)
                {
                    actor.jobs.EndCurrentJob(JobCondition.Incompletable);
                    return;
                }

                var waterTypeDef = MizuDef.Dic_WaterTypeDef[waterType];

                // 向き変更
                actor.rotationTracker.FaceCell(actor.Position);

                // 作業量
                actor.jobs.curDriver.ticksLeftThisToil = (int)(baseDrinkTicksFromTerrain * need_water.WaterWanted);
                initialTicks = actor.jobs.curDriver.ticksLeftThisToil;

                if (actor.needs.mood != null)
                {
                    // 水分摂取による心情変化
                    List <ThoughtDef> thoughtList = new List <ThoughtDef>();
                    MizuUtility.ThoughtsFromWaterTypeDef(actor, waterTypeDef, true, thoughtList);
                    foreach (var thoughtDef in thoughtList)
                    {
                        actor.needs.mood.thoughts.memories.TryGainMemory(thoughtDef);
                    }
                }

                // 指定された健康状態になる
                if (waterTypeDef.hediffs != null)
                {
                    foreach (var hediff in waterTypeDef.hediffs)
                    {
                        actor.health.AddHediff(HediffMaker.MakeHediff(hediff, actor));
                    }
                }
                // 確率で食中毒
                if (Rand.Value < waterTypeDef.foodPoisonChance)
                {
                    actor.health.AddHediff(HediffMaker.MakeHediff(HediffDefOf.FoodPoisoning, actor));
                    if (PawnUtility.ShouldSendNotificationAbout(actor))
                    {
                        var    water = ThingMaker.MakeThing(MizuUtility.GetWaterThingDefFromWaterType(waterType));
                        string cause = "MizuPoisonedByDirtyWater".Translate().CapitalizeFirst();
                        string text  = "MessageFoodPoisoning".Translate(actor.LabelShort, water.ToString(), cause, actor.Named("PAWN"), water.Named("FOOD")).CapitalizeFirst();
                        Messages.Message(text, actor, MessageTypeDefOf.NegativeEvent);
                    }
                }
            };
            toil.tickAction = delegate
            {
                toil.actor.GainComfortFromCellIfPossible();
                var need_water = toil.actor.needs.water();
                var cell       = toil.actor.CurJob.GetTarget(cellIndex).Cell;
                if (need_water == null)
                {
                    toil.actor.jobs.EndCurrentJob(JobCondition.Incompletable);
                    return;
                }

                // 徐々に飲む
                float riseNeedWater = 1 / (float)baseDrinkTicksFromTerrain;
                need_water.CurLevel = Mathf.Min(need_water.CurLevel + riseNeedWater, need_water.MaxLevel);
            };
            toil.WithProgressBar(cellIndex, delegate
            {
                return(1f - (float)toil.actor.jobs.curDriver.ticksLeftThisToil / initialTicks);
            }, false, -0.5f);
            toil.defaultCompleteMode = ToilCompleteMode.Delay;
            toil.FailOn((t) =>
            {
                Pawn actor = toil.actor;
                return(actor.CurJob.targetA.Cell.IsForbidden(actor) || !actor.CanReach(actor.CurJob.targetA.Cell, PathEndMode.OnCell, Danger.Deadly));
            });

            // エフェクト追加
            toil.PlaySustainerOrSound(delegate
            {
                return(DefDatabase <SoundDef> .GetNamed("Ingest_Beer"));
            });
            return(toil);
        }
Exemple #14
0
        public static Toil DrinkFromBuilding(TargetIndex buildingIndex)
        {
            int initialTicks = 1;

            Toil toil = new Toil();

            toil.initAction = delegate
            {
                var actor    = toil.actor;
                var thing    = actor.CurJob.GetTarget(buildingIndex).Thing;
                var comp     = thing.TryGetComp <CompWaterSource>();
                var building = thing as IBuilding_DrinkWater;

                if (actor.needs == null || actor.needs.water() == null || building == null || comp == null || !comp.IsWaterSource)
                {
                    actor.jobs.EndCurrentJob(JobCondition.Incompletable);
                    return;
                }

                var need_water   = actor.needs.water();
                var waterTypeDef = MizuDef.Dic_WaterTypeDef[comp.WaterType];

                // 向きを変更
                actor.rotationTracker.FaceCell(actor.Position);

                // 作業量
                actor.jobs.curDriver.ticksLeftThisToil = (int)(comp.BaseDrinkTicks * need_water.WaterWanted);
                initialTicks = actor.jobs.curDriver.ticksLeftThisToil;

                if (actor.needs.mood != null)
                {
                    // 水分摂取による心情変化
                    foreach (var thoughtDef in MizuUtility.ThoughtsFromGettingWater(actor, thing))
                    {
                        actor.needs.mood.thoughts.memories.TryGainMemory(thoughtDef);
                    }
                }

                // 指定された健康状態になる
                if (waterTypeDef.hediffs != null)
                {
                    foreach (var hediff in waterTypeDef.hediffs)
                    {
                        actor.health.AddHediff(HediffMaker.MakeHediff(hediff, actor));
                    }
                }
                // 確率で食中毒
                if (Rand.Value < waterTypeDef.foodPoisonChance)
                {
                    FoodUtility.AddFoodPoisoningHediff(actor, thing, FoodPoisonCause.Unknown);
                }
            };
            toil.tickAction = delegate
            {
                toil.actor.GainComfortFromCellIfPossible();
                var need_water = toil.actor.needs.water();
                var thing      = toil.actor.CurJob.GetTarget(buildingIndex).Thing;
                var comp       = thing.TryGetComp <CompWaterSource>();
                var building   = thing as IBuilding_DrinkWater;
                if (thing == null || comp == null || !comp.IsWaterSource || building == null || building.IsEmpty)
                {
                    toil.actor.jobs.EndCurrentJob(JobCondition.Incompletable);
                    return;
                }

                // 徐々に飲む
                float riseNeedWater = 1 / (float)comp.BaseDrinkTicks;
                need_water.CurLevel = Mathf.Min(need_water.CurLevel + riseNeedWater, need_water.MaxLevel);
                building.DrawWater(riseNeedWater * Need_Water.NeedWaterVolumePerDay);
            };
            toil.WithProgressBar(buildingIndex, delegate
            {
                return(1f - (float)toil.actor.jobs.curDriver.ticksLeftThisToil / initialTicks);
            }, false, -0.5f);
            toil.defaultCompleteMode = ToilCompleteMode.Delay;
            toil.FailOn((t) =>
            {
                Pawn actor = toil.actor;
                var target = actor.CurJob.GetTarget(buildingIndex);

                if (target.Thing.def.hasInteractionCell)
                {
                    // 使用場所があるなら使用場所基準
                    return(target.Thing.InteractionCell.IsForbidden(actor) || !actor.CanReach(target.Thing.InteractionCell, PathEndMode.OnCell, Danger.Deadly));
                }
                else
                {
                    // 使用場所がないなら設備の場所基準
                    return(target.Thing.Position.IsForbidden(actor) || !actor.CanReach(target.Thing.Position, PathEndMode.ClosestTouch, Danger.Deadly));
                }
            });

            // エフェクト追加
            toil.PlaySustainerOrSound(delegate
            {
                return(DefDatabase <SoundDef> .GetNamed("Ingest_Beer"));
            });
            return(toil);
        }
Exemple #15
0
        public static Toil DoRecipeWorkDrawing(TargetIndex billGiverIndex)
        {
            Toil toil = new Toil();

            toil.initAction = delegate
            {
                Pawn             actor            = toil.actor;
                Job              curJob           = actor.jobs.curJob;
                JobDriver_DoBill jobDriver_DoBill = (JobDriver_DoBill)actor.jobs.curDriver;

                jobDriver_DoBill.workLeft                  = curJob.bill.recipe.WorkAmountTotal(null);
                jobDriver_DoBill.billStartTick             = Find.TickManager.TicksGame;
                jobDriver_DoBill.ticksSpentDoingRecipeWork = 0;

                curJob.bill.Notify_DoBillStarted(actor);
            };
            toil.tickAction = delegate
            {
                Pawn             actor            = toil.actor;
                Job              curJob           = actor.jobs.curJob;
                JobDriver_DoBill jobDriver_DoBill = (JobDriver_DoBill)actor.jobs.curDriver;

                jobDriver_DoBill.ticksSpentDoingRecipeWork++;
                curJob.bill.Notify_PawnDidWork(actor);

                IBillGiverWithTickAction billGiverWithTickAction = actor.CurJob.GetTarget(billGiverIndex).Thing as IBillGiverWithTickAction;
                if (billGiverWithTickAction != null)
                {
                    // 設備の時間経過処理
                    billGiverWithTickAction.UsedThisTick();
                }

                // 工数を進める処理
                float num = (curJob.RecipeDef.workSpeedStat != null) ? actor.GetStatValue(curJob.RecipeDef.workSpeedStat, true) : 1f;
                Building_WorkTable building_WorkTable = jobDriver_DoBill.BillGiver as Building_WorkTable;
                if (building_WorkTable != null)
                {
                    num *= building_WorkTable.GetStatValue(StatDefOf.WorkTableWorkSpeedFactor, true);
                }
                if (DebugSettings.fastCrafting)
                {
                    num *= 30f;
                }
                jobDriver_DoBill.workLeft -= num;

                // 椅子から快適さを得る
                actor.GainComfortFromCellIfPossible();

                // 完了チェック
                if (jobDriver_DoBill.workLeft <= 0f)
                {
                    jobDriver_DoBill.ReadyForNextToil();
                }
            };
            toil.defaultCompleteMode = ToilCompleteMode.Never;
            toil.WithEffect(() => toil.actor.CurJob.bill.recipe.effectWorking, billGiverIndex);
            toil.PlaySustainerOrSound(() => toil.actor.CurJob.bill.recipe.soundWorking);
            toil.WithProgressBar(billGiverIndex, delegate
            {
                Pawn actor = toil.actor;
                Job curJob = actor.CurJob;
                return(1f - ((JobDriver_DoBill)actor.jobs.curDriver).workLeft / curJob.bill.recipe.WorkAmountTotal(null));
            }, false, -0.5f);
            toil.FailOn(() => toil.actor.CurJob.bill.suspended);
            return(toil);
        }
Exemple #16
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 #17
0
        protected override Toil DoBill()
        {
            var objectThing          = job.GetTarget(objectTI).Thing;
            var qualityComponent     = objectThing.TryGetComp <CompQuality> ();
            var tableThing           = job.GetTarget(tableTI).Thing as Building_WorkTable;
            var tablePowerTraderComp = tableThing.GetComp <CompPowerTrader> ();

            var toil = new Toil();

            toil.initAction = delegate {
                job.bill.Notify_DoBillStarted(pawn);

                processedHitPoints = 0;
                failChance         = ChanceDef.GetFor(objectThing);

                workCycleProgress = workCycle = Math.Max(job.bill.recipe.workAmount, 10f);
            };
            toil.tickAction = delegate {
                if (objectThing == null || objectThing.Destroyed)
                {
                    pawn.jobs.EndCurrentJob(JobCondition.Incompletable);
                }

                workCycleProgress -= StatExtension.GetStatValue(pawn, StatDefOf.WorkToMake, true);

                tableThing.UsedThisTick();
                if (!tableThing.UsableNow)
                {
                    pawn.jobs.EndCurrentJob(JobCondition.Incompletable);
                }

                if (workCycleProgress <= 0)
                {
                    objectThing.HitPoints -= fixedHitPointsPerCycle;

                    if (tablePowerTraderComp != null && tablePowerTraderComp.PowerOn)
                    {
                        processedHitPoints += fixedHitPointsPerCycle;
                    }
                    else
                    {
                        processedHitPoints += fixedHitPointsPerCycle / 2;
                    }

                    float skillPerc = 0.5f;

                    var skillDef = job.RecipeDef.workSkill;
                    if (skillDef != null)
                    {
                        var skill = pawn.skills.GetSkill(skillDef);

                        if (skill != null)
                        {
                            skillPerc = (float)skill.Level / 20f;

                            skill.Learn(0.11f * job.RecipeDef.workSkillLearnFactor);
                        }
                    }

                    if (qualityComponent != null && qualityComponent.Quality > QualityCategory.Awful)
                    {
                        var qc = qualityComponent.Quality;

                        float skillFactor = Mathf.Lerp(0.5f, 1.5f, skillPerc);

                        if (failChance != null && Rand.Value < failChance.Chance(qc) * skillFactor)
                        {
                            objectThing.HitPoints -= fixedFailedDamage;

                            MoteMaker.ThrowText(pawn.DrawPos, pawn.Map, "Failed");
                        }
                    }

                    pawn.GainComfortFromCellIfPossible();

                    if (objectThing.HitPoints <= 0)
                    {
                        pawn.Map.reservationManager.Release(job.targetB, pawn, job);
                        objectThing.Destroy(DestroyMode.Vanish);

                        float skillFactor  = Mathf.Lerp(0.5f, 1.5f, skillPerc);
                        float healthPerc   = (float)processedHitPoints / (float)objectThing.MaxHitPoints;
                        float healthFactor = Mathf.Lerp(0f, 0.4f, healthPerc);

                        var list = JobDriverUtils.Reclaim(objectThing, skillFactor * healthFactor);

                        if (list.Count > 1)
                        {
                            for (int j = 1; j < list.Count; j++)
                            {
                                if (!GenPlace.TryPlaceThing(list [j], pawn.Position, pawn.Map, ThingPlaceMode.Near, null))
                                {
                                    Log.Error("Mending :: " + pawn + " could not drop recipe product " + list [j] + " near " + pawn.Position);
                                }
                            }
                        }
                        else if (list.Count == 1)
                        {
                            list [0].SetPositionDirect(pawn.Position);

                            job.bill.Notify_IterationCompleted(pawn, list);
                            job.targetB = list [0];

                            pawn.Map.reservationManager.Reserve(pawn, job, job.targetB, 1);
                        }
                        else
                        {
                            Log.Message("Mending :: " + pawn + " could not reclaim anything from " + objectThing);
                        }

                        ReadyForNextToil();
                    }

                    workCycleProgress = workCycle;
                }
            };
            toil.defaultCompleteMode = ToilCompleteMode.Never;
            toil.WithEffect(() => job.bill.recipe.effectWorking, tableTI);
            toil.PlaySustainerOrSound(() => toil.actor.CurJob.bill.recipe.soundWorking);
            toil.WithProgressBar(tableTI, delegate {
                return((float)objectThing.HitPoints / (float)objectThing.MaxHitPoints);
            }, false, 0.5f);
            toil.FailOn(() => {
                return(toil.actor.CurJob.bill.suspended || !tableThing.UsableNow);
            });
            return(toil);
        }
Exemple #18
0
        static IEnumerable <Toil> prepToils(JobDriver_Ingest driver, Toil chewToil)
        {
            if ((bool)LeatingFromInventory.GetValue(driver))
            {
                yield return(Toils_Misc.TakeItemFromInventoryToCarrier(driver.pawn, TargetIndex.A));
            }
            else
            {
                yield return((Toil)LReserveFood.Invoke(driver, new object[] { }));

                Toil gotoToPickup = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(TargetIndex.A);
                yield return(Toils_Jump.JumpIf(gotoToPickup, () => driver.pawn.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation)));

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

                yield return(Toils_Jump.Jump(chewToil));

                yield return(gotoToPickup);

                yield return(Toils_Ingest.PickupIngestible(TargetIndex.A, driver.pawn));

                gotoToPickup = null;
            }
            if (driver.job.takeExtraIngestibles > 0)
            {
                foreach (Toil toil in (IEnumerable <Toil>)LTakeExtraIngestibles.Invoke(driver, new object[] { }))
                {
                    yield return(toil);
                }
            }
            if (!driver.pawn.Drafted)
            {
                yield return(reserveChewSpot(driver.pawn, TargetIndex.A, TargetIndex.B));

                Toil gotospot = gotoSpot(TargetIndex.B).FailOnDestroyedOrNull(TargetIndex.A);

                if (!Utility.IncapableOfCleaning(driver.pawn))
                {
                    TargetIndex filthListIndex = TargetIndex.B;
                    TargetIndex progIndex      = TargetIndex.A;
                    Toil        FilthList      = new Toil();
                    FilthList.initAction = delegate()
                    {
                        Job curJob = FilthList.actor.jobs.curJob;
                        //
                        if (curJob.GetTargetQueue(filthListIndex).NullOrEmpty())
                        {
                            LocalTargetInfo A = curJob.GetTarget(filthListIndex);
                            if (!A.HasThing)
                            {
                                return;
                            }
                            IEnumerable <Filth> l = Utility.SelectAllFilth(FilthList.actor, A, Settings.adv_clean_num);
                            Utility.AddFilthToQueue(curJob, filthListIndex, l, FilthList.actor);
                            FilthList.actor.ReserveAsManyAsPossible(curJob.GetTargetQueue(filthListIndex), curJob);
                            curJob.GetTargetQueue(filthListIndex).Add(A);
                        }
                    };

                    yield return(FilthList);

                    yield return(Toils_Jump.JumpIf(gotospot, () => driver.job.GetTargetQueue(filthListIndex).NullOrEmpty()));

                    Toil nextTarget = Toils_JobTransforms.ExtractNextTargetFromQueue(filthListIndex, true);
                    yield return(nextTarget);

                    yield return(Toils_Jump.JumpIf(gotospot, () => driver.job.GetTargetQueue(filthListIndex).NullOrEmpty()));

                    yield return(Toils_Goto.GotoThing(filthListIndex, PathEndMode.Touch).JumpIfDespawnedOrNullOrForbidden(filthListIndex, nextTarget).JumpIfOutsideHomeArea(filthListIndex, nextTarget));

                    //
                    if (driver.job.GetTargetQueue(progIndex).Count == 0)
                    {
                        driver.job.GetTargetQueue(progIndex).Add(new IntVec3(0, 0, 0));
                    }
                    //
                    Toil clean = new Toil();
                    clean.initAction = delegate()
                    {
                        Filth filth   = clean.actor.jobs.curJob.GetTarget(filthListIndex).Thing as Filth;
                        var   progQue = clean.actor.jobs.curJob.GetTargetQueue(progIndex);
                        progQue[0] = new IntVec3(0, 0, (int)filth.def.filth.cleaningWorkToReduceThickness * filth.thickness);
                    };
                    clean.tickAction = delegate()
                    {
                        Filth   filth   = clean.actor.jobs.curJob.GetTarget(filthListIndex).Thing as Filth;
                        var     progQue = clean.actor.jobs.curJob.GetTargetQueue(progIndex);
                        IntVec3 iv      = progQue[0].Cell;
                        iv.x += 1;
                        iv.y += 1;
                        if (iv.x > filth.def.filth.cleaningWorkToReduceThickness)
                        {
                            filth.ThinFilth();
                            iv.x = 0;
                            if (filth.Destroyed)
                            {
                                clean.actor.records.Increment(RecordDefOf.MessesCleaned);
                                driver.ReadyForNextToil();
                                return;
                            }
                        }
                        progQue[0] = iv;
                    };
                    clean.defaultCompleteMode = ToilCompleteMode.Never;
                    clean.WithEffect(EffecterDefOf.Clean, filthListIndex);
                    clean.WithProgressBar(filthListIndex,
                                          delegate()
                    {
                        var q        = driver.job.GetTargetQueue(progIndex)[0];
                        float result = (float)q.Cell.y / q.Cell.z;
                        return(result);
                    }
                                          , true, -0.5f);
                    clean.PlaySustainerOrSound(() => SoundDefOf.Interact_CleanFilth);
                    clean.JumpIfDespawnedOrNullOrForbidden(filthListIndex, nextTarget);
                    clean.JumpIfOutsideHomeArea(filthListIndex, nextTarget);
                    clean.FailOnDestroyedOrNull(TargetIndex.A);
                    yield return(clean);

                    yield return(Toils_Jump.Jump(nextTarget));
                }
                yield return(gotospot);
            }
            yield return(Toils_Ingest.FindAdjacentEatSurface(TargetIndex.B, TargetIndex.A));

            yield break;
        }
Exemple #19
0
        protected override Toil DoBill()
        {
            var objectThing = job.GetTarget(objectTI).Thing;
            var tableThing  = job.GetTarget(tableTI).Thing as Building_WorkTable;

            var toil = new Toil();

            toil.initAction = delegate {
                job.bill.Notify_DoBillStarted(pawn);

                workCycleProgress = workCycle = Math.Max(job.bill.recipe.workAmount, 10f);
            };
            toil.tickAction = delegate {
                if (objectThing == null || objectThing.Destroyed)
                {
                    pawn.jobs.EndCurrentJob(JobCondition.Incompletable);
                }

                workCycleProgress -= StatExtension.GetStatValue(pawn, StatDefOf.WorkToMake, true);

                tableThing.UsedThisTick();
                if (!tableThing.CurrentlyUsableForBills())
                {
                    pawn.jobs.EndCurrentJob(JobCondition.Incompletable);
                }

                if (workCycleProgress <= 0)
                {
                    int remainingHitPoints = objectThing.MaxHitPoints - objectThing.HitPoints;
                    if (remainingHitPoints > 0)
                    {
                        objectThing.HitPoints += (int)Math.Min(remainingHitPoints, fixedHitPointsPerCycle);
                    }

                    float skillPerc = 0.5f;

                    var skillDef = job.RecipeDef.workSkill;
                    if (skillDef != null)
                    {
                        var skill = pawn.skills.GetSkill(skillDef);

                        if (skill != null)
                        {
                            skillPerc = (float)skill.Level / 20f;

                            skill.Learn(0.11f * job.RecipeDef.workSkillLearnFactor);
                        }
                    }

                    var qualityComponent = objectThing.TryGetComp <CompQuality>();
                    if (qualityComponent != null && qualityComponent.Quality > QualityCategory.Awful)
                    {
                        var qc = qualityComponent.Quality;

                        float skillFactor = Mathf.Lerp(1.5f, 0f, skillPerc);

                        if (!SuccessChanceUtil.SuccessOnAction(pawn, skillFactor, objectThing))
                        {
                            objectThing.HitPoints -= fixedFailedDamage;

                            MoteMaker.ThrowText(pawn.DrawPos, pawn.Map, "Failed");
                        }
                    }

                    pawn.GainComfortFromCellIfPossible();

                    if (objectThing.HitPoints <= 0)
                    {
                        // recycling whats left...
                        float skillFactor = Mathf.Lerp(0.5f, 1.5f, skillPerc);

                        var list = JobDriverUtils.Reclaim(objectThing, skillFactor * 0.1f);

                        pawn.Map.reservationManager.Release(job.targetB, pawn, job);
                        objectThing.Destroy(DestroyMode.Vanish);

                        if (list.Count > 1)
                        {
                            for (int j = 1; j < list.Count; j++)
                            {
                                if (!GenPlace.TryPlaceThing(list [j], pawn.Position, pawn.Map, ThingPlaceMode.Near, null))
                                {
                                    Log.Error("Mending :: " + pawn + " could not drop recipe product " + list [j] + " near " + pawn.Position);
                                }
                            }
                        }
                        list[0].SetPositionDirect(pawn.Position);

                        job.targetB = list[0];
                        job.bill.Notify_IterationCompleted(pawn, list);

                        pawn.Map.reservationManager.Reserve(pawn, job, job.targetB, 1);

                        ReadyForNextToil();
                    }
                    else if (objectThing.HitPoints == objectThing.MaxHitPoints)
                    {
                        // fixed!

                        var mendApparel = objectThing as Apparel;
                        if (mendApparel != null)
                        {
                            ApparelWornByCorpseInt.SetValue(mendApparel, false);
                        }

                        var list = new List <Thing> ();
                        list.Add(objectThing);
                        job.bill.Notify_IterationCompleted(pawn, list);

                        ReadyForNextToil();
                    }
                    else if (objectThing.HitPoints > objectThing.MaxHitPoints)
                    {
                        Log.Error("Mending :: This should never happen! HitPoints > MaxHitPoints");
                        pawn.jobs.EndCurrentJob(JobCondition.Incompletable);
                    }

                    workCycleProgress = workCycle;
                }
            };
            toil.defaultCompleteMode = ToilCompleteMode.Never;
            toil.WithEffect(() => job.bill.recipe.effectWorking, tableTI);
            toil.PlaySustainerOrSound(() => toil.actor.CurJob.bill.recipe.soundWorking);
            toil.WithProgressBar(tableTI, delegate {
                return((float)objectThing.HitPoints / (float)objectThing.MaxHitPoints);
            }, false, 0.5f);
            toil.FailOn(() => {
                var billGiver = job.GetTarget(tableTI).Thing as IBillGiver;

                return(job.bill.suspended || job.bill.DeletedOrDereferenced || (billGiver != null && !billGiver.CurrentlyUsableForBills()));
            });
            return(toil);
        }
        public override IEnumerable <Toil> MakeNewToils()
        {
            this.FailOnIncapable(PawnCapacityDefOf.Manipulation);
            yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell));

            if (_Necron == null)
            {
                Log.Warning("ERROR!!!! _Necron null");
                yield break;
            }
            if (!DamagedNecron.Spawned && !DamagedNecron.Corpse.Spawned)
            {
                Log.Warning("ERROR!!!! DamagedNecron despawned");
                yield break;
            }
            if (DamagedNecron == null)
            {
                Log.Warning("ERROR!!!! DamagedNecron null");
                yield break;
            }
            if (!_Necron.PawnHediffs.NullOrEmpty())
            {
                //    Log.Message("CHECKING!!!! _Necron Damage");
                foreach (Hediff hd in _Necron.PawnHediffs)
                {
                    if (hd.def.hediffClass == typeof(Hediff_Injury))
                    {
                        //    Log.Message("INJURY!!!!");
                        this.useDuration += (int)(((hd.Severity * DamagedNecron.BodySize)) * (_Necron.UnhealableHediffs.Contains(hd) ? 3 : 1));
                    }
                    else if (hd.def.hediffClass == typeof(Hediff_MissingPart) && !DamagedNecron.health.hediffSet.PartOrAnyAncestorHasDirectlyAddedParts(hd.Part))
                    {
                        //    Log.Message("MISSING PART!!!!");
                        this.useDuration += (int)(((300 * DamagedNecron.BodySize) * hd.Severity) * (_Necron.UnhealableHediffs.Contains(hd) ? 3 : 1));
                    }
                    else
                    {
                        //    Log.Message("STILL CHECKING!!!!");
                        if (hd.def.hediffClass != typeof(Hediff_Implant) && hd.def.hediffClass != typeof(Hediff_MissingPart))
                        {
                            //    Log.Message("NOT IMPLANT OR MISSINGPART!!!!");
                        }
                        //    Log.Message(string.Format("Missed {0} {1} on {2}", hd.LabelCap, hd.def.hediffClass, hd.Part.LabelCap));
                    }
                }
            }
            else
            {
                //   Log.Warning("ERROR!!!! DamagedNecron null");
            }
            if (DamagedNecron.Dead)
            {
                this.useDuration = (int)(500 * DamagedNecron.BodySize);
            }
            Toil prepare = Toils_General.Wait(this.useDuration, TargetIndex.A);

            prepare.NPCWithProgressBarToilDelay(TargetIndex.A, false, -0.5f);
            prepare.FailOnDespawnedNullOrForbidden(TargetIndex.A);
            prepare.WithEffect(EffecterDefOf.ConstructMetal, TargetIndex.A);
            prepare.PlaySustainerOrSound(() => SoundDefOf.Crunch);
            if (DamagedNecron.Dead)
            {
                yield return(prepare);

                Toil use = new Toil();
                use.initAction = delegate()
                {
                    Pawn Spyder = use.actor;
                    _Necron.TryRevive(true);
                };
                use.defaultCompleteMode = ToilCompleteMode.Instant;
                yield return(use);
            }
            else
            {
                if (DamagedNecron.Downed)
                {
                    yield return(prepare);

                    Toil use = new Toil();
                    use.initAction = delegate()
                    {
                        Pawn Spyder = use.actor;
                        foreach (Hediff hd in _Necron.PawnHediffs)
                        {
                            DamagedNecron.health.RemoveHediff(hd);
                        }
                    };
                    use.defaultCompleteMode = ToilCompleteMode.Instant;
                    yield return(use);

                    if (_Necron.originalWeapon != null)
                    {
                        ThingWithComps thing = _Necron.originalWeapon;
                        if (thing.Spawned)
                        {
                            thing.DeSpawn();
                        }
                        if (DamagedNecron.inventory.innerContainer.Contains(thing))
                        {
                            DamagedNecron.inventory.innerContainer.Remove(thing);
                        }
                        DamagedNecron.equipment.AddEquipment(thing);
                    }
                    if (_Necron.secondryWeapon != null)
                    {
                        ThingWithComps thing = _Necron.secondryWeapon;
                        if (thing.Spawned)
                        {
                            thing.DeSpawn();
                        }
                        if (DamagedNecron.inventory.innerContainer.Contains(thing))
                        {
                            DamagedNecron.inventory.innerContainer.Remove(thing);
                        }
                        //    DamagedNecron.equipment.AdMechAddOffHandEquipment(thing);
                    }
                }
            }
            yield break;
        }
        // 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;
        }
        protected override Toil DoBill()
        {
            Pawn  actor                   = GetActor();
            Job   curJob                  = actor.jobs.curJob;
            Thing objectThing             = curJob.GetTarget(objectTI).Thing;
            Building_WorkTable tableThing = curJob.GetTarget(tableTI).Thing as Building_WorkTable;

            Toil toil = new Toil();

            toil.initAction = delegate
            {
                curJob.bill.Notify_DoBillStarted(actor);
                this.workCycleProgress = this.workCycle = Math.Max(curJob.bill.recipe.workAmount, 10f);
            };
            toil.tickAction = delegate
            {
                if (objectThing == null || objectThing.Destroyed)
                {
                    actor.jobs.EndCurrentJob(JobCondition.Incompletable);
                }

                workCycleProgress -= StatExtension.GetStatValue(actor, StatDefOf.WorkToMake, true);

                tableThing.UsedThisTick();
                //if (!tableThing.UsableNow)
                //{
                //    actor.jobs.EndCurrentJob(JobCondition.Incompletable);
                //}

                if (workCycleProgress <= 0)
                {
                    float skillPerc = 0.5f;

                    SkillDef skillDef = curJob.RecipeDef.workSkill;
                    if (skillDef != null)
                    {
                        SkillRecord skill = actor.skills.GetSkill(skillDef);

                        if (skill != null)
                        {
                            skillPerc = (float)skill.Level / 20f;

                            skill.Learn(0.11f * curJob.RecipeDef.workSkillLearnFactor);
                        }
                    }

                    actor.GainComfortFromCellIfPossible();

                    Apparel mendApparel = objectThing as Apparel;
                    if (mendApparel != null)
                    {
                        ApparelWornByCorpseInt.SetValue(mendApparel, false);
                    }

                    List <Thing> list = new List <Thing>();
                    list.Add(objectThing);
                    curJob.bill.Notify_IterationCompleted(actor, list);

                    workCycleProgress = workCycle;
                    ReadyForNextToil();
                }
            };


            toil.defaultCompleteMode = ToilCompleteMode.Never;
            toil.WithEffect(() => curJob.bill.recipe.effectWorking, tableTI);
            toil.PlaySustainerOrSound(() => toil.actor.CurJob.bill.recipe.soundWorking);
            toil.WithProgressBar(tableTI, delegate
            {
                return((float)objectThing.HitPoints / (float)objectThing.MaxHitPoints);
            }, false, 0.5f);
            toil.FailOn(() =>
            {
                IBillGiver billGiver = curJob.GetTarget(tableTI).Thing as IBillGiver;

                return(curJob.bill.suspended || curJob.bill.DeletedOrDereferenced || (billGiver != null && !billGiver.CurrentlyUsableForBills()));
            });
            return(toil);
        }
        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;
        }
Exemple #24
0
        static IEnumerable <Toil> DoMakeToils(JobDriver_DoBill_Access __instance)
        {
            //normal scenario
            __instance.AddEndCondition(delegate
            {
                Thing thing = __instance.GetActor().jobs.curJob.GetTarget(TargetIndex.A).Thing;
                if (thing is Building && !thing.Spawned)
                {
                    return(JobCondition.Incompletable);
                }
                return(JobCondition.Ongoing);
            });
            __instance.FailOnBurningImmobile(TargetIndex.A);
            __instance.FailOn(delegate()
            {
                if (__instance.job.GetTarget(TargetIndex.A).Thing is Filth)
                {
                    return(false);
                }

                IBillGiver billGiver = __instance.job.GetTarget(TargetIndex.A).Thing as IBillGiver;
                if (billGiver != null)
                {
                    if (__instance.job.bill.DeletedOrDereferenced)
                    {
                        return(true);
                    }
                    if (!billGiver.CurrentlyUsableForBills())
                    {
                        return(true);
                    }
                }
                return(false);
            });

            Toil gotoBillGiver = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell);

            yield return(new Toil
            {
                initAction = delegate()
                {
                    if (__instance.job.targetQueueB != null && __instance.job.targetQueueB.Count == 1)
                    {
                        UnfinishedThing unfinishedThing = __instance.job.targetQueueB[0].Thing as UnfinishedThing;
                        if (unfinishedThing != null)
                        {
                            unfinishedThing.BoundBill = (Bill_ProductionWithUft)__instance.job.bill;
                        }
                    }
                }
            });

            yield return(Toils_Jump.JumpIf(gotoBillGiver, () => __instance.job.GetTargetQueue(TargetIndex.B).NullOrEmpty()));

            //hauling patch
            if (Settings.adv_haul_all_ings && __instance.pawn.Faction == Faction.OfPlayer)
            {
                Toil checklist = new Toil();
                checklist.initAction = delegate()
                {
                    Pawn actor  = checklist.actor;
                    Job  curJob = actor.jobs.curJob;
                    List <LocalTargetInfo> targetQueue = curJob.GetTargetQueue(TargetIndex.B);
                    if (targetQueue.NullOrEmpty())
                    {
                        actor.jobs.curDriver.EndJobWith(JobCondition.Incompletable);
                    }
                    else
                    {
                        foreach (var target in (targetQueue))
                        {
                            if (target == null || target.Thing.DestroyedOrNull())
                            {
                                actor.jobs.curDriver.EndJobWith(JobCondition.Incompletable);
                                break;
                            }
                        }
                    }
                };

                yield return(checklist);

                Toil extract = new Toil();
                extract.initAction = delegate()
                {
                    Pawn actor  = extract.actor;
                    Job  curJob = actor.jobs.curJob;
                    List <LocalTargetInfo> targetQueue = curJob.GetTargetQueue(TargetIndex.B);
                    if (!curJob.countQueue.NullOrEmpty())
                    {
                        if (curJob.countQueue[0] > targetQueue[0].Thing.stackCount)
                        {
                            actor.jobs.curDriver.EndJobWith(JobCondition.Incompletable);
                        }
                        else
                        {
                            curJob.SetTarget(TargetIndex.B, targetQueue[0]);
                            targetQueue.RemoveAt(0);
                            curJob.count = curJob.countQueue[0];
                            curJob.countQueue.RemoveAt(0);
                        }
                    }
                };

                Toil PickUpThing;
                List <LocalTargetInfo> L = __instance.job.GetTargetQueue(TargetIndex.B);
                if (L.Count < 2 && (L.Count == 0 || L[0].Thing.def.stackLimit < 2))
                {
                    PickUpThing = Toils_Haul.StartCarryThing(TargetIndex.B, true, false, true);
                }
                else
                {
                    PickUpThing            = new Toil();
                    PickUpThing.initAction = delegate()
                    {
                        Pawn  actor  = PickUpThing.actor;
                        Job   curJob = actor.jobs.curJob;
                        Thing thing  = curJob.GetTarget(TargetIndex.B).Thing;
                        List <LocalTargetInfo> targetQueue = curJob.GetTargetQueue(TargetIndex.B);
                        bool InventorySpawned = thing.ParentHolder == actor.inventory;
                        if (InventorySpawned || !Toils_Haul.ErrorCheckForCarry(actor, thing))
                        {
                            if (thing.stackCount < curJob.count)
                            {
                                actor.jobs.curDriver.EndJobWith(JobCondition.Incompletable);
                            }
                            else
                            {
                                Thing splitThing = thing.SplitOff(curJob.count);
                                if (splitThing.ParentHolder != actor.inventory && !actor.inventory.GetDirectlyHeldThings().TryAdd(splitThing, false))
                                {
                                    actor.jobs.curDriver.EndJobWith(JobCondition.Incompletable);
                                }


                                if (!splitThing.Destroyed && splitThing.stackCount != 0)
                                {
                                    targetQueue.Add(splitThing);

                                    if (!InventorySpawned)
                                    {
                                        CompUnloadChecker CUC = splitThing.TryGetComp <CompUnloadChecker>();
                                        if (CUC != null)
                                        {
                                            CUC.ShouldUnload = true;
                                        }
                                    }
                                }

                                if (splitThing != thing && actor.Map.reservationManager.ReservedBy(thing, actor, curJob))
                                {
                                    actor.Map.reservationManager.Release(thing, actor, curJob);
                                }
                            }
                        }
                    };
                }

                Toil TakeToHands = new Toil();
                TakeToHands.initAction = delegate()
                {
                    Pawn actor  = TakeToHands.actor;
                    Job  curJob = actor.jobs.curJob;
                    List <LocalTargetInfo> targetQueue = curJob.GetTargetQueue(TargetIndex.B);
                    if (!targetQueue.NullOrEmpty() && targetQueue[0].Thing.ParentHolder != actor.carryTracker)
                    {
                        actor.inventory.innerContainer.TryTransferToContainer(targetQueue[0].Thing, actor.carryTracker.innerContainer);
                        actor.Reserve(targetQueue[0], curJob);
                        curJob.SetTarget(TargetIndex.B, targetQueue[0]);
                        targetQueue.RemoveAt(0);
                    }
                };

                yield return(extract);

                Toil getToHaulTarget = Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(TargetIndex.B).FailOnSomeonePhysicallyInteracting(TargetIndex.B);
                yield return(Toils_Jump.JumpIf(PickUpThing, () => __instance.job.GetTarget(TargetIndex.B).Thing.ParentHolder == __instance.pawn.inventory));

                yield return(getToHaulTarget);

                yield return(PickUpThing);

                yield return(Toils_Jump.JumpIf(extract, () => !__instance.job.countQueue.NullOrEmpty()));

                yield return(TakeToHands);

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

                Toil findPlaceTarget = Toils_JobTransforms.SetTargetToIngredientPlaceCell(TargetIndex.A, TargetIndex.B, TargetIndex.C);
                yield return(findPlaceTarget);

                yield return(Toils_Haul.PlaceHauledThingInCell(TargetIndex.C, findPlaceTarget, false));

                yield return(Toils_Jump.JumpIfHaveTargetInQueue(TargetIndex.B, TakeToHands));
            }
            else
            {
                Toil extract = Toils_JobTransforms.ExtractNextTargetFromQueue(TargetIndex.B, true);
                yield return(extract);

                Toil getToHaulTarget = Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(TargetIndex.B).FailOnSomeonePhysicallyInteracting(TargetIndex.B);
                yield return(getToHaulTarget);

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

                yield return(JobDriver_DoBill_Access.JumpToCollectNextIntoHandsForBillCrutch(getToHaulTarget, TargetIndex.B));

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

                Toil findPlaceTarget = Toils_JobTransforms.SetTargetToIngredientPlaceCell(TargetIndex.A, TargetIndex.B, TargetIndex.C);
                yield return(findPlaceTarget);

                yield return(Toils_Haul.PlaceHauledThingInCell(TargetIndex.C, findPlaceTarget, false));

                yield return(Toils_Jump.JumpIfHaveTargetInQueue(TargetIndex.B, extract));
            }

            yield return(gotoBillGiver); //one line from normal scenario

            //cleaning patch
            if (Settings.adv_cleaning && !Utility.IncapableOfCleaning(__instance.pawn))
            {
                Toil returnToBillGiver = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell);
                Toil FilthList         = new Toil();
                FilthList.initAction = delegate()
                {
                    Job curJob = FilthList.actor.jobs.curJob;
                    if (curJob.GetTargetQueue(TargetIndex.A).NullOrEmpty())
                    {
                        LocalTargetInfo A = curJob.GetTarget(TargetIndex.A);
                        DoCleanComp     comp;
                        if (!Settings.clean_gizmo || (comp = A.Thing?.TryGetComp <DoCleanComp>()) == null || comp.Active)
                        {
                            IEnumerable <Filth> l = Utility.SelectAllFilth(FilthList.actor, A, Settings.adv_clean_num);
                            Utility.AddFilthToQueue(curJob, TargetIndex.A, l, FilthList.actor);
                            FilthList.actor.ReserveAsManyAsPossible(curJob.GetTargetQueue(TargetIndex.A), curJob);
                        }
                        curJob.targetQueueA.Add(A);
                    }
                };
                yield return(FilthList);

                yield return(Toils_Jump.JumpIf(returnToBillGiver, () => __instance.job.GetTargetQueue(TargetIndex.A).NullOrEmpty()));

                Toil CleanFilthList = Toils_JobTransforms.ClearDespawnedNullOrForbiddenQueuedTargets(TargetIndex.A, null);
                yield return(CleanFilthList);

                yield return(Toils_JobTransforms.ExtractNextTargetFromQueue(TargetIndex.A, true));

                yield return(Toils_Jump.JumpIf(returnToBillGiver, () => __instance.job.GetTargetQueue(TargetIndex.A).NullOrEmpty()));

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

                Toil clean = new Toil();
                clean.initAction = delegate()
                {
                    Filth filth = clean.actor.jobs.curJob.GetTarget(TargetIndex.A).Thing as Filth;
                    __instance.billStartTick             = 0;
                    __instance.ticksSpentDoingRecipeWork = 0;
                    __instance.workLeft = filth.def.filth.cleaningWorkToReduceThickness * filth.thickness;
                };
                clean.tickAction = delegate()
                {
                    Filth filth = clean.actor.jobs.curJob.GetTarget(TargetIndex.A).Thing as Filth;
                    __instance.billStartTick             += 1;
                    __instance.ticksSpentDoingRecipeWork += 1;
                    if (__instance.billStartTick > filth.def.filth.cleaningWorkToReduceThickness)
                    {
                        filth.ThinFilth();
                        __instance.billStartTick = 0;
                        if (filth.Destroyed)
                        {
                            clean.actor.records.Increment(RecordDefOf.MessesCleaned);
                            __instance.ReadyForNextToil();
                            return;
                        }
                    }
                };
                clean.defaultCompleteMode = ToilCompleteMode.Never;
                clean.WithEffect(EffecterDefOf.Clean, TargetIndex.A);
                clean.WithProgressBar(TargetIndex.A, () => __instance.ticksSpentDoingRecipeWork / __instance.workLeft, true, -0.5f);
                clean.PlaySustainerOrSound(() => SoundDefOf.Interact_CleanFilth);
                clean.JumpIfDespawnedOrNullOrForbidden(TargetIndex.A, CleanFilthList);
                clean.JumpIfOutsideHomeArea(TargetIndex.A, CleanFilthList);
                yield return(clean);

                yield return(Toils_Jump.Jump(CleanFilthList));

                yield return(returnToBillGiver);
            }

            //continuation of normal scenario
            yield return(Toils_Recipe.MakeUnfinishedThingIfNeeded());

            yield return(Toils_Recipe.DoRecipeWork().FailOnDespawnedNullOrForbiddenPlacedThings().FailOnCannotTouch(TargetIndex.A, PathEndMode.InteractionCell));

            yield return(Toils_Recipe.FinishRecipeAndStartStoringProduct());

            if (!__instance.job.RecipeDef.products.NullOrEmpty() || !__instance.job.RecipeDef.specialProducts.NullOrEmpty())
            {
                yield return(Toils_Reserve.Reserve(TargetIndex.B, 1, -1, null));

                Toil carryToCell = Toils_Haul.CarryHauledThingToCell(TargetIndex.B);
                yield return(carryToCell);

                yield return(Toils_Haul.PlaceHauledThingInCell(TargetIndex.B, carryToCell, true));

                Toil recount = new Toil();
                recount.initAction = delegate()
                {
                    Bill_Production bill_Production = recount.actor.jobs.curJob.bill as Bill_Production;
                    if (bill_Production != null && bill_Production.repeatMode == BillRepeatModeDefOf.TargetCount)
                    {
                        __instance.MapCrutch().resourceCounter.UpdateResourceCounts();
                    }
                };
                yield return(recount);
            }
            yield break;
        }
        Toil HarvestSeedsToil()
        {
            var toil = new Toil();

            toil.defaultCompleteMode = ToilCompleteMode.Never;
            toil.tickAction          = delegate {
                var actor = toil.actor;
                var plant = Plant;

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

                workDone += actor.GetStatValue(StatDefOf.PlantWorkSpeed, true);
                if (workDone >= plant.def.plant.harvestWork)
                {
                    if (plant.def.plant.harvestedThingDef != null)
                    {
                        if (actor.RaceProps.Humanlike && plant.def.plant.harvestFailable && Rand.Value > actor.GetStatValue(StatDefOf.PlantHarvestYield, true))
                        {
                            MoteMaker.ThrowText((actor.DrawPos + plant.DrawPos) / 2f, actor.Map, "TextMote_HarvestFailed".Translate(), 3.65f);
                        }
                        else
                        {
                            int plantYield = plant.YieldNow();

                            ThingDef harvestedThingDef;

                            var seedDef = plant.def.blueprintDef as SeedDef;
                            if (seedDef != null)
                            {
                                float parameter = Mathf.Min(Mathf.InverseLerp(plant.def.plant.harvestMinGrowth, 0.9f, plant.Growth), 1f);

                                if (seedDef.seed.seedFactor > 0 && Rand.Value < seedDef.seed.baseChance * parameter)
                                {
                                    int count;
                                    if (Rand.Value < seedDef.seed.extraChance)
                                    {
                                        count = 2;
                                    }
                                    else
                                    {
                                        count = 1;
                                    }

                                    Thing seeds = ThingMaker.MakeThing(seedDef, null);
                                    seeds.stackCount = Mathf.RoundToInt(seedDef.seed.seedFactor * count);

                                    GenPlace.TryPlaceThing(seeds, actor.Position, actor.Map, ThingPlaceMode.Near);
                                }

                                plantYield = Mathf.RoundToInt(plantYield * seedDef.seed.harvestFactor);

                                harvestedThingDef = seedDef.harvest;
                            }
                            else
                            {
                                harvestedThingDef = plant.def.plant.harvestedThingDef;
                            }

                            if (plantYield > 0)
                            {
                                var thing = ThingMaker.MakeThing(harvestedThingDef, null);
                                thing.stackCount = plantYield;
                                if (actor.Faction != Faction.OfPlayer)
                                {
                                    thing.SetForbidden(true, true);
                                }
                                GenPlace.TryPlaceThing(thing, actor.Position, actor.Map, ThingPlaceMode.Near, null);
                                actor.records.Increment(RecordDefOf.PlantsHarvested);
                            }
                        }
                    }
                    plant.def.plant.soundHarvestFinish.PlayOneShot(actor);
                    plant.PlantCollected();
                    workDone = 0;
                    ReadyForNextToil();
                    return;
                }
            };

            toil.FailOnDespawnedNullOrForbidden(TargetIndex.A);
            toil.WithEffect(EffecterDefOf.Harvest, TargetIndex.A);
            toil.WithProgressBar(TargetIndex.A, () => workDone / Plant.def.plant.harvestWork, true, -0.5f);
            toil.PlaySustainerOrSound(() => Plant.def.plant.soundHarvesting);

            return(toil);
        }
        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.Plants, 0.22f);
                }

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

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

                    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 #27
0
        protected Toil Train(Thing currentWeapon)
        {
            Toil train = new Toil();

            train.initAction = delegate()
            {
                Pawn     actor  = train.actor;
                Job      curJob = actor.jobs.curJob;
                ThingDef weapon = practice ? currentWeapon.def : job.targetB.Thing.def;
                workLeft                  = curJob.bill.recipe.WorkAmountTotal(null);
                billStartTick             = Find.TickManager.TicksGame;
                ticksSpentDoingRecipeWork = 0;
                curJob.bill.Notify_DoBillStarted(actor);
                Verb            verbToUse = actor.TryGetAttackVerb(currentWeapon, true);
                LocalTargetInfo target    = actor.jobs.curJob.GetTarget(TargetIndex.A);
                pawn.stances.SetStance(new Stance_Cooldown(2, target, verbToUse));
            };
            train.tickAction = delegate()
            {
                Pawn     actor  = train.actor;
                Job      curJob = actor.jobs.curJob;
                ThingDef weapon = practice ? currentWeapon.def : job.targetB.Thing.def;
                ticksSpentDoingRecipeWork++;
                curJob.bill.Notify_PawnDidWork(actor);
                IBillGiverWithTickAction billGiverWithTickAction = train.actor.CurJob.GetTarget(TargetIndex.A).Thing as IBillGiverWithTickAction;
                if (billGiverWithTickAction != null)
                {
                    billGiverWithTickAction.UsedThisTick();
                }
                float num = (curJob.RecipeDef.workSpeedStat != null) ? actor.GetStatValue(curJob.RecipeDef.workSpeedStat, true) : 1f;
                if (curJob.RecipeDef.workTableSpeedStat != null)
                {
                    Building_WorkTable building_WorkTable = BillGiver as Building_WorkTable;
                    if (building_WorkTable != null)
                    {
                        num *= building_WorkTable.GetStatValue(curJob.RecipeDef.workTableSpeedStat, true);
                    }
                }
                if (DebugSettings.fastCrafting)
                {
                    num *= 30f;
                }
                workLeft -= num;
                actor.GainComfortFromCellIfPossible();
                if (workLeft <= 0f)
                {
                    ReadyForNextToil();
                }
                LearningUtility.WeaponTrainingAnimation(pawn, pawn.jobs.curJob.GetTarget(TargetIndex.A), actor.TryGetAttackVerb(currentWeapon, true), ticksSpentDoingRecipeWork);
                if (job.RecipeDef.workSkill != null)
                {
                    float xpDelta = practice ? 0.5f : 0.1f;
                    float xp      = xpDelta * job.RecipeDef.workSkillLearnFactor;
                    actor.skills.GetSkill(job.RecipeDef.workSkill).Learn(xp, false);
                }
            };
            train.defaultCompleteMode = ToilCompleteMode.Never;
            train.WithEffect(() => train.actor.CurJob.bill.recipe.effectWorking, TargetIndex.A);
            train.PlaySustainerOrSound(() => train.actor.CurJob.bill.recipe.soundWorking);
            train.WithProgressBar(TargetIndex.A, delegate
            {
                Pawn actor = train.actor;
                Job curJob = actor.CurJob;
                return(1f - (workLeft / curJob.bill.recipe.WorkAmountTotal(null)));
            }, false, -0.5f);
            train.FailOn(() => train.actor.CurJob.bill.suspended);
            train.activeSkill = () => train.actor.CurJob.bill.recipe.workSkill;
            return(train);
        }
        protected override Toil DoBill()
        {
            Pawn  actor                   = GetActor();
            Job   curJob                  = actor.jobs.curJob;
            Thing objectThing             = curJob.GetTarget(objectTI).Thing;
            Building_WorkTable tableThing = curJob.GetTarget(tableTI).Thing as Building_WorkTable;

            Toil toil = new Toil();

            toil.initAction = delegate {
                curJob.bill.Notify_DoBillStarted();

                this.failChance = ChanceDef.GetFor(objectThing);

                this.workCycleProgress = this.workCycle = Math.Max(curJob.bill.recipe.workAmount, 10f);
            };
            toil.tickAction = delegate {
                if (objectThing == null || objectThing.Destroyed)
                {
                    actor.jobs.EndCurrentJob(JobCondition.Incompletable);
                }

                workCycleProgress -= StatExtension.GetStatValue(actor, StatDefOf.WorkToMake, true);

                if (!tableThing.UsableNow)
                {
                    actor.jobs.EndCurrentJob(JobCondition.Incompletable);
                }

                if (workCycleProgress <= 0)
                {
                    int remainingHitPoints = objectThing.MaxHitPoints - objectThing.HitPoints;
                    if (remainingHitPoints > 0)
                    {
                        objectThing.HitPoints += (int)Math.Min(remainingHitPoints, fixedHitPointsPerCycle);
                    }

                    SkillRecord skill = actor.skills.GetSkill(SkillDefOf.Crafting);

                    if (skill == null)
                    {
                        Log.Error("Mending :: This should never happen! skill == null");

                        actor.jobs.EndCurrentJob(JobCondition.Incompletable);

                        return;
                    }

                    float skillPerc = (float)skill.Level / 20f;

                    skill.Learn(0.33f);

                    CompQuality qualityComponent = objectThing.TryGetComp <CompQuality>();
                    if (qualityComponent != null && qualityComponent.Quality > QualityCategory.Awful)
                    {
                        QualityCategory qc = qualityComponent.Quality;

                        float skillFactor = Mathf.Lerp(1.5f, 0f, skillPerc);

                        if (failChance != null && Rand.Value < failChance.Chance(qc) * skillFactor)
                        {
                            objectThing.HitPoints -= fixedFailedDamage;

                            MoteMaker.ThrowText(actor.DrawPos, actor.Map, "Failed");
                        }
                    }

                    actor.GainComfortFromCellIfPossible();

                    if (objectThing.HitPoints <= 0)
                    {
                        // recycling whats left...
                        float skillFactor = Mathf.Lerp(0.5f, 1.5f, skillPerc);

                        var list = JobDriverUtils.Reclaim(objectThing, skillFactor * 0.1f);

                        pawn.Map.reservationManager.Release(curJob.targetB, pawn);
                        objectThing.Destroy(DestroyMode.Vanish);

                        if (list.Count > 1)
                        {
                            for (int j = 1; j < list.Count; j++)
                            {
                                if (!GenPlace.TryPlaceThing(list [j], actor.Position, actor.Map, ThingPlaceMode.Near, null))
                                {
                                    Log.Error("Mending :: " + actor + " could not drop recipe product " + list [j] + " near " + actor.Position);
                                }
                            }
                        }
                        list[0].SetPositionDirect(actor.Position);

                        curJob.targetB = list[0];
                        curJob.bill.Notify_IterationCompleted(actor, list);

                        pawn.Map.reservationManager.Reserve(pawn, curJob.targetB, 1);

                        ReadyForNextToil();
                    }
                    else if (objectThing.HitPoints == objectThing.MaxHitPoints)
                    {
                        // fixed!

                        Apparel mendApparel = objectThing as Apparel;
                        if (mendApparel != null)
                        {
                            ApparelWornByCorpseInt.SetValue(mendApparel, false);
                        }

                        List <Thing> list = new List <Thing> ();
                        list.Add(objectThing);
                        curJob.bill.Notify_IterationCompleted(actor, list);

                        ReadyForNextToil();
                    }
                    else if (objectThing.HitPoints > objectThing.MaxHitPoints)
                    {
                        Log.Error("Mending :: This should never happen! HitPoints > MaxHitPoints");
                        actor.jobs.EndCurrentJob(JobCondition.Incompletable);
                    }

                    workCycleProgress = workCycle;
                }
            };
            toil.defaultCompleteMode = ToilCompleteMode.Never;
            toil.WithEffect(() => curJob.bill.recipe.effectWorking, tableTI);
            toil.PlaySustainerOrSound(() => toil.actor.CurJob.bill.recipe.soundWorking);
            toil.WithProgressBar(tableTI, delegate {
                return((float)objectThing.HitPoints / (float)objectThing.MaxHitPoints);
            }, false, 0.5f);
            toil.FailOn(() => {
                IBillGiver billGiver = curJob.GetTarget(tableTI).Thing as IBillGiver;

                return(curJob.bill.suspended || curJob.bill.DeletedOrDereferenced || (billGiver != null && !billGiver.CurrentlyUsable()));
            });
            return(toil);
        }
Exemple #29
0
        // Token: 0x060000EE RID: 238 RVA: 0x00008574 File Offset: 0x00006774
        public static void DoRecipeWork_Prefix(ref Toil __result)
        {
            Toil toil = new Toil();

            toil.initAction = delegate()
            {
                Log.Message("init delegated.", false);
                Pawn actor  = toil.actor;
                Job  curJob = actor.jobs.curJob;
                bool animal = actor.RaceProps.Animal;
                if (animal)
                {
                    Log.Message("I am in.", false);
                    JobDriver          curDriver          = actor.jobs.curDriver;
                    JobDriver_WPDoBill jobDriver_WPDoBill = curDriver as JobDriver_WPDoBill;
                    UnfinishedThing    unfinishedThing    = curJob.GetTarget(TargetIndex.B).Thing as UnfinishedThing;
                    jobDriver_WPDoBill.workLeft = curJob.bill.recipe.WorkAmountTotal(unfinishedThing.def);
                    bool flag = unfinishedThing != null;
                    if (flag)
                    {
                        unfinishedThing.workLeft = jobDriver_WPDoBill.workLeft;
                    }
                    jobDriver_WPDoBill.billStartTick             = Find.TickManager.TicksGame;
                    jobDriver_WPDoBill.ticksSpentDoingRecipeWork = 0;
                    curJob.bill.Notify_DoBillStarted(actor);
                }
                else
                {
                    Log.Message("I am here instead.", false);
                    JobDriver_DoBill jobDriver_DoBill = (JobDriver_DoBill)actor.jobs.curDriver;
                    UnfinishedThing  unfinishedThing2 = curJob.GetTarget(TargetIndex.B).Thing as UnfinishedThing;
                    bool             flag2            = unfinishedThing2 != null && unfinishedThing2.Initialized;
                    if (flag2)
                    {
                        jobDriver_DoBill.workLeft = unfinishedThing2.workLeft;
                    }
                    else
                    {
                        jobDriver_DoBill.workLeft = curJob.bill.recipe.WorkAmountTotal((unfinishedThing2 == null) ? null : unfinishedThing2.Stuff);
                        bool flag3 = unfinishedThing2 != null;
                        if (flag3)
                        {
                            unfinishedThing2.workLeft = jobDriver_DoBill.workLeft;
                        }
                    }
                    jobDriver_DoBill.billStartTick             = Find.TickManager.TicksGame;
                    jobDriver_DoBill.ticksSpentDoingRecipeWork = 0;
                    curJob.bill.Notify_DoBillStarted(actor);
                }
            };
            toil.tickAction = delegate()
            {
                Log.Message("tick delegated.", false);
                Pawn      actor     = toil.actor;
                Job       curJob    = actor.jobs.curJob;
                JobDriver curDriver = actor.jobs.curDriver;
                bool      animal    = actor.RaceProps.Animal;
                if (animal)
                {
                    JobDriver_WPDoBill jobDriver_WPDoBill = curDriver as JobDriver_WPDoBill;
                    UnfinishedThing    unfinishedThing    = curJob.GetTarget(TargetIndex.B).Thing as UnfinishedThing;
                    bool flag = unfinishedThing != null && unfinishedThing.Destroyed;
                    if (flag)
                    {
                        actor.jobs.EndCurrentJob(JobCondition.Incompletable, true, true);
                        return;
                    }
                    jobDriver_WPDoBill.ticksSpentDoingRecipeWork++;
                    curJob.bill.Notify_PawnDidWork(actor);
                    IBillGiverWithTickAction billGiverWithTickAction = toil.actor.CurJob.GetTarget(TargetIndex.A).Thing as IBillGiverWithTickAction;
                    bool flag2 = billGiverWithTickAction != null;
                    if (flag2)
                    {
                        billGiverWithTickAction.UsedThisTick();
                    }
                    float num = (curJob.RecipeDef.workSpeedStat != null) ? actor.GetStatValue(curJob.RecipeDef.workSpeedStat, true) : 1f;
                    Building_WorkTable building_WorkTable = jobDriver_WPDoBill.BillGiver as Building_WorkTable;
                    bool flag3 = building_WorkTable != null;
                    if (flag3)
                    {
                        num *= building_WorkTable.GetStatValue(StatDefOf.WorkTableWorkSpeedFactor, true);
                    }
                    bool fastCrafting = DebugSettings.fastCrafting;
                    if (fastCrafting)
                    {
                        num *= 30f;
                    }
                    jobDriver_WPDoBill.workLeft -= num;
                    bool flag4 = unfinishedThing != null;
                    if (flag4)
                    {
                        unfinishedThing.workLeft = jobDriver_WPDoBill.workLeft;
                    }
                    actor.GainComfortFromCellIfPossible(false);
                    bool flag5 = jobDriver_WPDoBill.workLeft <= 0f;
                    if (flag5)
                    {
                        jobDriver_WPDoBill.ReadyForNextToil();
                    }
                    bool usesUnfinishedThing = curJob.bill.recipe.UsesUnfinishedThing;
                    if (usesUnfinishedThing)
                    {
                        int  num2  = Find.TickManager.TicksGame - jobDriver_WPDoBill.billStartTick;
                        bool flag6 = num2 >= 3000 && num2 % 1000 == 0;
                        if (flag6)
                        {
                            actor.jobs.CheckForJobOverride();
                        }
                    }
                }
                bool flag7 = !actor.RaceProps.Animal;
                if (flag7)
                {
                    JobDriver_DoBill jobDriver_DoBill = (JobDriver_DoBill)actor.jobs.curDriver;
                    UnfinishedThing  unfinishedThing2 = curJob.GetTarget(TargetIndex.B).Thing as UnfinishedThing;
                    bool             flag8            = unfinishedThing2 != null && unfinishedThing2.Destroyed;
                    if (flag8)
                    {
                        actor.jobs.EndCurrentJob(JobCondition.Incompletable, true, true);
                    }
                    else
                    {
                        jobDriver_DoBill.ticksSpentDoingRecipeWork++;
                        curJob.bill.Notify_PawnDidWork(actor);
                        IBillGiverWithTickAction billGiverWithTickAction2 = toil.actor.CurJob.GetTarget(TargetIndex.A).Thing as IBillGiverWithTickAction;
                        bool flag9 = billGiverWithTickAction2 != null;
                        if (flag9)
                        {
                            billGiverWithTickAction2.UsedThisTick();
                        }
                        bool flag10 = curJob.RecipeDef.workSkill != null && curJob.RecipeDef.UsesUnfinishedThing;
                        if (flag10)
                        {
                            actor.skills.GetSkill(curJob.RecipeDef.workSkill).Learn(0.11f * curJob.RecipeDef.workSkillLearnFactor, false);
                        }
                        float num3 = (curJob.RecipeDef.workSpeedStat != null) ? actor.GetStatValue(curJob.RecipeDef.workSpeedStat, true) : 1f;
                        Building_WorkTable building_WorkTable2 = jobDriver_DoBill.BillGiver as Building_WorkTable;
                        bool flag11 = building_WorkTable2 != null;
                        if (flag11)
                        {
                            num3 *= building_WorkTable2.GetStatValue(StatDefOf.WorkTableWorkSpeedFactor, true);
                        }
                        bool fastCrafting2 = DebugSettings.fastCrafting;
                        if (fastCrafting2)
                        {
                            num3 *= 30f;
                        }
                        jobDriver_DoBill.workLeft -= num3;
                        bool flag12 = unfinishedThing2 != null;
                        if (flag12)
                        {
                            unfinishedThing2.workLeft = jobDriver_DoBill.workLeft;
                        }
                        actor.GainComfortFromCellIfPossible(false);
                        bool flag13 = jobDriver_DoBill.workLeft <= 0f;
                        if (flag13)
                        {
                            jobDriver_DoBill.ReadyForNextToil();
                        }
                        bool usesUnfinishedThing2 = curJob.bill.recipe.UsesUnfinishedThing;
                        if (usesUnfinishedThing2)
                        {
                            int  num4   = Find.TickManager.TicksGame - jobDriver_DoBill.billStartTick;
                            bool flag14 = num4 >= 3000 && num4 % 1000 == 0;
                            if (flag14)
                            {
                                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, delegate
            {
                Pawn actor = toil.actor;
                Job curJob = actor.CurJob;
                UnfinishedThing unfinishedThing = curJob.GetTarget(TargetIndex.B).Thing as UnfinishedThing;
                bool animal = actor.RaceProps.Animal;
                float result;
                if (animal)
                {
                    result = 1f - ((JobDriver_WPDoBill)actor.jobs.curDriver).workLeft / curJob.bill.recipe.WorkAmountTotal((unfinishedThing == null) ? null : unfinishedThing.Stuff);
                }
                else
                {
                    result = 1f - ((JobDriver_DoBill)actor.jobs.curDriver).workLeft / curJob.bill.recipe.WorkAmountTotal((unfinishedThing == null) ? null : unfinishedThing.Stuff);
                }
                return(result);
            }, false, -0.5f);
            toil.FailOn(() => toil.actor.CurJob.bill.suspended);
            __result = toil;
        }
Exemple #30
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            // ツールまで移動
            yield return(Toils_Goto.GotoThing(ToolInd, PathEndMode.Touch).FailOnDespawnedNullOrForbidden(ToolInd));

            // ツールを手に取る
            yield return(Toils_Haul.StartCarryThing(ToolInd));

            // ターゲットが水やり対象として不適になっていたらリストから外す
            Toil initExtractTargetFromQueue = Toils_Mizu.ClearConditionSatisfiedTargets(WateringInd, (lti) =>
            {
                var mapComp = this.Map.GetComponent <MapComponent_Watering>();
                return(mapComp.Get(this.Map.cellIndices.CellToIndex(lti.Cell)) > 0);
            });

            yield return(initExtractTargetFromQueue);

            yield return(Toils_JobTransforms.SucceedOnNoTargetInQueue(WateringInd));

            // ターゲットキューから次のターゲットを取り出す
            yield return(Toils_JobTransforms.ExtractNextTargetFromQueue(WateringInd, true));

            // ターゲットの元へ移動
            yield return(Toils_Goto.GotoCell(WateringInd, PathEndMode.Touch));

            // 作業中
            Toil workToil = new Toil();

            workToil.initAction = delegate
            {
                // 必要工数の計算
                this.ticksLeftThisToil = WorkingTicks;
            };
            // 細々とした設定
            workToil.defaultCompleteMode = ToilCompleteMode.Delay;
            workToil.WithProgressBar(WateringInd, () => 1f - (float)this.ticksLeftThisToil / WorkingTicks, true, -0.5f);
            workToil.PlaySustainerOrSound(() => SoundDefOf.Interact_CleanFilth);
            yield return(workToil);

            // 作業終了
            var finishToil = new Toil();

            finishToil.initAction = () =>
            {
                // 水やり更新
                var mapComp = this.Map.GetComponent <MapComponent_Watering>();
                mapComp.Set(this.Map.cellIndices.CellToIndex(WateringPos), MapComponent_Watering.MaxWateringValue);
                this.Map.mapDrawer.SectionAt(WateringPos).dirtyFlags = MapMeshFlag.Terrain;

                // ツールから水を減らす
                var compTool = Tool.GetComp <CompWaterTool>();
                compTool.StoredWaterVolume -= ConsumeWaterVolume;
            };
            finishToil.defaultCompleteMode = ToilCompleteMode.Instant;
            yield return(finishToil);

            // 最初に戻る
            yield return(Toils_Jump.JumpIf(initExtractTargetFromQueue, () =>
            {
                return this.pawn.jobs.curJob.GetTargetQueue(WateringInd).Count > 0;
            }));

            // ツールを片付ける場所を決める
            yield return(Toils_Mizu.TryFindStoreCell(ToolInd, ToolPlaceInd));

            // 倉庫まで移動
            yield return(Toils_Goto.GotoCell(ToolPlaceInd, PathEndMode.Touch));

            // 倉庫に置く
            yield return(Toils_Haul.PlaceHauledThingInCell(ToolPlaceInd, null, true));
        }
Exemple #31
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            //Commence fail checks!
            this.FailOnDestroyedOrNull(TargetIndex.A);

            yield return(Toils_Reserve.Reserve(AltarIndex, 1));

            yield return(new Toil
            {
                initAction = delegate
                {
                    this.DropAltar.IsFilling = true;
                    this.customString = "FillChthonianPitGoing".Translate();
                }
            });


            yield return(Toils_Goto.GotoThing(AltarIndex, PathEndMode.Touch));

            Toil chantingTime = new Toil()
            {
                defaultCompleteMode = ToilCompleteMode.Delay,
                defaultDuration     = 5000
            };

            chantingTime.WithProgressBarToilDelay(AltarIndex, false, -0.5f);
            chantingTime.PlaySustainerOrSound(() => SoundDefOf.Interact_ClearSnow);
            chantingTime.initAction = delegate
            {
                this.customString = "FillChthonianPitFilling".Translate();
            };
            chantingTime.AddPreTickAction(() =>
            {
                if (this.DropAltar.IsActive)
                {
                    if (Rand.Range(1, 100) > 95)
                    {
                        this.DropAltar.TrySpawnChthonian();
                    }
                }
                if (this.DropAltar.GaveSacrifice)
                {
                    if (this.pawn.IsHashIntervalTick(300))
                    {
                        if (Rand.Range(1, 100) > 60)
                        {
                            Messages.Message("CriesFromBelow".Translate(new object[]
                            {
                                this.pawn.LabelShort,
                                this.pawn.gender.GetPronoun()
                            }), MessageTypeDefOf.NegativeEvent);
                        }
                    }
                }
            });
            yield return(chantingTime);

            yield return(new Toil
            {
                initAction = delegate
                {
                    this.customString = "FillChthonianPitFinished".Translate();
                    IntVec3 position = this.DropAltar.Position;
                    FillingCompleted();
                },
                defaultCompleteMode = ToilCompleteMode.Instant
            });

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

            //Toil 9: Think about that.
            yield return(new Toil
            {
                initAction = delegate
                {
                    ////It's a day to remember
                    //TaleDef taleToAdd = TaleDef.Named("HeldSermon");
                    //if ((this.pawn.IsColonist || this.pawn.HostFaction == Faction.OfPlayer) && taleToAdd != null)
                    //{
                    //    TaleRecorder.RecordTale(taleToAdd, new object[]
                    //    {
                    //       this.pawn,
                    //    });
                    //}
                },
                defaultCompleteMode = ToilCompleteMode.Instant
            });

            yield break;
        }
        protected override IEnumerable <Toil> MakeNewToils()
        {
            // モップまで移動
            yield return(Toils_Goto.GotoThing(MopInd, PathEndMode.Touch).FailOnDespawnedNullOrForbidden(MopInd));

            // モップを手に取る
            yield return(Toils_Haul.StartCarryThing(MopInd));

            // ターゲットが掃除対象として不適になっていたらリストから外す
            // Thing系にしか使えない
            var initExtractTargetFromQueue = Toils_Mizu.ClearConditionSatisfiedTargets(
                MoppingInd,
                lti => lti.Cell.GetFirstThing(pawn.Map, MizuDef.Thing_MoppedThing) != null);

            yield return(initExtractTargetFromQueue);

            yield return(Toils_JobTransforms.SucceedOnNoTargetInQueue(MoppingInd));

            // ターゲットキューから次のターゲットを取り出す
            yield return(Toils_JobTransforms.ExtractNextTargetFromQueue(MoppingInd));

            // ターゲットの元へ移動
            yield return(Toils_Goto.GotoCell(MoppingInd, PathEndMode.Touch).JumpIf(
                             () =>
            {
                var target = pawn.jobs.curJob.GetTarget(MoppingInd);
                if (target.HasThing)
                {
                    return true;
                }

                return target.Cell.GetFirstThing(pawn.Map, MizuDef.Thing_MoppedThing) != null;
            },
                             initExtractTargetFromQueue).JumpIfOutsideMopArea(MoppingInd, initExtractTargetFromQueue));

            // モップ掛け作業中
            var mopToil = new Toil
            {
                initAction = delegate
                {
                    // 必要工数の計算
                    ticksLeftThisToil = MoppingTicks;
                },

                // 細々とした設定
                defaultCompleteMode = ToilCompleteMode.Delay
            };

            mopToil.WithProgressBar(MoppingInd, () => 1f - ((float)ticksLeftThisToil / MoppingTicks), true);
            mopToil.PlaySustainerOrSound(() => SoundDefOf.Interact_CleanFilth);

            // 掃除中に条件が変更されたら最初に戻る
            mopToil.JumpIf(
                () =>
            {
                var target = pawn.jobs.curJob.GetTarget(MoppingInd);
                if (target.HasThing)
                {
                    return(true);
                }

                return(target.Cell.GetFirstThing(pawn.Map, MizuDef.Thing_MoppedThing) != null);
            },
                initExtractTargetFromQueue);
            mopToil.JumpIfOutsideMopArea(MoppingInd, initExtractTargetFromQueue);
            yield return(mopToil);

            // モップ掛け終了
            var finishToil = new Toil
            {
                initAction = () =>
                {
                    // モップオブジェクト生成
                    var moppedThing = ThingMaker.MakeThing(MizuDef.Thing_MoppedThing);
                    GenSpawn.Spawn(moppedThing, MoppingPos, mopToil.actor.Map);

                    // モップから水を減らす
                    var compTool = Mop.GetComp <CompWaterTool>();
                    compTool.StoredWaterVolume -= ConsumeWaterVolume;
                },
                defaultCompleteMode = ToilCompleteMode.Instant
            };

            yield return(finishToil);

            // 最初に戻る
            yield return(Toils_Jump.JumpIf(
                             initExtractTargetFromQueue,
                             () => pawn.jobs.curJob.GetTargetQueue(MoppingInd).Count > 0));

            // モップを片付ける場所を決める
            yield return(Toils_Mizu.TryFindStoreCell(MopInd, MopPlaceInd));

            // Toil startCarryToil = new Toil();
            // startCarryToil.initAction = () =>
            // {
            // var actor = startCarryToil.actor;
            // var curJob = actor.jobs.curJob;
            // IntVec3 c;
            // if (StoreUtility.TryFindBestBetterStoreCellFor(Mop, actor, actor.Map, StoragePriority.Unstored, actor.Faction, out c))
            // {
            // curJob.targetC = c;
            // curJob.count = 99999;
            // return;
            // }
            // };
            // startCarryToil.defaultCompleteMode = ToilCompleteMode.Instant;
            // yield return startCarryToil;

            // 倉庫まで移動
            yield return(Toils_Goto.GotoCell(MopPlaceInd, PathEndMode.Touch));

            // 倉庫に置く
            yield return(Toils_Haul.PlaceHauledThingInCell(MopPlaceInd, null, true));
        }
Exemple #33
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            Bill bill = job.bill;

            AddEndCondition(delegate
            {
                Thing thing = GetActor().jobs.curJob.GetTarget(TargetIndex.A).Thing;
                if (thing is Building && !thing.Spawned)
                {
                    return(JobCondition.Incompletable);
                }
                return(JobCondition.Ongoing);
            });
            this.FailOnBurningImmobile(TargetIndex.A);
            this.FailOn(delegate()
            {
                IBillGiver billGiver = job.GetTarget(TargetIndex.A).Thing as IBillGiver;
                if (billGiver != null)
                {
                    if (job.bill.DeletedOrDereferenced)
                    {
                        return(true);
                    }
                    if (!billGiver.CurrentlyUsableForBills())
                    {
                        return(true);
                    }
                }
                return(false);
            });
            AddFinishAction(delegate()
            {
                //Log.Message("LearnWeapon: finishing");
                ThingWithComps thingWithComps = (ThingWithComps)job.targetB.Thing;
                if (pawn.equipment.Primary != null)
                {
                    pawn.equipment.TryDropEquipment(thingWithComps, out thingWithComps, pawn.Position, false);
                }
            });
            Toil gotoBillGiver = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell);

            yield return(Toils_Jump.JumpIf(gotoBillGiver, () => job.GetTargetQueue(TargetIndex.B).NullOrEmpty <LocalTargetInfo>()));

            Toil extract = Toils_JobTransforms.ExtractNextTargetFromQueue(TargetIndex.B, true);

            yield return(extract);

            Toil getToHaulTarget = Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(TargetIndex.B).FailOnSomeonePhysicallyInteracting(TargetIndex.B);

            yield return(getToHaulTarget);

            //temporary equip
            yield return(new Toil
            {
                initAction = delegate()
                {
                    ThingWithComps thingWithComps = (ThingWithComps)job.targetB.Thing;
                    ThingWithComps thingWithComps2;
                    if (thingWithComps.def.stackLimit > 1 && thingWithComps.stackCount > 1)
                    {
                        thingWithComps2 = (ThingWithComps)thingWithComps.SplitOff(1);
                    }
                    else
                    {
                        thingWithComps2 = thingWithComps;
                        thingWithComps2.DeSpawn(DestroyMode.Vanish);
                    }
                    pawn.equipment.MakeRoomFor(thingWithComps2);
                    pawn.equipment.AddEquipment(thingWithComps2);
                    if (thingWithComps.def.soundInteract != null)
                    {
                        thingWithComps.def.soundInteract.PlayOneShot(new TargetInfo(pawn.Position, pawn.Map, false));
                    }
                },
                defaultCompleteMode = ToilCompleteMode.Instant
            });

            yield return(Toils_Jump.JumpIfHaveTargetInQueue(TargetIndex.B, extract));

            yield return(gotoBillGiver);

            yield return(Toils_Combat.TrySetJobToUseAttackVerb(TargetIndex.A));

            Toil train = new Toil();

            train.initAction = delegate()
            {
                Pawn     actor  = train.actor;
                Job      curJob = actor.jobs.curJob;
                ThingDef weapon = job.targetB.Thing.def;
                workLeft                  = curJob.bill.recipe.WorkAmountTotal(null);
                billStartTick             = Find.TickManager.TicksGame;
                ticksSpentDoingRecipeWork = 0;
                curJob.bill.Notify_DoBillStarted(actor);
                //sound:
                if (weapon.soundInteract != null)
                {
                    weapon.soundInteract.PlayOneShot(new TargetInfo(pawn.Position, pawn.Map, false));
                }
            };
            train.tickAction = delegate()
            {
                Pawn     actor  = train.actor;
                Job      curJob = actor.jobs.curJob;
                ThingDef weapon = job.targetB.Thing.def;
                ticksSpentDoingRecipeWork++;
                curJob.bill.Notify_PawnDidWork(actor);
                IBillGiverWithTickAction billGiverWithTickAction = train.actor.CurJob.GetTarget(TargetIndex.A).Thing as IBillGiverWithTickAction;
                if (billGiverWithTickAction != null)
                {
                    billGiverWithTickAction.UsedThisTick();
                }
                float num = (curJob.RecipeDef.workSpeedStat != null) ? actor.GetStatValue(curJob.RecipeDef.workSpeedStat, true) : 1f;
                if (curJob.RecipeDef.workTableSpeedStat != null)
                {
                    Building_WorkTable building_WorkTable = BillGiver as Building_WorkTable;
                    if (building_WorkTable != null)
                    {
                        num *= building_WorkTable.GetStatValue(curJob.RecipeDef.workTableSpeedStat, true);
                    }
                }
                if (DebugSettings.fastCrafting)
                {
                    num *= 30f;
                }
                workLeft -= num;
                actor.GainComfortFromCellIfPossible();
                if (workLeft <= 0f)
                {
                    ReadyForNextToil();
                }

                //pawn posture
                Verb            verbToUse = actor.jobs.curJob.verbToUse;
                LocalTargetInfo target    = actor.jobs.curJob.GetTarget(TargetIndex.A);
                pawn.stances.SetStance(new Stance_Warmup(1, target, verbToUse));

                //sound:
                if (verbToUse.verbProps != null && verbToUse.verbProps.warmupTime > 0)
                {
                    if ((ticksSpentDoingRecipeWork % verbToUse.verbProps.AdjustedFullCycleTime(verbToUse, actor).SecondsToTicks()) == 0)
                    {
                        if (verbToUse.verbProps.soundCast != null)
                        {
                            verbToUse.verbProps.soundCast.PlayOneShot(new TargetInfo(pawn.Position, pawn.Map, false));
                        }
                        if (verbToUse.verbProps.soundCastTail != null)
                        {
                            verbToUse.verbProps.soundCastTail.PlayOneShotOnCamera(pawn.Map);
                        }
                    }
                }
                if (job.RecipeDef.workSkill != null)
                {
                    //float xpDelta = techComp.proficientWeapons.Contains(job.targetB.Thing.def) ? 1f : 0.1f;
                    float xp = 0.1f * job.RecipeDef.workSkillLearnFactor;
                    actor.skills.GetSkill(job.RecipeDef.workSkill).Learn(xp, false);
                }
            };
            train.defaultCompleteMode = ToilCompleteMode.Never;
            train.WithEffect(() => train.actor.CurJob.bill.recipe.effectWorking, TargetIndex.A);
            train.PlaySustainerOrSound(() => train.actor.CurJob.bill.recipe.soundWorking);
            train.WithProgressBar(TargetIndex.A, delegate
            {
                Pawn actor = train.actor;
                Job curJob = actor.CurJob;
                //return 1f - ((JobDriver_DoBill)actor.jobs.curDriver).workLeft / curJob.bill.recipe.WorkAmountTotal(null);
                return(1f - (workLeft / curJob.bill.recipe.WorkAmountTotal(null)));
            }, false, -0.5f);
            train.FailOn(() => train.actor.CurJob.bill.suspended);
            train.activeSkill = () => train.actor.CurJob.bill.recipe.workSkill;
            yield return(train.FailOnDespawnedNullOrForbiddenPlacedThings().FailOnCannotTouch(TargetIndex.A, PathEndMode.InteractionCell));

            Toil finalizeTraining = new Toil();

            finalizeTraining.initAction = delegate
            {
                Pawn          actor    = finalizeTraining.actor;
                CompKnowledge techComp = actor.TryGetComp <CompKnowledge>();
                if (!techComp.proficientWeapons.Contains(job.targetB.Thing.def))
                {
                    techComp.proficientWeapons.Add(TargetThingB.def);
                }
                job.bill.Notify_IterationCompleted(actor, new List <Thing> {
                });
                actor.jobs.EndCurrentJob(JobCondition.Succeeded, false);
            };
            finalizeTraining.defaultCompleteMode = ToilCompleteMode.Instant;
            finalizeTraining.FailOnDespawnedOrNull(TargetIndex.A);
            yield return(finalizeTraining);

            //testing
            yield return(Toils_Reserve.Reserve(TargetIndex.B, 1, -1, null));

            Toil findPlaceTarget = Toils_Haul.CarryHauledThingToCell(TargetIndex.B);

            yield return(findPlaceTarget);

            yield return(Toils_Haul.PlaceHauledThingInCell(TargetIndex.B, findPlaceTarget, true, true));

            yield break;
        }