public ManagerJobProduction(RecipeDef recipe)
 {
     Bill = recipe.UsesUnfinishedThing ? new Bill_ProductionWithUft(recipe) : new Bill_Production(recipe);
     MainProduct = new MainProductTracker(Bill.recipe);
     Trigger = new TriggerThreshold(this);
     BillGivers = new BillGiverTracker(this);
 }
        public ManagerJob_Production( RecipeDef recipe )
        {
            Bill = recipe.UsesUnfinishedThing ? new Bill_ProductionWithUft( recipe ) : new Bill_Production( recipe );
            _hasMeaningfulIngredientChoices = Dialog_CreateJobsForIngredients.HasPrerequisiteChoices( recipe );
            MainProduct = new MainProductTracker( Bill.recipe );
            Trigger = new Trigger_Threshold( this );
            BillGivers = new BillGiverTracker( this );

            History = new History( new[] { Trigger.ThresholdFilter.Summary } );
        }
Example #3
0
 public override string ProductsDescription(Bill_Production bill)
 {
     return(ThingCategoryDefOf.ResourcesRaw.label);
 }
        protected override IEnumerable <Toil> MakeNewToils()
        {
            base.AddEndCondition(delegate
            {
                Thing thing = this.$this.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 = this.$this.job.GetTarget(TargetIndex.A).Thing as IBillGiver;
                if (billGiver != null)
                {
                    if (this.$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.$this.job.targetQueueB != null && this.$this.job.targetQueueB.Count == 1)
                    {
                        UnfinishedThing unfinishedThing = this.$this.job.targetQueueB[0].Thing as UnfinishedThing;
                        if (unfinishedThing != null)
                        {
                            unfinishedThing.BoundBill = (Bill_ProductionWithUft)this.$this.job.bill;
                        }
                    }
                }
            });

            yield return(Toils_Jump.JumpIf(gotoBillGiver, () => this.$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.$this.Map.resourceCounter.UpdateResourceCounts();
                    }
                };
                yield return(recount);
            }
        }
        public void MirrorBills(Bill_Production sourceBill, Bill_Production destinationBill, bool preserveTargetProduct)
        {
            if (!preserveTargetProduct || DoFiltersMatch(sourceBill, destinationBill))
            {
                if (sourceBill.ingredientFilter != null)
                {
                    destinationBill.ingredientFilter?.CopyAllowancesFrom(sourceBill.ingredientFilter);
                }
            }

            destinationBill.ingredientSearchRadius = sourceBill.ingredientSearchRadius;
            destinationBill.allowedSkillRange      = sourceBill.allowedSkillRange;
            destinationBill.SetStoreMode(sourceBill.GetStoreMode(), sourceBill.GetStoreZone());
            destinationBill.paused          = sourceBill.paused;
            destinationBill.pawnRestriction = sourceBill.pawnRestriction;

            if (Main.Instance.ShouldMirrorSuspendedStatus())
            {
                destinationBill.suspended = sourceBill.suspended;
            }

            var outputCanBeFiltered =
                CanOutputBeFiltered(destinationBill) ||
                destinationBill.recipe?.WorkerCounter is RecipeWorkerCounter_MakeStoneBlocks;

            if (sourceBill.repeatMode != BillRepeatModeDefOf.TargetCount || outputCanBeFiltered)
            {
                destinationBill.repeatMode = sourceBill.repeatMode;
            }

            if (outputCanBeFiltered)
            {
                destinationBill.repeatCount        = sourceBill.repeatCount;
                destinationBill.targetCount        = sourceBill.targetCount;
                destinationBill.pauseWhenSatisfied = sourceBill.pauseWhenSatisfied;
                destinationBill.unpauseWhenYouHave = sourceBill.unpauseWhenYouHave;
                destinationBill.includeFromZone    = sourceBill.includeFromZone;
                destinationBill.hpRange            = sourceBill.hpRange;

                var sourceThingDef   = sourceBill.recipe.ProducedThingDef;
                var producedThingDef = destinationBill.recipe.ProducedThingDef;
                if (sourceThingDef != null && producedThingDef != null)
                {
                    if ((sourceThingDef.IsWeapon || sourceThingDef.IsApparel) &&
                        (producedThingDef.IsWeapon || producedThingDef.IsApparel))
                    {
                        destinationBill.includeEquipped = sourceBill.includeEquipped;
                    }

                    if (sourceThingDef.IsApparel && sourceThingDef.apparel.careIfWornByCorpse &&
                        producedThingDef.IsApparel && producedThingDef.apparel.careIfWornByCorpse)
                    {
                        destinationBill.includeTainted = sourceBill.includeTainted;
                    }

                    if (sourceThingDef.HasComp(typeof(CompQuality)) &&
                        producedThingDef.HasComp(typeof(CompQuality)))
                    {
                        destinationBill.qualityRange = sourceBill.qualityRange;
                    }

                    if (sourceThingDef.MadeFromStuff && producedThingDef.MadeFromStuff)
                    {
                        destinationBill.limitToAllowedStuff = sourceBill.limitToAllowedStuff;
                    }
                }
            }

            var sourceExtendedData = GetOrCreateExtendedDataFor(sourceBill);

            if (sourceExtendedData == null)
            {
                return;
            }

            var destinationExtendedData = GetOrCreateExtendedDataFor(destinationBill);

            destinationExtendedData?.CloneFrom(sourceExtendedData, !preserveTargetProduct);
        }
 // Delete extended data when bill is deleted
 public void DeleteExtendedDataFor(Bill_Production bill)
 {
     RemoveBillFromLinkSets(bill);
     _store.Remove(bill);
 }
Example #7
0
        public bool UpdateAvailIngredientsCache()
        {
            anyBillIngredientsAvailable = false;
            ingredientsAvailableNow.Clear();

            if (AnyPendingRequests == false)
            {
                return(false);
            }

            //Thing giver = (observedThingHolder as Thing);
            //QEEMod.TryLog("Updating available ingredients cache for " + giver.ThingID);

            List <Bill> bills = new List <Bill>();

            if (_activeBill != null)
            {
                bills.Add(_activeBill);
            }
            else
            {
                bills = (observedThingHolder as IBillGiver)?.BillStack.Bills;
            }

            Dictionary <string, Thing> ingsFoundOnMap = new Dictionary <string, Thing>();
            int checkIntervalTicks = QEESettings.instance.ingredientCheckIntervalSeconds * 60;

            for (int i = 0; i < bills.Count; i++)
            {
                Bill_Production curBill = bills[i] as Bill_Production;

                if (Find.TickManager.TicksGame < curBill.lastIngredientSearchFailTicks + checkIntervalTicks)
                {
                    QEEMod.TryLog("checked " + curBill.GetUniqueLoadID() + " for avail. ingredients recently, skipping");
                    continue;
                }
                curBill.lastIngredientSearchFailTicks = 0;

                if (curBill.ShouldDoNow())
                {
                    //loop through ingredients
                    foreach (IngredientCount curIng in curBill.recipe.ingredients)
                    {
                        Thing ing;

                        //if same ingredient was found on map in previous loop iteration, don't search map again
                        ingsFoundOnMap.TryGetValue(curIng.FixedIngredient.defName, out ing);
                        if (ing != null)
                        {
                            ingredientsAvailableNow[curBill.GetUniqueLoadID()] = ing;
                            //QEEMod.TryLog("Already found " + ing.Label + " on previous iteration. Skipping");
                            break;
                        }

                        //check if this ingredient is on the map
                        ing = IngredientUtility.FindClosestIngToBillGiver(curBill, curIng);
                        if (ing != null)
                        {
                            QEEMod.TryLog("Found " + ing.Label + " on map, adding to ingredient cache");
                            ingsFoundOnMap[curIng.FixedIngredient.defName]     = ing;
                            ingredientsAvailableNow[curBill.GetUniqueLoadID()] = ing;
                            anyBillIngredientsAvailable = true;
                            break;
                        }
                        else
                        {
                            //QEEMod.TryLog("no ingredients available");
                        }
                    }

                    Thing dummy;
                    if (!ingredientsAvailableNow.TryGetValue(curBill.GetUniqueLoadID(), out dummy))
                    {
                        curBill.lastIngredientSearchFailTicks = Find.TickManager.TicksGame;
                    }
                }
            }

            return(anyBillIngredientsAvailable);
        }
 public bool CanPasteInto(Bill_Production targetBill)
 {
     return(_copiedBills.Count == 1 && _copiedBills.First() != targetBill);
 }
        private void Update(Bill_Production thatBill, ref bool actionTaken)
        {
            if (thatBill.storeMode != Bill.storeMode)
            {
                thatBill.storeMode = Bill.storeMode;
                actionTaken = true;
            }

            if (thatBill.ingredientFilter != Bill.ingredientFilter)
            {
                thatBill.ingredientFilter = Bill.ingredientFilter;
                actionTaken = true;
            }

            if (Math.Abs(thatBill.ingredientSearchRadius - Bill.ingredientSearchRadius) > 1)
            {
                thatBill.ingredientSearchRadius = Bill.ingredientSearchRadius;
                actionTaken = true;
            }

            if (thatBill.minSkillLevel != Bill.minSkillLevel)
            {
                thatBill.minSkillLevel = Bill.minSkillLevel;
                actionTaken = true;
            }
        }
        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);
        }
Example #11
0
 public override string ProductsDescription(Bill_Production bill)
 {
     return(Base.DefOf.DTechshards.label);
 }
Example #12
0
 public override int CountProducts(Bill_Production bill)
 {
     return(bill.Map.resourceCounter.GetCountIn(Base.DefOf.DTechshards));
 }
 //public int CountValidThings(List<Thing> things, Bill_Production bill, ThingDef def)
 public static bool Prefix(ref int __result, RecipeWorkerCounter __instance, List <Thing> things, Bill_Production bill, ThingDef def)
 {
     //Vital fix being stackCount, not just # of things.
     __result = things.Where(t => __instance.CountValidThing(t, bill, def)).Sum(t => t.stackCount);
     return(false);
 }
Example #14
0
 public void OnBillDeleted(Bill_Production bill)
 {
     _extendedBillDataStorage?.DeleteExtendedDataFor(bill);
     BillCopyPasteHandler.RemoveBill(bill);
 }
        public override Job JobOnThing(Pawn pawn, Thing researchBench)
        {
            var billGiver = researchBench as IBillGiver;
            Bill bill;

            // check if can generate bills
            if (billGiver == null)
            {
                return null;
            }
            // require no power or power available
            if (!billGiver.CurrentlyUsable())
            {
                return null;
            }

            if (!pawn.CanReserve(researchBench) ||
                !pawn.CanReach(researchBench.InteractionCell, PathEndMode.OnCell, Danger.Some) ||
                researchBench.IsBurning() || researchBench.IsForbidden(pawn))
            {
                return null;
            }

            // researchBench has added bills
            if (billGiver.BillStack.Count == 1)
            {
                // clear bill stack if research is finished or changed
                if (billGiver.BillStack[0].recipe.defName != Find.ResearchManager.currentProj.defName ||
                    ResearchProjectDef.Named(billGiver.BillStack[0].recipe.defName).IsFinished)
                {
                    billGiver.BillStack.Clear();
                }
            }

            // Add research bill if it's not added already
            if (billGiver.BillStack.Count == 0)
            {
                bill = new Bill_Production(DefDatabase<RecipeDef>.GetNamed(Find.ResearchManager.currentProj.defName))
                {
                    suspended = true
                };
                // NOTE: why suspended???
                billGiver.BillStack.AddBill(bill);
            }
            else
            {
                bill = billGiver.BillStack[0];
            }

            if (!TryFindBestBillIngredients(bill, pawn, researchBench, chosenIngridiens))
            {
                if (FloatMenuMakerMap.making)
                {
                    JobFailReason.Is(MissingMaterialsTranslated);
                }
                return null;
            }
            bill.suspended = false;

            // clear the work table
            var haulAside = WorkGiverUtility.HaulStuffOffBillGiverJob(pawn, billGiver, null);
            if (haulAside != null)
            {
                return haulAside;
            }

            // gather ingridients and do bill
            var doBill = new Job(JobDefOf.Research, researchBench)
            {
                targetQueueB = new List<TargetInfo>(chosenIngridiens.Count),
                numToBringList = new List<int>(chosenIngridiens.Count)
            };
            foreach (var ingridient in chosenIngridiens)
            {
                doBill.targetQueueB.Add(ingridient.thing);
                doBill.numToBringList.Add(ingridient.count);
            }
            doBill.haulMode = HaulMode.ToCellNonStorage;
            doBill.bill = bill;
            return doBill;
        }
        /// <summary>
        ///     update bill settings
        /// </summary>
        /// <param name="thatBill">Managed bill</param>
        /// <param name="actionTaken">Any changes made?</param>
        private void Update( Bill_Production thatBill, ref bool actionTaken )
        {
            if ( thatBill.storeMode != Bill.storeMode )
            {
            #if DEBUG_JOBS
                debug.AppendLine( "Updating Bill.storeMode" );
            #endif
                thatBill.storeMode = Bill.storeMode;
                actionTaken = true;
            }

            if ( thatBill.ingredientFilter != Bill.ingredientFilter )
            {
            #if DEBUG_JOBS
                debug.AppendLine( "Updating Bill.ingredientFilter" );
            #endif
                thatBill.ingredientFilter = Bill.ingredientFilter;
                actionTaken = true;
            }

            if ( Math.Abs( thatBill.ingredientSearchRadius - Bill.ingredientSearchRadius ) > 1 )
            {
            #if DEBUG_JOBS
                debug.AppendLine( "Updating Bill.ingredientSearchRadius" );
            #endif
                thatBill.ingredientSearchRadius = Bill.ingredientSearchRadius;
                actionTaken = true;
            }

            if ( thatBill.allowedSkillRange != Bill.allowedSkillRange )
            {
            #if DEBUG_JOBS
                debug.AppendLine( "Updating Bill.minSkillLevel" );
            #endif
                thatBill.allowedSkillRange = Bill.allowedSkillRange;
                actionTaken = true;
            }
        }
Example #17
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            AddEndCondition(delegate
            {
                Thing thing = GetActor().jobs.curJob.GetTarget(TargetIndex.A).Thing;
                return((!(thing is Building) || thing.Spawned) ? JobCondition.Ongoing : JobCondition.Incompletable);
            });
            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);
            });
            Toil gotoBillGiver = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell);
            Toil toil          = new Toil();

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

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

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

            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, putRemainderInQueue: true, subtractNumTakenFromJobCount: false, failIfStackCountLessThanJobCount: true));

            yield return(JumpToCollectNextIntoHandsForBill(getToHaulTarget, TargetIndex.B));

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

            Toil findPlaceTarget2 = Toils_JobTransforms.SetTargetToIngredientPlaceCell(TargetIndex.A, TargetIndex.B, TargetIndex.C);

            yield return(findPlaceTarget2);

            yield return(Toils_Haul.PlaceHauledThingInCell(TargetIndex.C, findPlaceTarget2, storageMode: 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 (!job.RecipeDef.products.NullOrEmpty() || !job.RecipeDef.specialProducts.NullOrEmpty())
            {
                yield return(Toils_Reserve.Reserve(TargetIndex.B));

                findPlaceTarget2 = Toils_Haul.CarryHauledThingToCell(TargetIndex.B);
                yield return(findPlaceTarget2);

                yield return(Toils_Haul.PlaceHauledThingInCell(TargetIndex.B, findPlaceTarget2, 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)
                    {
                        base.Map.resourceCounter.UpdateResourceCounts();
                    }
                };
                yield return(recount);
            }
        }
Example #18
0
        private static bool TryCreateBill(StreamReader sr, out Bill_Production bill)
        {
            bill = null;
            string[] kv = null;
            try
            {
                while (!sr.EndOfStream)
                {
                    if (ReadField(sr, out kv))
                    {
                        RecipeDef def;
                        switch (kv[0])
                        {
                        case BREAK:
                            return(true);

                        case "recipeDefName":
                            def = DefDatabase <RecipeDef> .GetNamed(kv[1]);

                            if (def == null)
                            {
                                string msg = "SaveStorageSettings.UnableToLoadRecipeDef".Translate().Replace("%s", kv[1]);
                                Messages.Message(msg, MessageTypeDefOf.SilentInput);
                                Log.Warning(msg);
                                return(false);
                            }
                            if (def.researchPrerequisite != null && !def.researchPrerequisite.IsFinished)
                            {
                                string msg = "SaveStorageSettings.ResearchNotDoneForRecipeDef".Translate().Replace("%s", def.label);
                                Messages.Message(msg, MessageTypeDefOf.SilentInput);
                                Log.Warning(msg);
                                return(false);
                            }
                            bill = new Bill_Production(def);
                            break;

                        case "recipeDefNameUft":
                            def = DefDatabase <RecipeDef> .GetNamed(kv[1]);

                            if (def == null)
                            {
                                string msg = "SaveStorageSettings.UnableToLoadRecipeDef".Translate().Replace("%s", kv[1]);
                                Messages.Message(msg, MessageTypeDefOf.SilentInput);
                                Log.Warning(msg);
                                return(false);
                            }
                            if (def.researchPrerequisite != null && !def.researchPrerequisite.IsFinished)
                            {
                                string msg = "SaveStorageSettings.ResearchNotDoneForRecipeDef".Translate().Replace("%s", def.label);
                                Messages.Message(msg, MessageTypeDefOf.SilentInput);
                                Log.Warning(msg);
                                return(false);
                            }
                            bill = new Bill_ProductionWithUft(def);
                            break;

                        case "skillRange":
                            kv = kv[1].Split('~');
                            bill.allowedSkillRange = new IntRange(int.Parse(kv[0]), int.Parse(kv[1]));
                            break;

                        case "suspended":
                            bill.suspended = bool.Parse(kv[1]);
                            break;

                        case "ingSearchRadius":
                            bill.ingredientSearchRadius = float.Parse(kv[1]);
                            break;

                        case "repeatMode":
                            bill.repeatMode = null;
                            if (BillRepeatModeDefOf.Forever.defName.Equals(kv[1]))
                            {
                                bill.repeatMode = BillRepeatModeDefOf.Forever;
                            }
                            else if (BillRepeatModeDefOf.RepeatCount.defName.Equals(kv[1]))
                            {
                                bill.repeatMode = BillRepeatModeDefOf.RepeatCount;
                            }
                            else if (BillRepeatModeDefOf.TargetCount.defName.Equals(kv[1]))
                            {
                                bill.repeatMode = BillRepeatModeDefOf.TargetCount;
                            }
                            else if ("TD_ColonistCount".Equals(kv[1]))
                            {
                                EverybodyGetsOneUtil.TryGetRepeatModeDef("TD_ColonistCount", out bill.repeatMode);
                            }
                            else if ("TD_XPerColonist".Equals(kv[1]))
                            {
                                EverybodyGetsOneUtil.TryGetRepeatModeDef("TD_XPerColonist", out bill.repeatMode);
                            }
                            else if ("TD_WithSurplusIng".Equals(kv[1]))
                            {
                                EverybodyGetsOneUtil.TryGetRepeatModeDef("TD_WithSurplusIng", out bill.repeatMode);
                            }

                            if (bill.repeatMode == null)
                            {
                                Log.Warning("Unknown repeatMode of [" + kv[1] + "] for bill " + bill.recipe.defName);
                                bill = null;
                                return(false);
                            }
                            break;

                        case "repeatCount":
                            bill.repeatCount = int.Parse(kv[1]);
                            break;

                        case "storeMode":
                            string[] storeSplit = kv[1].Split('/');

                            BillStoreModeDef storeMode = DefDatabase <BillStoreModeDef> .GetNamedSilentFail(storeSplit[0]);

                            if (storeMode == null)
                            {
                                Log.Message("Bill [" + bill.recipe.defName + "] storeMode [" + kv[1] + "] cannot be found. Defaulting to [" + BillStoreModeDefOf.BestStockpile.ToString() + "].");
                                storeMode = BillStoreModeDefOf.BestStockpile;
                            }

                            Zone_Stockpile storeZone = null;
                            if (storeMode == BillStoreModeDefOf.SpecificStockpile)
                            {
                                if (storeSplit.Length > 1)
                                {
                                    storeZone = (Zone_Stockpile)Find.CurrentMap?.zoneManager.AllZones.FirstOrFallback(z => z.GetUniqueLoadID() == storeSplit[1]);
                                }

                                if (storeZone == null)
                                {
                                    Log.Message("Bill [" + bill.recipe.defName + "] storeZone [" + kv[1] + "] cannot be found. Defaulting to storeMode [" + BillStoreModeDefOf.BestStockpile.ToString() + "].");
                                    storeMode = BillStoreModeDefOf.BestStockpile;
                                }
                            }

                            bill.SetStoreMode(storeMode, storeZone);
                            break;

                        case "targetCount":
                            bill.targetCount = int.Parse(kv[1]);
                            break;

                        case "includeEquipped":
                            bill.includeEquipped = bool.Parse(kv[1]);
                            break;

                        case "includeTainted":
                            bill.includeTainted = bool.Parse(kv[1]);
                            break;

                        case "includeFromZone":
                            Zone_Stockpile zone = (Zone_Stockpile)Find.CurrentMap?.zoneManager.AllZones.FirstOrFallback(z => z.GetUniqueLoadID() == kv[1]);

                            if (zone == null)
                            {
                                Log.Message("Bill [" + bill.recipe.defName + "] includeFromZone [" + kv[1] + "] cannot be found. Defaulting to Everywhere (null).");
                            }

                            bill.includeFromZone = zone;
                            break;

                        case "limitToAllowedStuff":
                            bill.limitToAllowedStuff = bool.Parse(kv[1]);
                            break;

                        case "pauseWhenSatisfied":
                            bill.pauseWhenSatisfied = bool.Parse(kv[1]);
                            break;

                        case "unpauseWhenYouHave":
                            bill.unpauseWhenYouHave = int.Parse(kv[1]);
                            break;

                        case "hpRange":
                            kv           = kv[1].Split('~');
                            bill.hpRange = new FloatRange(float.Parse(kv[0]), float.Parse(kv[1]));
                            break;

                        case "qualityRange":
                            bill.qualityRange = QualityRange.FromString(kv[1]);
                            break;

                        case "ingredientFilter":
                            ReadFiltersFromFile(bill.ingredientFilter, sr);
                            return(true);
                        }
                    }
                }
            }
            catch
            {
                string error = "";
                if (bill != null && bill.recipe != null)
                {
                    error = "Unable to load bill [" + bill.recipe.defName + "].";
                }
                else
                {
                    error = "Unable to load a bill.";
                }

                if (kv == null || kv.Length < 2)
                {
                    error += " Current line: [" + kv[0] + ":" + kv[1] + "]";
                }
                Log.Warning(error);
                bill = null;
                return(false);
            }
            return(true);
        }
Example #19
0
 public virtual bool CanPossiblyStoreInStockpile(Bill_Production bill, Zone_Stockpile stockpile)
 {
     return(!this.CanCountProducts(bill) || stockpile.GetStoreSettings().AllowedToAccept(this.recipe.products[0].thingDef));
 }
            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 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 = new Toil();
                    PickUpThing.initAction = delegate()
                    {
                        Pawn  actor  = extract.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;
                                        }
                                    }
                                }
                            }
                        }
                    };

                    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())
                        {
                            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)
                {
                    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);
                            IEnumerable <Filth> l = Utility.SelectAllFilth(FilthList.actor, A);
                            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 = __instance.job.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 = __instance.job.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, FilthList);
                    clean.JumpIfOutsideHomeArea(TargetIndex.A, FilthList);
                    yield return(clean);

                    yield return(Toils_Jump.Jump(FilthList));

                    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;
            }
Example #21
0
 public virtual bool CanCountProducts(Bill_Production bill)
 {
     return(this.recipe.specialProducts == null && this.recipe.products != null && this.recipe.products.Count == 1);
 }
Example #22
0
        // Specific storage stockpile
        private static void ShowCustomTakeToStockpileMenu(Bill_Production billRaw, Rect inRect)
        {
            var extendedBillDataStorage = Main.Instance.GetExtendedBillDataStorage();
            var extendedBillData        = extendedBillDataStorage.GetExtendedDataFor(billRaw);

            if (extendedBillData == null)
            {
                return;
            }

            const float columnWidth  = 180f;
            const float middleColumn = columnWidth + 34f;
            const float buttonHeight = 30f;

            var storeRect = new Rect(middleColumn + 3f, inRect.yMin + 114f,
                                     columnWidth, buttonHeight);
            var allStockpiles = Find.VisibleMap.zoneManager.AllZones.OfType <Zone_Stockpile>();

            if (Widgets.ButtonText(storeRect, "null"))
            {
                var storeOptionList = new List <FloatMenuOption>();

                var builtInStoremodesQry =
                    from bsm in DefDatabase <BillStoreModeDef> .AllDefs
                    orderby bsm.listOrder
                    select bsm;

                foreach (var storeModeDef in builtInStoremodesQry)
                {
                    var smLocal = storeModeDef;
                    var smLabel = storeModeDef.LabelCap;
                    storeOptionList.Add(
                        new FloatMenuOption(
                            smLabel,
                            delegate
                    {
                        billRaw.storeMode = smLocal;
                        extendedBillData.RemoveTakeToStockpile();
                    }
                            )
                        );
                }

                foreach (Zone_Stockpile stockpile in allStockpiles)
                {
                    var label  = "IW.TakeToLabel".Translate() + " " + stockpile.label;
                    var option = new FloatMenuOption(
                        label,
                        delegate
                    {
                        extendedBillData.SetTakeToStockpile(stockpile);
                        billRaw.storeMode = BillStoreModeDefOf.BestStockpile;
                    }
                        );

                    storeOptionList.Add(option);
                }

                Find.WindowStack.Add(new FloatMenu(storeOptionList));
            }
        }
        static IEnumerable <Widgets.DropdownMenuElement <Pawn> > Postfix(IEnumerable <Widgets.DropdownMenuElement <Pawn> > values, Dialog_BillConfig __instance)
        {
            foreach (Widgets.DropdownMenuElement <Pawn> value in values)
            {
                yield return(value);
            }
            Bill_Production bill                 = Traverse.Create(__instance).Field("bill").GetValue <Bill_Production>();
            WorkGiverDef    workGiver            = bill.billStack.billGiver.GetWorkgiver();
            List <Pawn>     allPrisonersOfColony = PawnsFinder.AllMaps_PrisonersOfColony;

            Widgets.DropdownMenuElement <Pawn> dropdownMenuElement;
            foreach (Pawn pawn in allPrisonersOfColony)
            {
                if (PrisonLaborUtility.LaborEnabled(pawn))
                {
                    if (pawn.WorkTypeIsDisabled(workGiver.workType))
                    {
                        dropdownMenuElement = new Widgets.DropdownMenuElement <Pawn>
                        {
                            option  = new FloatMenuOption(string.Format("{0} ({1})", pawn.LabelShortCap, "WillNever".Translate(workGiver.verb)), null),
                            payload = pawn
                        };
                        yield return(dropdownMenuElement);
                    }
                    else if (bill.recipe.workSkill != null && !pawn.workSettings.WorkIsActive(workGiver.workType))
                    {
                        dropdownMenuElement = new Widgets.DropdownMenuElement <Pawn>
                        {
                            option = new FloatMenuOption(string.Format("{0} ({1} {2}, {3})", pawn.LabelShortCap, pawn.skills.GetSkill(bill.recipe.workSkill).Level, bill.recipe.workSkill.label, "NotAssigned".Translate()), delegate
                            {
                                bill.pawnRestriction = pawn;
                            }),
                            payload = pawn
                        };
                        yield return(dropdownMenuElement);
                    }
                    else if (!pawn.workSettings.WorkIsActive(workGiver.workType))
                    {
                        dropdownMenuElement = new Widgets.DropdownMenuElement <Pawn>
                        {
                            option = new FloatMenuOption(string.Format("{0} ({1})", pawn.LabelShortCap, "NotAssigned".Translate()), delegate
                            {
                                bill.pawnRestriction = pawn;
                            }),
                            payload = pawn
                        };
                        yield return(dropdownMenuElement);
                    }
                    else if (bill.recipe.workSkill != null)
                    {
                        dropdownMenuElement = new Widgets.DropdownMenuElement <Pawn>
                        {
                            option = new FloatMenuOption($"{pawn.LabelShortCap} ({pawn.skills.GetSkill(bill.recipe.workSkill).Level} {bill.recipe.workSkill.label})", delegate
                            {
                                bill.pawnRestriction = pawn;
                            }),
                            payload = pawn
                        };
                        yield return(dropdownMenuElement);
                    }
                    else
                    {
                        dropdownMenuElement = new Widgets.DropdownMenuElement <Pawn>
                        {
                            option = new FloatMenuOption($"{pawn.LabelShortCap}", delegate
                            {
                                bill.pawnRestriction = pawn;
                            }),
                            payload = pawn
                        };
                        yield return(dropdownMenuElement);
                    }
                }
            }
        }
 public bool IsLinkedBill(Bill_Production bill)
 {
     return(GetBillSetContaining(bill) != null);
 }
Example #25
0
        public static void Postfix(Bill_Production __instance)
        {
            var storage = HugsLib.Utils.UtilityWorldObjectManager.GetUtilityWorldObject <ExtendedBillDataStorage>();

            storage.GetOrCreateExtendedDataFor(__instance).ExposeData();
        }
 // Return the associate extended data for a given bill, if found.
 public ExtendedBillData GetExtendedDataFor(Bill_Production bill)
 {
     return(_store.TryGetValue(bill, out ExtendedBillData data) ? data : null);
 }
 public virtual string ProductsDescription(Bill_Production bill)
 {
     return(null);
 }
Example #28
0
 public override bool CanCountProducts(Bill_Production bill)
 {
     return(true);
 }
        public virtual int CountProducts(Bill_Production bill)
        {
            ThingDefCountClass thingDefCountClass = recipe.products[0];
            ThingDef           thingDef           = thingDefCountClass.thingDef;

            if (thingDefCountClass.thingDef.CountAsResource && !bill.includeEquipped && (bill.includeTainted || !thingDefCountClass.thingDef.IsApparel || !thingDefCountClass.thingDef.apparel.careIfWornByCorpse) && bill.includeFromZone == null && bill.hpRange.min == 0f && bill.hpRange.max == 1f && bill.qualityRange.min == QualityCategory.Awful && bill.qualityRange.max == QualityCategory.Legendary && !bill.limitToAllowedStuff)
            {
                return(bill.Map.resourceCounter.GetCount(thingDefCountClass.thingDef) + GetCarriedCount(bill, thingDef));
            }
            int num = 0;

            if (bill.includeFromZone == null)
            {
                num = CountValidThings(bill.Map.listerThings.ThingsOfDef(thingDefCountClass.thingDef), bill, thingDef);
                if (thingDefCountClass.thingDef.Minifiable)
                {
                    List <Thing> list = bill.Map.listerThings.ThingsInGroup(ThingRequestGroup.MinifiedThing);
                    for (int i = 0; i < list.Count; i++)
                    {
                        MinifiedThing minifiedThing = (MinifiedThing)list[i];
                        if (CountValidThing(minifiedThing.InnerThing, bill, thingDef))
                        {
                            num += minifiedThing.stackCount * minifiedThing.InnerThing.stackCount;
                        }
                    }
                }
                num += GetCarriedCount(bill, thingDef);
            }
            else
            {
                foreach (Thing allContainedThing in bill.includeFromZone.AllContainedThings)
                {
                    Thing innerIfMinified = allContainedThing.GetInnerIfMinified();
                    if (CountValidThing(innerIfMinified, bill, thingDef))
                    {
                        num += innerIfMinified.stackCount;
                    }
                }
            }
            if (bill.includeEquipped)
            {
                foreach (Pawn item in bill.Map.mapPawns.FreeColonistsSpawned)
                {
                    List <ThingWithComps> allEquipmentListForReading = item.equipment.AllEquipmentListForReading;
                    for (int j = 0; j < allEquipmentListForReading.Count; j++)
                    {
                        if (CountValidThing(allEquipmentListForReading[j], bill, thingDef))
                        {
                            num += allEquipmentListForReading[j].stackCount;
                        }
                    }
                    List <Apparel> wornApparel = item.apparel.WornApparel;
                    for (int k = 0; k < wornApparel.Count; k++)
                    {
                        if (CountValidThing(wornApparel[k], bill, thingDef))
                        {
                            num += wornApparel[k].stackCount;
                        }
                    }
                    ThingOwner directlyHeldThings = item.inventory.GetDirectlyHeldThings();
                    for (int l = 0; l < directlyHeldThings.Count; l++)
                    {
                        if (CountValidThing(directlyHeldThings[l], bill, thingDef))
                        {
                            num += directlyHeldThings[l].stackCount;
                        }
                    }
                }
                return(num);
            }
            return(num);
        }
 public override string ProductsDescription(Bill_Production bill)
 {
     return(ThingCategoryDefOf.StoneBlocks.label);
 }
Example #31
0
        /// <summary>
        /// Checks if Bill specifies to drop product on ground, and if so, creates the product and drops it.
        /// The current grower's active Bill is retrieved programmatically via grower members.
        /// Heavily modified version of the Toils_Recipe.FinishRecipeAndStartStoringProduct() toil in vanilla.
        /// </summary>
        /// <returns></returns>
        public static Toil TryDropProductOnFloor(Building_GrowerBase_WorkTable vat)
        {
            Toil toil = new Toil();

            toil.initAction = delegate
            {
                Pawn            actor      = toil.actor;
                Bill_Production activeBill = vat.billProc.ActiveBill;

                if (vat?.activeRecipe?.products[0]?.thingDef == null)
                {
                    if (vat?.activeRecipe?.label != null)
                    {
                        QEEMod.TryLog("No product found in recipe " + vat.activeRecipe.label + ".Ending extract Job.");
                    }
                    else
                    {
                        QEEMod.TryLog("No product found in recipe. Ending extract Job.");
                    }

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

                    actor.jobs.EndCurrentJob(JobCondition.Succeeded);
                }
                else if (activeBill == null || activeBill.GetStoreMode() == BillStoreModeDefOf.DropOnFloor)
                {
                    //true if no output stockpile specified in bill options

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

                    if (activeBill?.GetUniqueLoadID() != null)
                    {
                        QEEMod.TryLog("activeBill: " + activeBill?.GetUniqueLoadID() + " specifies dropping " + product.Label + " on floor.");
                    }
                    else
                    {
                        QEEMod.TryLog("activeBill is null, dropping " + product.Label + " on floor.");
                    }

                    //put the product on the ground on the same cell as the pawn
                    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.");
                    }

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

                    actor.jobs.EndCurrentJob(JobCondition.Succeeded);
                }
            };
            return(toil);
        } // end TryDropProductOnFloor
        public void SetNewRecipe( RecipeDef newRecipe )
        {
            // clear currently assigned bills.
            CleanUp();

            // set the bill on this job
            Bill = newRecipe.UsesUnfinishedThing
                       ? new Bill_ProductionWithUft( newRecipe )
                       : new Bill_Production( newRecipe );
            _hasMeaningfulIngredientChoices = Dialog_CreateJobsForIngredients.HasPrerequisiteChoices( manager, newRecipe );

            // mainproduct and trigger do not change.
            BillGivers = new BillGiverTracker( this );

            // set the last cache time so it gets updated.
            ForceRecacheOtherRecipe();

            // null targets cache so it gets updated
            _targets = null;
        }
Example #33
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
 public BillTablePriority( Bill_Production bill, Building_WorkTable table, int priority )
 {
     this.bill = bill;
     this.table = table;
     this.priority = priority;
 }
 public void RemoveBill(Bill_Production bill)
 {
     _copiedBills.Remove(bill);
 }
 public void DoCopy(Bill_Production bill)
 {
     _copiedBills.Clear();
     _copiedBills.Add(bill);
 }
Example #37
0
        public static bool SaveCraftingSettings(BillStack bills, FileInfo fi)
        {
            try
            {
                // Write Data
                using (FileStream fileStream = File.Open(fi.FullName, FileMode.Create, FileAccess.Write))
                {
                    using (StreamWriter sw = new StreamWriter(fileStream))
                    {
                        WriteField(sw, "Version", "2");

                        foreach (Bill b in bills)
                        {
                            if (b is Bill_Production)
                            {
                                Bill_Production p = b as Bill_Production;

                                BillStoreModeDef storeMode       = p.GetStoreMode();
                                Zone_Stockpile   storeZone       = p.GetStoreZone();
                                Zone_Stockpile   includeFromZone = p.includeFromZone;

                                WriteField(sw, "bill", p.recipe.defName);
                                if (b is Bill_ProductionWithUft)
                                {
                                    WriteField(sw, "recipeDefNameUft", p.recipe.defName);
                                }
                                else
                                {
                                    WriteField(sw, "recipeDefName", p.recipe.defName);
                                }
                                WriteField(sw, "skillRange", p.allowedSkillRange.ToString());
                                WriteField(sw, "suspended", p.suspended.ToString());
                                WriteField(sw, "ingSearchRadius", p.ingredientSearchRadius.ToString());
                                WriteField(sw, "storeMode", storeMode == BillStoreModeDefOf.SpecificStockpile ?
                                           string.Join("/", storeMode.defName, storeZone.GetUniqueLoadID()) :
                                           storeMode.defName
                                           );
                                WriteField(sw, "repeatMode", p.repeatMode.defName);
                                WriteField(sw, "repeatCount", p.repeatCount.ToString());
                                WriteField(sw, "targetCount", p.targetCount.ToString());
                                WriteField(sw, "includeEquipped", p.includeEquipped.ToString());
                                WriteField(sw, "includeTainted", p.includeTainted.ToString());
                                if (includeFromZone != null)
                                {
                                    WriteField(sw, "includeFromZone", includeFromZone.GetUniqueLoadID());
                                }
                                WriteField(sw, "limitToAllowedStuff", p.limitToAllowedStuff.ToString());
                                WriteField(sw, "pauseWhenSatisfied", p.pauseWhenSatisfied.ToString());
                                WriteField(sw, "unpauseWhenYouHave", p.unpauseWhenYouHave.ToString());
                                WriteField(sw, "hpRange", p.hpRange.ToString());
                                WriteField(sw, "qualityRange", p.qualityRange.ToString());
                                WriteField(sw, "ingredientFilter", "");
                                WriteFiltersToFile(p.ingredientFilter, sw);
                            }
                            WriteField(sw, BREAK, BREAK);
                        }
                    }
                }
            }
            catch (Exception e)
            {
                LogException("Problem saving crafting bills file '" + fi.Name + "'.", e);
                return(false);
            }
            return(true);
        }