Example #1
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, 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, jobDriver_DoBill.BillGiver).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) >= 10000f && 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, null))
                        {
                            Log.Error(string.Concat(new object[]
                            {
                                actor,
                                " could not drop recipe product ",
                                list[i],
                                " near ",
                                actor.Position
                            }), false);
                        }
                    }
                    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, null))
                        {
                            Log.Error(string.Concat(new object[]
                            {
                                actor,
                                " could not drop recipe product ",
                                list[j],
                                " near ",
                                actor.Position
                            }), false);
                        }
                    }
                }
                IntVec3 invalid = IntVec3.Invalid;
                if (curJob.bill.GetStoreMode() == BillStoreModeDefOf.BestStockpile)
                {
                    StoreUtility.TryFindBestBetterStoreCellFor(list[0], actor, actor.Map, StoragePriority.Unstored, actor.Faction, out invalid, true);
                }
                else if (curJob.bill.GetStoreMode() == BillStoreModeDefOf.SpecificStockpile)
                {
                    StoreUtility.TryFindBestBetterStoreCellForIn(list[0], actor, actor.Map, StoragePriority.Unstored, actor.Faction, curJob.bill.GetStoreZone().slotGroup, out invalid, true);
                }
                else
                {
                    Log.ErrorOnce("Unknown store mode", 9158246, false);
                }
                if (invalid.IsValid)
                {
                    actor.carryTracker.TryStartCarry(list[0]);
                    curJob.targetB = invalid;
                    curJob.targetA = list[0];
                    curJob.count   = 99999;
                    return;
                }
                if (!GenPlace.TryPlaceThing(list[0], actor.Position, actor.Map, ThingPlaceMode.Near, null, null))
                {
                    Log.Error(string.Concat(new object[]
                    {
                        "Bill doer could not drop product ",
                        list[0],
                        " near ",
                        actor.Position
                    }), false);
                }
                actor.jobs.EndCurrentJob(JobCondition.Succeeded, true);
            };
            return(toil);
        }
Example #2
0
        public static Toil PlaceHauledThingInCell(TargetIndex cellInd, Toil nextToilOnPlaceFailOrIncomplete, bool storageMode, bool tryStoreInSameStorageIfSpotCantHoldWholeStack = false)
        {
            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(string.Concat(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 var _, placedAction))
                    {
                        if (storageMode)
                        {
                            if (nextToilOnPlaceFailOrIncomplete != null && ((tryStoreInSameStorageIfSpotCantHoldWholeStack && StoreUtility.TryFindBestBetterStoreCellForIn(actor.carryTracker.CarriedThing, actor, actor.Map, StoragePriority.Unstored, actor.Faction, cell.GetSlotGroup(actor.Map), out var foundCell)) || StoreUtility.TryFindBestBetterStoreCellFor(actor.carryTracker.CarriedThing, actor, actor.Map, StoragePriority.Unstored, actor.Faction, out 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(string.Concat("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();
                                }
                            }
                        }
        public static Toil FinishRecipeAndStartStoringCorpse(TargetIndex corpseIndex)
        {
            Toil toil = new Toil();

            toil.initAction = delegate
            {
                Pawn   actor  = toil.actor;
                Job    curJob = actor.jobs.curJob;
                Corpse corpse = actor.jobs.curJob.GetTarget(TargetIndex.B).Thing as Corpse;

                actor.skills.GetSkill(SkillDefOf.Medicine).Learn(Dissection.Singleton.ExpPerCorpse, Dissection.Singleton.IgnoreDailyLimit);

                ApplyThoughts(actor, corpse);
                RecordTale(actor, corpse);

                bool destroyedBody = RemoveDissectedBodyParts(actor, corpse);

                curJob.bill.Notify_IterationCompleted(actor, new List <Thing>()
                {
                    corpse
                });
                RecordsUtility.Notify_BillDone(actor, new List <Thing>()
                {
                    corpse
                });

                if (destroyedBody)
                {
                    actor.jobs.EndCurrentJob(JobCondition.Succeeded);
                    return;
                }

                IntVec3 bestStoreCell = IntVec3.Invalid;
                if (curJob.bill.GetStoreMode() == BillStoreModeDefOf.BestStockpile)
                {
                    StoreUtility.TryFindBestBetterStoreCellFor(corpse, actor, actor.Map, StoragePriority.Unstored, actor.Faction, out bestStoreCell, true);
                }
                else if (curJob.bill.GetStoreMode() == BillStoreModeDefOf.SpecificStockpile)
                {
                    StoreUtility.TryFindBestBetterStoreCellForIn(corpse, actor, actor.Map, StoragePriority.Unstored, actor.Faction, curJob.bill.GetStoreZone().slotGroup, out bestStoreCell, true);
                }
                else
                {
                    Log.ErrorOnce("Unknown store mode", 9158246, false);
                }

                if (bestStoreCell.IsValid)
                {
                    corpse.DeSpawn();
                    actor.carryTracker.TryStartCarry(corpse);
                    curJob.targetC = bestStoreCell;
                    curJob.targetB = corpse;
                    curJob.count   = 99999;

                    curJob.placedThings?.Clear();
                }
                else
                {
                    actor.jobs.EndCurrentJob(JobCondition.Succeeded);
                }
            };
            return(toil);
        }
Example #4
0
        } // end TryDropProductOnFloor

        /// <summary>
        /// Generates the recipe product, then looks for a valid cell in the Bill's output stockpile.
        /// If a valid cell is found, puts the product into the pawn's arms for transport in a future Toil.
        /// Uses code from the Toils_Recipe.FinishRecipeAndStartStoringProduct() toil in vanilla.
        /// </summary>
        /// <param name="vat"></param>
        /// <returns></returns>
        public static Toil StartCarryProductToStockpile(Building_GrowerBase_WorkTable vat)
        {
            Toil toil = new Toil();

            toil.initAction = delegate
            {
                Pawn actor  = toil.actor;
                Job  curJob = actor.jobs.curJob;

                //Skip null checking, as it was done in previous toil

                Thing product = ThingMaker.MakeThing(vat.activeRecipe.products[0].thingDef);
                product.stackCount = vat.activeRecipe.products[0].count;
                Bill_Production activeBill = vat.billProc.ActiveBill;

                //decrement billstack count
                if (activeBill.repeatMode == BillRepeatModeDefOf.RepeatCount)
                {
                    if (activeBill.repeatCount > 0)
                    {
                        activeBill.repeatCount--;
                    }
                }

                IntVec3 foundCell = IntVec3.Invalid;

                //find the best cell to put the product in
                if (activeBill.GetStoreMode() == BillStoreModeDefOf.BestStockpile)
                {
                    StoreUtility.TryFindBestBetterStoreCellFor(product, actor, actor.Map, StoragePriority.Unstored, actor.Faction, out foundCell);
                }
                else if (activeBill.GetStoreMode() == BillStoreModeDefOf.SpecificStockpile)
                {
                    StoreUtility.TryFindBestBetterStoreCellForIn(product, actor, actor.Map, StoragePriority.Unstored, actor.Faction,
                                                                 activeBill.GetStoreZone().slotGroup, out foundCell);
                }
                else
                {
                    Log.ErrorOnce("Unknown bill store mode", 9158246);
                }

                //if a cell was found in a stockpile, start a hauling job to move the product from the ground to that cell
                if (foundCell.IsValid)
                {
                    bool tryCarrySuccess = actor.carryTracker.TryStartCarry(product);
                    QEEMod.TryLog("Valid stockpile found - haul product to cell " + foundCell + ". TryStartCarry() result for "
                                  + actor.LabelShort + ": " + tryCarrySuccess);

                    curJob.targetB = foundCell;
                    curJob.targetA = product;
                    curJob.count   = 99999;

                    vat.Notify_ProductExtracted(actor);

                    //the next toil in the JobDriver will now haul the carried object to the stockpile
                }
                else
                {
                    QEEMod.TryLog("No stockpile found to haul " + product.Label + " to. Dropping product on ground.");
                    if (GenPlace.TryPlaceThing(product, actor.Position, actor.Map, ThingPlaceMode.Near))
                    {
                        vat.Notify_ProductExtracted(actor);
                    }
                    else
                    {
                        QEEMod.TryLog(actor + " could not drop recipe product " + product + " near " + actor.Position + ". Ending extract job.");
                    }

                    actor.jobs.EndCurrentJob(JobCondition.Succeeded);
                }
            };
            return(toil);
        } // end StartCarryProductToStockpile
Example #5
0
        public static Toil FinishRecipeAndStartStoringProduct()
        {
            Toil toil = new Toil();

            toil.initAction = () =>
            {
                var actor  = toil.actor;
                var curJob = actor.jobs.curJob;
                var driver = ((JobDriver_DoBill)actor.jobs.curDriver);

                //Learn (if the recipe doesn't use unfinished thing)
                if (curJob.RecipeDef.workSkill != null && !curJob.RecipeDef.UsesUnfinishedThing)
                {
                    float xp = driver.ticksSpentDoingRecipeWork * SkillTuning.XpPerTickRecipeBase * curJob.RecipeDef.workSkillLearnFactor;
                    actor.skills.GetSkill(curJob.RecipeDef.workSkill).Learn(xp);
                }

                //Calculate ingredients
                List <Thing> ingredients        = CalculateIngredients(curJob, actor);
                Thing        dominantIngredient = CalculateDominantIngredient(curJob, ingredients);

                //Make the products
                var products = GenRecipe.MakeRecipeProducts(curJob.RecipeDef, actor, ingredients, dominantIngredient, driver.BillGiver).ToList();

                //Consume the ingredients
                ConsumeIngredients(ingredients, curJob.RecipeDef, actor.Map);

                //Notify bill
                curJob.bill.Notify_IterationCompleted(actor, ingredients);

                //Add records
                RecordsUtility.Notify_BillDone(actor, products);

                //Add tale
                var uft = curJob.GetTarget(JobDriver_DoBill.IngredientInd).Thing as UnfinishedThing;
                if (curJob.bill.recipe.WorkAmountTotal(uft != null ? uft.Stuff : null) >= LongCraftingProjectThreshold && products.Count > 0)
                {
                    TaleRecorder.RecordTale(TaleDefOf.CompletedLongCraftingProject, actor, products[0].GetInnerIfMinified().def);
                }

                //----------------------------------------------------
                //Rearrange the job so the bill doer goes and stores the product
                //----------------------------------------------------

                //Nothing to store? End the job now
                if (products.Count == 0)
                {
                    actor.jobs.EndCurrentJob(JobCondition.Succeeded);
                    return;
                }

                //Bill is set to drop-on-floor mode?
                //Drop everything and end the job now
                if (curJob.bill.GetStoreMode() == BillStoreModeDefOf.DropOnFloor)
                {
                    for (int i = 0; i < products.Count; i++)
                    {
                        if (!GenPlace.TryPlaceThing(products[i], actor.Position, actor.Map, ThingPlaceMode.Near))
                        {
                            Log.Error(actor + " could not drop recipe product " + products[i] + " near " + actor.Position);
                        }
                    }

                    actor.jobs.EndCurrentJob(JobCondition.Succeeded);
                    return;
                }

                //Place all products except the first one on the ground
                if (products.Count > 1)
                {
                    for (int i = 1; i < products.Count; i++)
                    {
                        if (!GenPlace.TryPlaceThing(products[i], actor.Position, actor.Map, ThingPlaceMode.Near))
                        {
                            Log.Error(actor + " could not drop recipe product " + products[i] + " near " + actor.Position);
                        }
                    }
                }

                //Try find a cell to take the product to
                IntVec3 storeCell = IntVec3.Invalid;
                if (curJob.bill.GetStoreMode() == BillStoreModeDefOf.BestStockpile)
                {
                    StoreUtility.TryFindBestBetterStoreCellFor(products[0], actor, actor.Map, StoragePriority.Unstored, actor.Faction, out storeCell);
                }
                else if (curJob.bill.GetStoreMode() == BillStoreModeDefOf.SpecificStockpile)
                {
                    StoreUtility.TryFindBestBetterStoreCellForIn(products[0], actor, actor.Map, StoragePriority.Unstored, actor.Faction, curJob.bill.GetStoreZone().slotGroup, out storeCell);
                }
                else
                {
                    Log.ErrorOnce("Unknown store mode", 9158246);
                }

                if (storeCell.IsValid)
                {
                    //Start carrying the first product and proceed to the storage toils
                    actor.carryTracker.TryStartCarry(products[0]);

                    curJob.targetB = storeCell;
                    curJob.targetA = products[0];
                    curJob.count   = 99999;
                }
                else
                {
                    //No store cell? Drop the product; we're done.
                    if (!GenPlace.TryPlaceThing(products[0], actor.Position, actor.Map, ThingPlaceMode.Near))
                    {
                        Log.Error("Bill doer could not drop product " + products[0] + " near " + actor.Position);
                    }

                    actor.jobs.EndCurrentJob(JobCondition.Succeeded);
                    return;
                }
            };

            return(toil);
        }
        protected override IEnumerable <Toil> MakeNewToils()
        {
            Building_FishingSpot fishingSpot = this.job.GetTarget(FishingSpotIndex).Thing as Building_FishingSpot;

            int fishingDuration = (int)(baseFishingDuration * Rand.Range(0.2f, 1.8f) * fishingSpot.MapFishTracker.DifficultyMultiplier / (ModController.Settings.FishingEfficiency));

            Thing thingCaught = null;

            yield return(Toils_Goto.GotoThing(FishingSpotIndex, fishingSpot.InteractionCell)
                         .FailOnDespawnedNullOrForbidden(FishingSpotIndex));

            Toil fishToil = new Toil()
            {
                initAction = () =>
                {
                    if (Find.TickManager.TicksGame > fishingSpot.lastFishingStartTick + 60000 * fishingSpot.FishingFrequency)
                    {
                        fishingSpot.lastFishingStartTick = Find.TickManager.TicksGame;
                    }
                },
                tickAction = () => {
                    this.pawn.skills.Learn(job.def.joySkill, job.def.joyXpPerTick);

                    if (pawn.CurJob.GetTarget(FishingSpotIndex).IsValid)
                    {
                        pawn.rotationTracker.FaceCell(pawn.CurJob.GetTarget(FishingSpotIndex).Cell);
                    }
                },
                handlingFacing      = true,
                defaultDuration     = fishingDuration,
                defaultCompleteMode = ToilCompleteMode.Delay
            };

            yield return(fishToil.FailOnDespawnedNullOrForbidden(FishingSpotIndex));

            Toil catchFishToil = new Toil()
            {
                initAction = () =>
                {
                    string eventText;
                    if (Rand.Value < pawn.GetStatValue(ResourceBank.StatDefOf.FishingChance))
                    {
                        if (fishingSpot.FishStock > 0 && fishingSpot.FishByWeight.Count > 0)
                        {
                            FishDef fishDefToCatch = fishingSpot.FishByWeight.RandomElementByWeight(item => item.Item1).Item2;


                            if (fishDefToCatch.fishProperties.CanBite && Rand.Value < pawn.GetStatValue(ResourceBank.StatDefOf.FishBiteChance))
                            {
                                float damage = Rand.Range(fishDefToCatch.fishProperties.BiteDamageRange.min, fishDefToCatch.fishProperties.BiteDamageRange.max);

                                eventText = string.Format(ResourceBank.Strings.FishingTradegyText.Translate(), this.pawn.Name.ToStringShort.CapitalizeFirst(), fishDefToCatch.label);
                                Find.LetterStack.ReceiveLetter(ResourceBank.Strings.FishingTradegyTitle.Translate(), eventText, LetterDefOf.NegativeEvent, this.pawn);
                                this.pawn.TakeDamage(new DamageInfo(fishDefToCatch.fishProperties.BiteDamageDef, damage, 0f, -1f, this.pawn, null, null, DamageInfo.SourceCategory.ThingOrUnknown, this.pawn));
                                return;
                            }

                            fishingSpot.FishCaught();

                            bool roeFish = false;
                            if (fishDefToCatch.fishProperties.HasRoe && fishDefToCatch.fishProperties.RoeDef != null && fishDefToCatch.fishProperties.SpawningYearRange != null)
                            {
                                int day = GenDate.DayOfYear(Find.TickManager.TicksAbs, Find.WorldGrid.LongLatOf(this.Map.Tile).x);
                                if (fishDefToCatch.fishProperties.SpawningYearRange.min <= day && day <= fishDefToCatch.fishProperties.SpawningYearRange.max)
                                {
                                    if (Rand.Value < ModController.Settings.roeChance)
                                    {
                                        roeFish = true;
                                    }
                                }
                            }

                            if (roeFish)
                            {
                                thingCaught = ThingMaker.MakeThing(fishDefToCatch.fishProperties.RoeDef, null);
                            }
                            else
                            {
                                thingCaught = ThingMaker.MakeThing(fishDefToCatch, null);
                            }

                            thingCaught.stackCount = 1;
                            eventText = ResourceBank.Strings.FishingSuccess.Translate(this.pawn.Name.ToStringShort.CapitalizeFirst(), fishDefToCatch.label);

                            NotifyFishingSuccess(eventText);
                        }
                        else
                        if (Rand.Value < ModController.Settings.junkChance)
                        {
                            //catch non-fish
                            float treasureChance = ModController.Settings.treasureChanceStandart;
                            if (fishingSpot.DeepTerrain)
                            {
                                treasureChance *= treasureDeepAdditionalChance;
                            }

                            ThingSetMakerParams parms = default(ThingSetMakerParams);
                            parms.countRange = new IntRange(1, 1);

                            if (Rand.Value <= treasureChance)
                            {
                                parms.maxTotalMass          = ModController.Settings.MaxTreasureMass;
                                parms.totalMarketValueRange = new FloatRange(100.0f, ModController.Settings.treasureMaxValue);
                                parms.qualityGenerator      = QualityGenerator.Reward;

                                List <Thing> list = ThingSetMakerDefOf.Reward_ItemsStandard.root.Generate(parms);
                                thingCaught = list.RandomElement();

                                eventText = ResourceBank.Strings.FishingCaughtTreasureText.Translate(this.pawn.Name.ToStringShort.CapitalizeFirst(), thingCaught.def.label);
                                NotifyCaughtTreasure(eventText);
                            }
                            else
                            {
                                parms.maxTotalMass     = ModController.Settings.MaxJunkMass;
                                parms.qualityGenerator = QualityGenerator.BaseGen;

                                List <Thing> list = ResourceBank.ThingSetMakerDefOf.Fishing_ItemJunk.root.Generate(parms);
                                thingCaught = list.RandomElement();

                                eventText = ResourceBank.Strings.FishingCaughtJunkText.Translate(this.pawn.Name.ToStringShort.CapitalizeFirst(), thingCaught.def.label);
                                NotifyCaughtJunk(eventText);
                            }
                        }
                    }
                    else
                    {
                        eventText = ResourceBank.Strings.FishingCaughtNothingText.Translate(this.pawn.Name.ToStringShort.CapitalizeFirst());
                        MoteMaker.ThrowMetaIcon(this.pawn.Position, this.Map, ThingDefOf.Mote_IncapIcon);
                        NotifyCaughtNothing(eventText);
                        this.pawn.jobs.EndCurrentJob(JobCondition.Incompletable);
                        return;
                    }
                }
            };

            yield return(catchFishToil);

            //yield return FinishAndStartHaul(fishingCatch);

            Toil toilFinishAndStartHaul = new Toil();

            toilFinishAndStartHaul.initAction = delegate
            {
                Pawn actor  = toilFinishAndStartHaul.actor;
                Job  curJob = actor.jobs.curJob;
                Bill bill   = curJob.bill;

                Log.Message(bill.recipe.defName);
                Log.Message(thingCaught.def.defName);

                if (curJob.bill.GetStoreMode() == BillStoreModeDefOf.DropOnFloor)
                {
                    if (!GenPlace.TryPlaceThing(thingCaught, actor.Position, actor.Map, ThingPlaceMode.Near))
                    {
                        Log.Error(actor + " could not drop recipe product " + thingCaught + " near " + actor.Position);
                    }

                    actor.jobs.EndCurrentJob(JobCondition.Succeeded);
                }
                else
                {
                    IntVec3 foundCell = IntVec3.Invalid;
                    if (curJob.bill.GetStoreMode() == BillStoreModeDefOf.BestStockpile)
                    {
                        StoreUtility.TryFindBestBetterStoreCellFor(thingCaught, actor, actor.Map, StoragePriority.Unstored, actor.Faction, out foundCell);
                    }
                    else if (curJob.bill.GetStoreMode() == BillStoreModeDefOf.SpecificStockpile)
                    {
                        if (curJob.bill.GetStoreZone().Accepts(thingCaught))
                        {
                            StoreUtility.TryFindBestBetterStoreCellForIn(thingCaught, actor, actor.Map, StoragePriority.Unstored, actor.Faction, curJob.bill.GetStoreZone().slotGroup, out foundCell);
                        }
                        else
                        {
                            if (!GenPlace.TryPlaceThing(thingCaught, actor.Position, actor.Map, ThingPlaceMode.Near))
                            {
                                Log.Error(actor + " could not drop recipe product " + thingCaught + " near " + actor.Position);
                            }
                            actor.jobs.EndCurrentJob(JobCondition.Succeeded);
                        }
                    }
                    else
                    {
                        Log.ErrorOnce("Unknown store mode", 9158246);
                    }

                    if (foundCell.IsValid)
                    {
                        actor.carryTracker.TryStartCarry(thingCaught);
                        curJob.SetTarget(HaulableInd, thingCaught);
                        curJob.SetTarget(StoreCellInd, foundCell);
                        curJob.count = 99999;
                    }
                    else
                    {
                        if (!GenPlace.TryPlaceThing(thingCaught, actor.Position, actor.Map, ThingPlaceMode.Near))
                        {
                            Log.Error("Bill doer could not drop product " + thingCaught + " near " + actor.Position);
                        }
                        actor.jobs.EndCurrentJob(JobCondition.Succeeded);
                    }
                }
            };
            yield return(toilFinishAndStartHaul);

            yield return(Toils_Reserve.Reserve(StoreCellInd));

            Toil carryToCell = Toils_Haul.CarryHauledThingToCell(StoreCellInd);

            yield return(carryToCell);

            yield return(Toils_Haul.PlaceHauledThingInCell(StoreCellInd, carryToCell, storageMode: true, tryStoreInSameStorageIfSpotCantHoldWholeStack: 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)
                {
                    Map.resourceCounter.UpdateResourceCounts();
                }
            };
            yield return(recount);
        }