Пример #1
0
        public static Toil DoRecipeWork()
        {
            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;
                UnfinishedThing  unfinishedThing  = curJob.GetTarget(TargetIndex.B).Thing as UnfinishedThing;
                if (unfinishedThing != null && unfinishedThing.Initialized)
                {
                    jobDriver_DoBill.workLeft = unfinishedThing.workLeft;
                }
                else
                {
                    jobDriver_DoBill.workLeft = curJob.bill.recipe.WorkAmountTotal((unfinishedThing == null) ? null : unfinishedThing.Stuff);
                    if (unfinishedThing != null)
                    {
                        unfinishedThing.workLeft = jobDriver_DoBill.workLeft;
                    }
                }
                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;
                UnfinishedThing  unfinishedThing  = curJob.GetTarget(TargetIndex.B).Thing as UnfinishedThing;
                if (unfinishedThing != null && unfinishedThing.Destroyed)
                {
                    actor.jobs.EndCurrentJob(JobCondition.Incompletable, true);
                    return;
                }
                jobDriver_DoBill.ticksSpentDoingRecipeWork++;
                curJob.bill.Notify_PawnDidWork(actor);
                IBillGiverWithTickAction billGiverWithTickAction = toil.actor.CurJob.GetTarget(TargetIndex.A).Thing as IBillGiverWithTickAction;
                if (billGiverWithTickAction != null)
                {
                    billGiverWithTickAction.UsedThisTick();
                }
                if (curJob.RecipeDef.workSkill != null && curJob.RecipeDef.UsesUnfinishedThing)
                {
                    actor.skills.GetSkill(curJob.RecipeDef.workSkill).Learn(0.11f * curJob.RecipeDef.workSkillLearnFactor, false);
                }
                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;
                if (unfinishedThing != null)
                {
                    unfinishedThing.workLeft = jobDriver_DoBill.workLeft;
                }
                actor.GainComfortFromCellIfPossible();
                if (jobDriver_DoBill.workLeft <= 0f)
                {
                    jobDriver_DoBill.ReadyForNextToil();
                }
                if (curJob.bill.recipe.UsesUnfinishedThing)
                {
                    int num2 = Find.TickManager.TicksGame - jobDriver_DoBill.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, delegate
            {
                Pawn actor = toil.actor;
                Job curJob = actor.CurJob;
                UnfinishedThing unfinishedThing = curJob.GetTarget(TargetIndex.B).Thing as UnfinishedThing;
                return(1f - ((JobDriver_DoBill)actor.jobs.curDriver).workLeft / curJob.bill.recipe.WorkAmountTotal((unfinishedThing == null) ? null : unfinishedThing.Stuff));
            }, false, -0.5f);
            toil.FailOn(() => toil.actor.CurJob.bill.suspended);
            return(toil);
        }
Пример #2
0
        public static bool __Prefix(Pawn pawn, TargetIndex ingestibleInd, ref Toil __result)
        {
            if (!TableDiner.settings.useExtraFeatures)
            {
                return(true);
            }
            Toil toil = new Verse.AI.Toil();

            toil.initAction = delegate
            {
                Pawn              actor              = toil.actor;
                IntVec3           intVec             = IntVec3.Invalid;
                Thing             thing              = null;
                Thing             thing2             = actor.CurJob.GetTarget(ingestibleInd).Thing;
                Predicate <Thing> baseChairValidator = delegate(Thing t)
                {
                    bool result;
                    if (t.def.building == null || !t.def.building.isSittable)
                    {
                        result = false;
                    }
                    else if (t.IsForbidden(pawn))
                    {
                        result = false;
                    }
                    else if (!actor.CanReserve(t, 1, -1, null, false))
                    {
                        result = false;
                    }
                    else if (!t.IsSociallyProper(actor))
                    {
                        result = false;
                    }
                    else if (t.IsBurning())
                    {
                        result = false;
                    }
                    else if (t.HostileTo(pawn))
                    {
                        result = false;
                    }
                    else
                    {
                        bool flag = false;
                        for (int i = 0; i < 4; i++)
                        {
                            IntVec3  c       = t.Position + GenAdj.CardinalDirections[i];
                            Building edifice = c.GetEdifice(t.Map);
                            if (edifice != null && edifice.def.surfaceType == SurfaceType.Eat)
                            {
                                float tr = TableDinerGlobal.GetTableRadius(edifice.ThingID);
                                float pr = TableDinerGlobal.GetTableRadius(actor.ThingID);

                                if (tr >= 1 || pr >= 1)
                                {
                                    float r2 = (edifice.TrueCenter() - actor.TrueCenter()).sqrMagnitude;
                                    if (tr < 1)
                                    {
                                        if (r2 <= Mathf.Pow(pr, 2))
                                        {
                                            flag = true;
                                            break;
                                        }
                                    }
                                    else if (pr < 1)
                                    {
                                        if (r2 <= Mathf.Pow(tr, 2))
                                        {
                                            flag = true;
                                            break;
                                        }
                                    }
                                    else
                                    {
                                        if (r2 <= Mathf.Pow(Mathf.Min(tr, pr), 2))
                                        {
                                            flag = true;
                                            break;
                                        }
                                    }
                                }
                                else
                                {
                                    flag = true;
                                    break;
                                }
                            }
                        }
                        result = flag;
                    }
                    return(result);
                };
                if (thing2.def.ingestible.chairSearchRadius > 0f)
                {
                    thing = GenClosest.ClosestThingReachable(actor.Position, actor.Map, ThingRequest.ForGroup(ThingRequestGroup.BuildingArtificial), PathEndMode.OnCell, TraverseParms.For(actor, Danger.Deadly, TraverseMode.ByPawn, false), thing2.def.ingestible.chairSearchRadius, (Thing t) => baseChairValidator(t) && t.Position.GetDangerFor(pawn, t.Map) == Danger.None, null, 0, -1, false, RegionType.Set_Passable, false);
                }
                if (thing == null)
                {
                    intVec = RCellFinder.SpotToChewStandingNear(actor, actor.CurJob.GetTarget(ingestibleInd).Thing);
                    Danger chewSpotDanger = intVec.GetDangerFor(pawn, actor.Map);
                    if (chewSpotDanger != Danger.None)
                    {
                        thing = GenClosest.ClosestThingReachable(actor.Position, actor.Map, ThingRequest.ForGroup(ThingRequestGroup.BuildingArtificial), PathEndMode.OnCell, TraverseParms.For(actor, Danger.Deadly, TraverseMode.ByPawn, false), thing2.def.ingestible.chairSearchRadius, (Thing t) => baseChairValidator(t) && t.Position.GetDangerFor(pawn, t.Map) <= chewSpotDanger, null, 0, -1, false, RegionType.Set_Passable, false);
                    }
                }
                if (thing != null)
                {
                    intVec = thing.Position;
                    actor.Reserve(thing, actor.CurJob, 1, -1, null);
                }
                actor.Map.pawnDestinationReservationManager.Reserve(actor, actor.CurJob, intVec);
                actor.pather.StartPath(intVec, PathEndMode.OnCell);
            };
            toil.defaultCompleteMode = ToilCompleteMode.PatherArrival;
            __result = toil;
            return(false);
        }
        protected override IEnumerable <Toil> MakeNewToils()
        {
            base.AddEndCondition(delegate
            {
                Thing thing = base.GetActor().jobs.curJob.GetTarget(TargetIndex.A).Thing;
                JobCondition result;
                if (thing is Building && !thing.Spawned)
                {
                    result = JobCondition.Incompletable;
                }
                else
                {
                    result = JobCondition.Ongoing;
                }
                return(result);
            });
            this.FailOnBurningImmobile(TargetIndex.A);
            this.FailOn(delegate()
            {
                IBillGiver billGiver = this.job.GetTarget(TargetIndex.A).Thing as IBillGiver;
                if (billGiver != null)
                {
                    if (this.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 (this.job.targetQueueB != null && this.job.targetQueueB.Count == 1)
                    {
                        UnfinishedThing unfinishedThing = this.job.targetQueueB[0].Thing as UnfinishedThing;
                        if (unfinishedThing != null)
                        {
                            unfinishedThing.BoundBill = (Bill_ProductionWithUft)this.job.bill;
                        }
                    }
                }
            });

            yield return(Toils_Jump.JumpIf(gotoBillGiver, () => this.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);

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

            yield return(JobDriver_DoBill.JumpToCollectNextIntoHandsForBill(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);

            yield return(Toils_Recipe.MakeUnfinishedThingIfNeeded());

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

            yield return(Toils_Recipe.FinishRecipeAndStartStoringProduct());

            if (!this.job.RecipeDef.products.NullOrEmpty <ThingDefCountClass>() || !this.job.RecipeDef.specialProducts.NullOrEmpty <SpecialProductType>())
            {
                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)
                    {
                        this.Map.resourceCounter.UpdateResourceCounts();
                    }
                };
                yield return(recount);
            }
            yield break;
        }
Пример #4
0
        public static Toil FinishRecipeAndStartStoringProduct()
        {
            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;
                if (curJob.RecipeDef.workSkill != null && !curJob.RecipeDef.UsesUnfinishedThing)
                {
                    float xp = (float)jobDriver_DoBill.ticksSpentDoingRecipeWork * 0.11f * curJob.RecipeDef.workSkillLearnFactor;
                    actor.skills.GetSkill(curJob.RecipeDef.workSkill).Learn(xp, false);
                }
                List <Thing> ingredients        = Toils_Recipe.CalculateIngredients(curJob, actor);
                Thing        dominantIngredient = Toils_Recipe.CalculateDominantIngredient(curJob, ingredients);
                List <Thing> list = GenRecipe.MakeRecipeProducts(curJob.RecipeDef, actor, ingredients, dominantIngredient).ToList <Thing>();
                Toils_Recipe.ConsumeIngredients(ingredients, curJob.RecipeDef, actor.Map);
                curJob.bill.Notify_IterationCompleted(actor, ingredients);
                RecordsUtility.Notify_BillDone(actor, list);
                UnfinishedThing unfinishedThing = curJob.GetTarget(TargetIndex.B).Thing as UnfinishedThing;
                if (curJob.bill.recipe.WorkAmountTotal((unfinishedThing == null) ? null : unfinishedThing.Stuff) >= 20000f && list.Count > 0)
                {
                    TaleRecorder.RecordTale(TaleDefOf.CompletedLongCraftingProject, new object[]
                    {
                        actor,
                        list[0].def
                    });
                }
                if (list.Count == 0)
                {
                    actor.jobs.EndCurrentJob(JobCondition.Succeeded, true);
                    return;
                }
                if (curJob.bill.GetStoreMode() == BillStoreModeDefOf.DropOnFloor)
                {
                    for (int i = 0; i < list.Count; i++)
                    {
                        if (!GenPlace.TryPlaceThing(list[i], actor.Position, actor.Map, ThingPlaceMode.Near, null))
                        {
                            Log.Error(string.Concat(new object[]
                            {
                                actor,
                                " could not drop recipe product ",
                                list[i],
                                " near ",
                                actor.Position
                            }));
                        }
                    }
                    actor.jobs.EndCurrentJob(JobCondition.Succeeded, true);
                    return;
                }
                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(string.Concat(new object[]
                            {
                                actor,
                                " could not drop recipe product ",
                                list[j],
                                " near ",
                                actor.Position
                            }));
                        }
                    }
                }
                list[0].SetPositionDirect(actor.Position);
                IntVec3 c;
                if (StoreUtility.TryFindBestBetterStoreCellFor(list[0], actor, actor.Map, StoragePriority.Unstored, actor.Faction, out c, true))
                {
                    actor.carryTracker.TryStartCarry(list[0]);
                    curJob.targetB = c;
                    curJob.targetA = list[0];
                    curJob.count   = 99999;
                    return;
                }
                if (!GenPlace.TryPlaceThing(list[0], actor.Position, actor.Map, ThingPlaceMode.Near, null))
                {
                    Log.Error(string.Concat(new object[]
                    {
                        "Bill doer could not drop product ",
                        list[0],
                        " near ",
                        actor.Position
                    }));
                }
                actor.jobs.EndCurrentJob(JobCondition.Succeeded, true);
            };
            return(toil);
        }
            public bool MoveNext()
            {
                uint num = (uint)this.$PC;

                this.$PC = -1;
                switch (num)
                {
                case 0u:
                {
                    base.AddEndCondition(delegate
                        {
                            Thing thing = base.GetActor().jobs.curJob.GetTarget(TargetIndex.A).Thing;
                            JobCondition result;
                            if (thing is Building && !thing.Spawned)
                            {
                                result = JobCondition.Incompletable;
                            }
                            else
                            {
                                result = JobCondition.Ongoing;
                            }
                            return(result);
                        });
                    this.FailOnBurningImmobile(TargetIndex.A);
                    this.FailOn(delegate()
                        {
                            IBillGiver billGiver = this.job.GetTarget(TargetIndex.A).Thing as IBillGiver;
                            if (billGiver != null)
                            {
                                if (this.job.bill.DeletedOrDereferenced)
                                {
                                    return(true);
                                }
                                if (!billGiver.CurrentlyUsableForBills())
                                {
                                    return(true);
                                }
                            }
                            return(false);
                        });
                    gotoBillGiver = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell);
                    Toil bind = new Toil();
                    bind.initAction = delegate()
                    {
                        if (this.job.targetQueueB != null && this.job.targetQueueB.Count == 1)
                        {
                            UnfinishedThing unfinishedThing = this.job.targetQueueB[0].Thing as UnfinishedThing;
                            if (unfinishedThing != null)
                            {
                                unfinishedThing.BoundBill = (Bill_ProductionWithUft)this.job.bill;
                            }
                        }
                    };
                    this.$current = bind;
                    if (!this.$disposing)
                    {
                        this.$PC = 1;
                    }
                    return(true);
                }

                case 1u:
                    this.$current = Toils_Jump.JumpIf(gotoBillGiver, () => this.job.GetTargetQueue(TargetIndex.B).NullOrEmpty <LocalTargetInfo>());
                    if (!this.$disposing)
                    {
                        this.$PC = 2;
                    }
                    return(true);

                case 2u:
                    extract       = Toils_JobTransforms.ExtractNextTargetFromQueue(TargetIndex.B, true);
                    this.$current = extract;
                    if (!this.$disposing)
                    {
                        this.$PC = 3;
                    }
                    return(true);

                case 3u:
                    getToHaulTarget = Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(TargetIndex.B).FailOnSomeonePhysicallyInteracting(TargetIndex.B);
                    this.$current   = getToHaulTarget;
                    if (!this.$disposing)
                    {
                        this.$PC = 4;
                    }
                    return(true);

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

                case 5u:
                    this.$current = JobDriver_DoBill.JumpToCollectNextIntoHandsForBill(getToHaulTarget, TargetIndex.B);
                    if (!this.$disposing)
                    {
                        this.$PC = 6;
                    }
                    return(true);

                case 6u:
                    this.$current = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell).FailOnDestroyedOrNull(TargetIndex.B);
                    if (!this.$disposing)
                    {
                        this.$PC = 7;
                    }
                    return(true);

                case 7u:
                    findPlaceTarget = Toils_JobTransforms.SetTargetToIngredientPlaceCell(TargetIndex.A, TargetIndex.B, TargetIndex.C);
                    this.$current   = findPlaceTarget;
                    if (!this.$disposing)
                    {
                        this.$PC = 8;
                    }
                    return(true);

                case 8u:
                    this.$current = Toils_Haul.PlaceHauledThingInCell(TargetIndex.C, findPlaceTarget, false);
                    if (!this.$disposing)
                    {
                        this.$PC = 9;
                    }
                    return(true);

                case 9u:
                    this.$current = Toils_Jump.JumpIfHaveTargetInQueue(TargetIndex.B, extract);
                    if (!this.$disposing)
                    {
                        this.$PC = 10;
                    }
                    return(true);

                case 10u:
                    this.$current = gotoBillGiver;
                    if (!this.$disposing)
                    {
                        this.$PC = 11;
                    }
                    return(true);

                case 11u:
                    this.$current = Toils_Recipe.MakeUnfinishedThingIfNeeded();
                    if (!this.$disposing)
                    {
                        this.$PC = 12;
                    }
                    return(true);

                case 12u:
                    this.$current = Toils_Recipe.DoRecipeWork().FailOnDespawnedNullOrForbiddenPlacedThings().FailOnCannotTouch(TargetIndex.A, PathEndMode.InteractionCell);
                    if (!this.$disposing)
                    {
                        this.$PC = 13;
                    }
                    return(true);

                case 13u:
                    this.$current = Toils_Recipe.FinishRecipeAndStartStoringProduct();
                    if (!this.$disposing)
                    {
                        this.$PC = 14;
                    }
                    return(true);

                case 14u:
                    if (!this.job.RecipeDef.products.NullOrEmpty <ThingDefCountClass>() || !this.job.RecipeDef.specialProducts.NullOrEmpty <SpecialProductType>())
                    {
                        this.$current = Toils_Reserve.Reserve(TargetIndex.B, 1, -1, null);
                        if (!this.$disposing)
                        {
                            this.$PC = 15;
                        }
                        return(true);
                    }
                    break;

                case 15u:
                    carryToCell   = Toils_Haul.CarryHauledThingToCell(TargetIndex.B);
                    this.$current = carryToCell;
                    if (!this.$disposing)
                    {
                        this.$PC = 16;
                    }
                    return(true);

                case 16u:
                    this.$current = Toils_Haul.PlaceHauledThingInCell(TargetIndex.B, carryToCell, true);
                    if (!this.$disposing)
                    {
                        this.$PC = 17;
                    }
                    return(true);

                case 17u:
                    < MakeNewToils > c__AnonStorey.recount            = new Toil();
                    < MakeNewToils > c__AnonStorey.recount.initAction = delegate()
                    {
                        Bill_Production bill_Production = < MakeNewToils > c__AnonStorey.recount.actor.jobs.curJob.bill as Bill_Production;
                        if (bill_Production != null && bill_Production.repeatMode == BillRepeatModeDefOf.TargetCount)
                        {
                            < MakeNewToils > c__AnonStorey.< > f__ref$0.$this.Map.resourceCounter.UpdateResourceCounts();
                        }
Пример #6
0
 public virtual void DecorateWaitToil(Toil wait)
 {
 }
Пример #7
0
        public static Toil StartCarryThing(TargetIndex haulableInd, bool putRemainderInQueue = false, bool subtractNumTakenFromJobCount = false, bool failIfStackCountLessThanJobCount = false)
        {
            Toil toil = new Toil();

            toil.initAction = delegate
            {
                Pawn  actor  = toil.actor;
                Job   curJob = actor.jobs.curJob;
                Thing thing  = curJob.GetTarget(haulableInd).Thing;
                if (!ErrorCheckForCarry(actor, thing))
                {
                    if (curJob.count == 0)
                    {
                        throw new Exception("StartCarryThing job had count = " + curJob.count + ". Job: " + curJob);
                    }
                    int num = actor.carryTracker.AvailableStackSpace(thing.def);
                    if (num == 0)
                    {
                        throw new Exception("StartCarryThing got availableStackSpace " + num + " for haulTarg " + thing + ". Job: " + curJob);
                    }
                    if (failIfStackCountLessThanJobCount && thing.stackCount < curJob.count)
                    {
                        actor.jobs.curDriver.EndJobWith(JobCondition.Incompletable);
                    }
                    else
                    {
                        int num2 = Mathf.Min(curJob.count, num, thing.stackCount);
                        if (num2 <= 0)
                        {
                            throw new Exception("StartCarryThing desiredNumToTake = " + num2);
                        }
                        int stackCount = thing.stackCount;
                        int num3       = actor.carryTracker.TryStartCarry(thing, num2);
                        if (num3 == 0)
                        {
                            actor.jobs.EndCurrentJob(JobCondition.Incompletable);
                        }
                        if (num3 < stackCount)
                        {
                            int num4 = curJob.count - num3;
                            if (putRemainderInQueue && num4 > 0)
                            {
                                curJob.GetTargetQueue(haulableInd).Insert(0, thing);
                                if (curJob.countQueue == null)
                                {
                                    curJob.countQueue = new List <int>();
                                }
                                curJob.countQueue.Insert(0, num4);
                            }
                            else if (actor.Map.reservationManager.ReservedBy(thing, actor, curJob))
                            {
                                actor.Map.reservationManager.Release(thing, actor, curJob);
                            }
                        }
                        if (subtractNumTakenFromJobCount)
                        {
                            curJob.count -= num3;
                        }
                        curJob.SetTarget(haulableInd, actor.carryTracker.CarriedThing);
                        actor.records.Increment(RecordDefOf.ThingsHauled);
                    }
                }
            };
            return(toil);
        }
Пример #8
0
        public static Toil PlaceHauledThingInCell(TargetIndex cellInd, Toil nextToilOnPlaceFailOrIncomplete, bool storageMode)
        {
            Toil toil = new Toil();

            toil.initAction = delegate
            {
                Pawn    actor  = toil.actor;
                Job     curJob = actor.jobs.curJob;
                IntVec3 cell   = curJob.GetTarget(cellInd).Cell;
                if (actor.carryTracker.CarriedThing == null)
                {
                    Log.Error(actor + " tried to place hauled thing in cell but is not hauling anything.");
                }
                else
                {
                    SlotGroup slotGroup = actor.Map.haulDestinationManager.SlotGroupAt(cell);
                    if (slotGroup != null && slotGroup.Settings.AllowedToAccept(actor.carryTracker.CarriedThing))
                    {
                        actor.Map.designationManager.TryRemoveDesignationOn(actor.carryTracker.CarriedThing, DesignationDefOf.Haul);
                    }
                    Action <Thing, int> placedAction = null;
                    if (curJob.def == JobDefOf.DoBill || curJob.def == JobDefOf.RefuelAtomic || curJob.def == JobDefOf.RearmTurretAtomic)
                    {
                        placedAction = delegate(Thing th, int added)
                        {
                            if (curJob.placedThings == null)
                            {
                                curJob.placedThings = new List <ThingCountClass>();
                            }
                            ThingCountClass thingCountClass = curJob.placedThings.Find((ThingCountClass x) => x.thing == th);
                            if (thingCountClass != null)
                            {
                                thingCountClass.Count += added;
                            }
                            else
                            {
                                curJob.placedThings.Add(new ThingCountClass(th, added));
                            }
                        };
                    }
                    if (!actor.carryTracker.TryDropCarriedThing(cell, ThingPlaceMode.Direct, out Thing _, placedAction))
                    {
                        if (storageMode)
                        {
                            if (nextToilOnPlaceFailOrIncomplete != null && StoreUtility.TryFindBestBetterStoreCellFor(actor.carryTracker.CarriedThing, actor, actor.Map, StoragePriority.Unstored, actor.Faction, out IntVec3 foundCell))
                            {
                                if (actor.CanReserve(foundCell))
                                {
                                    actor.Reserve(foundCell, actor.CurJob);
                                }
                                actor.CurJob.SetTarget(cellInd, foundCell);
                                actor.jobs.curDriver.JumpToToil(nextToilOnPlaceFailOrIncomplete);
                            }
                            else
                            {
                                Job job = HaulAIUtility.HaulAsideJobFor(actor, actor.carryTracker.CarriedThing);
                                if (job != null)
                                {
                                    curJob.targetA = job.targetA;
                                    curJob.targetB = job.targetB;
                                    curJob.targetC = job.targetC;
                                    curJob.count   = job.count;
                                    curJob.haulOpportunisticDuplicates = job.haulOpportunisticDuplicates;
                                    curJob.haulMode = job.haulMode;
                                    actor.jobs.curDriver.JumpToToil(nextToilOnPlaceFailOrIncomplete);
                                }
                                else
                                {
                                    Log.Error("Incomplete haul for " + actor + ": Could not find anywhere to put " + actor.carryTracker.CarriedThing + " near " + actor.Position + ". Destroying. This should never happen!");
                                    actor.carryTracker.CarriedThing.Destroy();
                                }
                            }
                        }
                        else if (nextToilOnPlaceFailOrIncomplete != null)
                        {
                            actor.jobs.curDriver.JumpToToil(nextToilOnPlaceFailOrIncomplete);
                        }
                    }
                }
            };
            return(toil);
        }
Пример #9
0
        public static Toil FinishRecipeAndStartStoringProduct()
        {
            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;
                if (curJob.RecipeDef.workSkill != null && !curJob.RecipeDef.UsesUnfinishedThing)
                {
                    float xp = (float)jobDriver_DoBill.ticksSpentDoingRecipeWork * 0.1f * curJob.RecipeDef.workSkillLearnFactor;
                    actor.skills.GetSkill(curJob.RecipeDef.workSkill).Learn(xp);
                }
                List <Thing> ingredients        = CalculateIngredients(curJob, actor);
                Thing        dominantIngredient = CalculateDominantIngredient(curJob, ingredients);
                List <Thing> list = GenRecipe.MakeRecipeProducts(curJob.RecipeDef, actor, ingredients, dominantIngredient, jobDriver_DoBill.BillGiver).ToList();
                ConsumeIngredients(ingredients, curJob.RecipeDef, actor.Map);
                curJob.bill.Notify_IterationCompleted(actor, ingredients);
                RecordsUtility.Notify_BillDone(actor, list);
                UnfinishedThing unfinishedThing = curJob.GetTarget(TargetIndex.B).Thing as UnfinishedThing;
                if (curJob.bill.recipe.WorkAmountTotal(unfinishedThing?.Stuff) >= 10000f && list.Count > 0)
                {
                    TaleRecorder.RecordTale(TaleDefOf.CompletedLongCraftingProject, actor, list[0].GetInnerIfMinified().def);
                }
                if (list.Count == 0)
                {
                    actor.jobs.EndCurrentJob(JobCondition.Succeeded);
                }
                else if (curJob.bill.GetStoreMode() == BillStoreModeDefOf.DropOnFloor)
                {
                    for (int i = 0; i < list.Count; i++)
                    {
                        if (!GenPlace.TryPlaceThing(list[i], actor.Position, actor.Map, ThingPlaceMode.Near))
                        {
                            Log.Error(actor + " could not drop recipe product " + list[i] + " near " + actor.Position);
                        }
                    }
                    actor.jobs.EndCurrentJob(JobCondition.Succeeded);
                }
                else
                {
                    if (list.Count > 1)
                    {
                        for (int j = 1; j < list.Count; j++)
                        {
                            if (!GenPlace.TryPlaceThing(list[j], actor.Position, actor.Map, ThingPlaceMode.Near))
                            {
                                Log.Error(actor + " could not drop recipe product " + list[j] + " near " + actor.Position);
                            }
                        }
                    }
                    IntVec3 foundCell = IntVec3.Invalid;
                    if (curJob.bill.GetStoreMode() == BillStoreModeDefOf.BestStockpile)
                    {
                        StoreUtility.TryFindBestBetterStoreCellFor(list[0], actor, actor.Map, StoragePriority.Unstored, actor.Faction, out foundCell);
                    }
                    else if (curJob.bill.GetStoreMode() == BillStoreModeDefOf.SpecificStockpile)
                    {
                        StoreUtility.TryFindBestBetterStoreCellForIn(list[0], actor, actor.Map, StoragePriority.Unstored, actor.Faction, curJob.bill.GetStoreZone().slotGroup, out foundCell);
                    }
                    else
                    {
                        Log.ErrorOnce("Unknown store mode", 9158246);
                    }
                    if (foundCell.IsValid)
                    {
                        actor.carryTracker.TryStartCarry(list[0]);
                        curJob.targetB = foundCell;
                        curJob.targetA = list[0];
                        curJob.count   = 99999;
                    }
                    else
                    {
                        if (!GenPlace.TryPlaceThing(list[0], actor.Position, actor.Map, ThingPlaceMode.Near))
                        {
                            Log.Error("Bill doer could not drop product " + list[0] + " near " + actor.Position);
                        }
                        actor.jobs.EndCurrentJob(JobCondition.Succeeded);
                    }
                }
            };
            return(toil);
        }