Esempio n. 1
0
        private static bool AllowToolHaulUrgentlyJobOnThing_PreFix(ref Job __result, Pawn pawn, Thing t, bool forced = false)
        {
            if (ModCompatibilityCheck.AllowToolIsActive)
            {
                //allowTool HaulUrgently
                CompHauledToInventory takenToInventory = pawn.TryGetComp <CompHauledToInventory>();

                if (pawn.RaceProps.Humanlike &&
                    pawn.Faction == Faction.OfPlayer &&
                    t is Corpse == false &&
                    takenToInventory != null &&
                    !(t.def.defName.Contains("Chunk"))    //most of the time we don't have space for it
                    )
                {
                    StoragePriority currentPriority = StoreUtility.CurrentStoragePriorityOf(t);
                    if (!StoreUtility.TryFindBestBetterStoreCellFor(t, pawn, pawn.Map, currentPriority, pawn.Faction, out IntVec3 storeCell, true))
                    {
                        JobFailReason.Is("NoEmptyPlaceLower".Translate());
                        return(false);
                    }

                    WorkGiver_HaulToInventory haulWG = (WorkGiver_HaulToInventory)pawn.workSettings.WorkGiversInOrderNormal.Find(wg => wg is WorkGiver_HaulToInventory);

                    Job haul = haulWG.JobOnThing(pawn, t, forced);
                    __result = haul;
                    return(false);
                }
            }
            return(true);
        }
Esempio n. 2
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            this.FailOnDespawnedNullOrForbidden(TargetIndex.A);
            this.FailOnBurningImmobile(TargetIndex.A);
            yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch));

            yield return(Toils_General.Wait(200, TargetIndex.None).FailOnDestroyedNullOrForbidden(TargetIndex.A).FailOnCannotTouch(TargetIndex.A, PathEndMode.Touch).FailOn(() => !this.OniWineBarrel.Fermented).WithProgressBarToilDelay(TargetIndex.A, false, -0.5f));

            yield return(new Toil
            {
                initAction = delegate()
                {
                    Thing thing = this.OniWineBarrel.TakeOutAOniWine();
                    GenPlace.TryPlaceThing(thing, this.pawn.Position, base.Map, ThingPlaceMode.Near, null, null, default);
                    StoragePriority currentPriority = StoreUtility.CurrentStoragePriorityOf(thing);
                    if (StoreUtility.TryFindBestBetterStoreCellFor(thing, this.pawn, base.Map, currentPriority, this.pawn.Faction, out IntVec3 c, true))
                    {
                        this.job.SetTarget(TargetIndex.C, c);
                        this.job.SetTarget(TargetIndex.B, thing);
                        this.job.count = thing.stackCount;
                        return;
                    }
                    base.EndJobWith(JobCondition.Incompletable);
                },
                defaultCompleteMode = ToilCompleteMode.Instant
            });
        public static bool Prefix(Pawn pawn, Thing thing, WorkGiver_HaulToInventory __instance, bool forced, ref bool __result)
        {
            #region PickUpAndHaul code
            //bulky gear (power armor + minigun) so don't bother.
            if (MassUtility.GearMass(pawn) / MassUtility.Capacity(pawn) >= 0.8f)
            {
                return(false);
            }

            if (!WorkGiver_HaulToInventory.GoodThingToHaul(thing, pawn) || !HaulAIUtility.PawnCanAutomaticallyHaulFast(pawn, thing, forced))
            {
                return(false);
            }

            StoragePriority currentPriority = StoreUtility.CurrentStoragePriorityOf(thing);
            bool            foundCell       = StoreUtility.TryFindBestBetterStoreCellFor(thing, pawn, pawn.Map, currentPriority, pawn.Faction, out IntVec3 storeCell, true);
            #endregion

            if (!foundCell)
            {
                __result = false;
            }
            else
            {
                SlotGroup slotGroup = pawn.Map.haulDestinationManager.SlotGroupAt(storeCell);
                __result = !(slotGroup != null && Limits.HasLimit(slotGroup.Settings) && Limits.GetLimit(slotGroup.Settings) >= slotGroup.TotalPrecalculatedItemsStack());
            }

            return(false);
        }
Esempio n. 4
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            this.FailOnDespawnedNullOrForbidden(BuildingInd);
            this.FailOnBurningImmobile(BuildingInd);
            yield return(Toils_Goto.GotoThing(BuildingInd, PathEndMode.Touch));

            yield return(Toils_General.Wait(Duration).FailOnDestroyedNullOrForbidden(BuildingInd).FailOnCannotTouch(BuildingInd, PathEndMode.Touch).FailOn(() => !Building.Completed).WithProgressBarToilDelay(BuildingInd));

            yield return(new Toil
            {
                initAction = delegate
                {
                    Thing product = Building.TakeOutProduct();
                    GenPlace.TryPlaceThing(product, pawn.Position, Map, ThingPlaceMode.Near);
                    StoragePriority currentPriority = StoreUtility.CurrentStoragePriorityOf(product);
                    if (StoreUtility.TryFindBestBetterStoreCellFor(product, pawn, Map, currentPriority, pawn.Faction, out IntVec3 cell))
                    {
                        job.SetTarget(StorageCellInd, cell);
                        job.SetTarget(ProductInd, product);
                        job.count = product.stackCount;
                    }
                    else
                    {
                        EndJobWith(JobCondition.Incompletable);
                    }
                },
Esempio n. 5
0
        public override bool TryMakePreToilReservations(bool errorOnFailed)
        {
            Pawn            pawn           = base.pawn;
            LocalTargetInfo target         = base.job.GetTarget(TargetIndex.B);
            Job             job            = base.job;
            bool            errorOnFailed2 = errorOnFailed;
            bool            result         = false;

            if (!target.Cell.IsValidStorageFor(pawn.Map, pawn.carryTracker.CarriedThing))
            {
                StoragePriority currentPriority = StoreUtility.CurrentStoragePriorityOf(TargetThingA);
                if (!StoreUtility.TryFindBestBetterStorageFor(TargetThingA, pawn, pawn.Map, currentPriority, pawn.Faction, out IntVec3 foundCell, out IHaulDestination haulDestination))
                {
                    return(false);
                }
            }


            if (pawn.Reserve(target, job, 1, -1, null, errorOnFailed2))
            {
                pawn           = base.pawn;
                target         = base.job.GetTarget(TargetIndex.A);
                job            = base.job;
                errorOnFailed2 = errorOnFailed;
                result         = pawn.Reserve(target, job, 1, -1, null, errorOnFailed2);
            }
            Log.Message("Make Reservation result: " + result);
            return(result);
        }
Esempio n. 6
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            this.FailOnDespawnedNullOrForbidden(BarrelInd);
            this.FailOnBurningImmobile(BarrelInd);
            yield return(Toils_Goto.GotoThing(BarrelInd, PathEndMode.Touch));

            yield return(Toils_General.Wait(Duration).FailOnDestroyedNullOrForbidden(BarrelInd)
                         .FailOnCannotTouch(BarrelInd, PathEndMode.Touch).FailOn(() => !MeadBarrel.Fermented)
                         .WithProgressBarToilDelay(BarrelInd));

            yield return(new Toil
            {
                initAction = delegate
                {
                    var thing = MeadBarrel.TakeOutMead();
                    GenPlace.TryPlaceThing(thing, pawn.Position, Map, ThingPlaceMode.Near);
                    var currentPriority = StoreUtility.CurrentStoragePriorityOf(thing);
                    if (StoreUtility.TryFindBestBetterStoreCellFor(thing,
                                                                   pawn, Map, currentPriority, pawn.Faction, out var c))
                    {
                        job.SetTarget(TargetIndex.C, c);
                        job.SetTarget(TargetIndex.B, thing);
                        job.count = thing.stackCount;
                    }
                    else
                    {
                        EndJobWith(JobCondition.Incompletable);
                    }
                },
        public static Job HaulToStorageJob(Pawn p, Thing t)
        {
            StoragePriority  currentPriority = StoreUtility.CurrentStoragePriorityOf(t);
            IntVec3          storeCell;
            IHaulDestination haulDestination;
            Job result;

            if (!StoreUtility.TryFindBestBetterStorageFor(t, p, p.Map, currentPriority, p.Faction, out storeCell, out haulDestination, true))
            {
                JobFailReason.Is(HaulAIUtility.NoEmptyPlaceLowerTrans, null);
                result = null;
            }
            else if (haulDestination is ISlotGroupParent)
            {
                result = HaulAIUtility.HaulToCellStorageJob(p, t, storeCell, false);
            }
            else
            {
                Thing thing = haulDestination as Thing;
                if (thing != null && thing.TryGetInnerInteractableThingOwner() != null)
                {
                    result = HaulAIUtility.HaulToContainerJob(p, t, thing);
                }
                else
                {
                    Log.Error("Don't know how to handle HaulToStorageJob for storage " + haulDestination.ToStringSafe <IHaulDestination>() + ". thing=" + t.ToStringSafe <Thing>(), false);
                    result = null;
                }
            }
            return(result);
        }
Esempio n. 8
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            //Log.Message("I am inside the job now, with "+pawn.ToString(), false);
            Building_ItemProcessor building_processor = (Building_ItemProcessor)this.job.GetTarget(TargetIndex.A).Thing;

            this.FailOnDespawnedNullOrForbidden(TargetIndex.A);
            this.FailOnBurningImmobile(TargetIndex.A);
            yield return(Toils_General.DoAtomic(delegate
            {
                this.job.count = 1;
            }));

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

            yield return(Toils_General.Wait(240).FailOnDestroyedNullOrForbidden(TargetIndex.A).FailOnCannotTouch(TargetIndex.A, PathEndMode.Touch).WithProgressBarToilDelay(TargetIndex.A, false, -0.5f));

            yield return(new Toil
            {
                initAction = delegate
                {
                    Thing newProduct;
                    if (building_processor.productsToTurnInto != null && building_processor.productsToTurnInto.Count > 0)
                    {
                        newProduct = ThingMaker.MakeThing(ThingDef.Named(building_processor.productsToTurnInto[(int)building_processor.qualityNow]));
                    }
                    else
                    {
                        newProduct = ThingMaker.MakeThing(ThingDef.Named(building_processor.productToTurnInto));
                    }

                    newProduct.stackCount = building_processor.amount;

                    if ((newProduct.TryGetComp <CompIngredients>() is CompIngredients ingredientComp) && !building_processor.compItemProcessor.Props.ignoresIngredientLists)
                    {
                        ingredientComp.ingredients = building_processor.ingredients;
                    }
                    if (building_processor.usingQualityIncreasing && newProduct.TryGetComp <CompQuality>() is CompQuality qualityComp)
                    {
                        qualityComp.SetQuality(building_processor.qualityNow, ArtGenerationContext.Colony);
                    }

                    GenSpawn.Spawn(newProduct, building_processor.InteractionCell, building_processor.Map);
                    building_processor.processorStage = ProcessorStage.ProductRemoved;
                    building_processor.ResetEverything();
                    building_processor.DestroyIngredients();

                    StoragePriority currentPriority = StoreUtility.CurrentStoragePriorityOf(newProduct);
                    IntVec3 c;
                    if (StoreUtility.TryFindBestBetterStoreCellFor(newProduct, this.pawn, this.Map, currentPriority, this.pawn.Faction, out c, true))
                    {
                        this.job.SetTarget(TargetIndex.C, c);
                        this.job.SetTarget(TargetIndex.B, newProduct);
                        this.job.count = newProduct.stackCount;
                    }
                    else
                    {
                        this.EndJobWith(JobCondition.Incompletable);
                    }
                },
Esempio n. 9
0
        public static void DeregisterHaulableItem(Thing haulableThing)
        {
            Map map = haulableThing.Map;

            if (map != null)
            {
                int storagePriority = (int)StoreUtility.CurrentStoragePriorityOf(haulableThing);
                getWaitingForZoneBetterThan(map)[storagePriority].Remove(haulableThing);
                RemoveThingFromAwaitingHaulingHashSets(haulableThing);
            }
        }
        //pick up stuff until you can't anymore,
        //while you're up and about, pick up something and haul it
        //before you go out, empty your pockets

        public override Job JobOnThing(Pawn pawn, Thing thing, bool forced = false)
        {
            //bulky gear (power armor + minigun) so don't bother.
            if (MassUtility.GearMass(pawn) / MassUtility.Capacity(pawn) >= 0.8f)
            {
                return(null);
            }

            DesignationDef haulUrgentlyDesignation = DefDatabase <DesignationDef> .GetNamed("HaulUrgentlyDesignation", false);

            // Misc. Robots compatibility
            // See https://github.com/catgirlfighter/RimWorld_CommonSense/blob/master/Source/CommonSense11/CommonSense/OpportunisticTasks.cs#L129-L140
            if (pawn.TryGetComp <CompHauledToInventory>() == null)
            {
                return(null);
            }

            //This WorkGiver gets hijacked by AllowTool and expects us to urgently haul corpses.
            if (ModCompatibilityCheck.AllowToolIsActive && thing is Corpse &&
                pawn.Map.designationManager.DesignationOn(thing)?.def == haulUrgentlyDesignation && HaulAIUtility.PawnCanAutomaticallyHaulFast(pawn, thing, forced))
            {
                return(HaulAIUtility.HaulToStorageJob(pawn, thing));
            }

            if (!GoodThingToHaul(thing, pawn) || !HaulAIUtility.PawnCanAutomaticallyHaulFast(pawn, thing, forced))
            {
                return(null);
            }

            StoragePriority currentPriority = StoreUtility.CurrentStoragePriorityOf(thing);

            if (StoreUtility.TryFindBestBetterStoreCellFor(thing, pawn, pawn.Map, currentPriority, pawn.Faction, out IntVec3 storeCell, true))
            {
                //since we've gone through all the effort of getting the loc, might as well use it.
                //Don't multi-haul food to hoppers.
                if (thing.def.IsNutritionGivingIngestible)
                {
                    if (thing.def.ingestible.preferability == FoodPreferability.RawBad || thing.def.ingestible.preferability == FoodPreferability.RawTasty)
                    {
                        List <Thing> thingList = storeCell.GetThingList(thing.Map);

                        foreach (Thing t in thingList)
                        {
                            if (t.def == ThingDefOf.Hopper)
                            {
                                return(HaulAIUtility.HaulToStorageJob(pawn, thing));
                            }
                        }
                    }
                }
            }
Esempio n. 11
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            this.FailOnDespawnedNullOrForbidden(TargetIndex.A);
            this.FailOnBurningImmobile(TargetIndex.A);
            yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch));

            yield return(Toils_General.Wait(240).FailOnDestroyedNullOrForbidden(TargetIndex.A).FailOnCannotTouch(TargetIndex.A, PathEndMode.Touch).WithProgressBarToilDelay(TargetIndex.A, false, -0.5f));

            yield return(new Toil
            {
                initAction = delegate
                {
                    Building_Beehouse buildingbeehouse = (Building_Beehouse)this.job.GetTarget(TargetIndex.A).Thing;
                    buildingbeehouse.BeehouseIsFull = false;
                    Thing newComb = ThingMaker.MakeThing(DecideRandomComb());
                    GenSpawn.Spawn(newComb, buildingbeehouse.Position - GenAdj.CardinalDirections[0], buildingbeehouse.Map);

                    StoragePriority currentPriority = StoreUtility.CurrentStoragePriorityOf(newComb);
                    IntVec3 c;
                    if (StoreUtility.TryFindBestBetterStoreCellFor(newComb, this.pawn, this.Map, currentPriority, this.pawn.Faction, out c, true))
                    {
                        this.job.SetTarget(TargetIndex.C, c);
                        this.job.SetTarget(TargetIndex.B, newComb);
                        this.job.count = newComb.stackCount;
                        buildingbeehouse.tickCounter = 0;
                    }
                    else
                    {
                        this.EndJobWith(JobCondition.Incompletable);
                        buildingbeehouse.BeehouseIsFull = false;
                        buildingbeehouse.tickCounter = 0;
                    }
                },
                defaultCompleteMode = ToilCompleteMode.Instant
            });

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

            yield return(Toils_Reserve.Reserve(TargetIndex.C, 1, -1, null));

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

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

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

            yield return(carryToCell);

            yield return(Toils_Haul.PlaceHauledThingInCell(TargetIndex.C, carryToCell, true));
        }
Esempio n. 12
0
        // Token: 0x0600002E RID: 46 RVA: 0x000035B0 File Offset: 0x000025B0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            this.FailOnDespawnedNullOrForbidden(TargetIndex.A);
            this.FailOnBurningImmobile(TargetIndex.A);
            yield return(Toils_Reserve.Reserve(TargetIndex.A, 1, -1, null));

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

            yield return(Toils_General.Wait(200, TargetIndex.None).FailOnDestroyedNullOrForbidden(TargetIndex.A).FailOn(() => !this.Barrel.Distilled).WithProgressBarToilDelay(TargetIndex.A, false, -0.5f));

            yield return(new Toil
            {
                initAction = delegate()
                {
                    Thing thing = this.Barrel.TakeOutrawlucibatch();
                    GenPlace.TryPlaceThing(thing, this.pawn.Position, base.Map, ThingPlaceMode.Near, null, null);
                    StoragePriority currentPriority = StoreUtility.CurrentStoragePriorityOf(thing);
                    IntVec3 c;
                    if (StoreUtility.TryFindBestBetterStoreCellFor(thing, this.pawn, base.Map, currentPriority, this.pawn.Faction, out c, true))
                    {
                        this.job.SetTarget(TargetIndex.C, c);
                        this.job.SetTarget(TargetIndex.B, thing);
                        this.job.count = thing.stackCount;
                    }
                    else
                    {
                        base.EndJobWith(JobCondition.Incompletable);
                    }
                },
                defaultCompleteMode = ToilCompleteMode.Instant
            });

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

            yield return(Toils_Reserve.Reserve(TargetIndex.C, 1, -1, null));

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

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

            Toil toil = Toils_Haul.CarryHauledThingToCell(TargetIndex.C);

            yield return(toil);

            yield return(Toils_Haul.PlaceHauledThingInCell(TargetIndex.C, toil, true));

            yield break;
        }
        // Token: 0x06000030 RID: 48 RVA: 0x00002C83 File Offset: 0x00000E83
        protected override IEnumerable <Toil> MakeNewToils()
        {
            CompUniversalFermenter comp = ThingCompUtility.TryGetComp <CompUniversalFermenter>(this.Fermenter);

            ToilFailConditions.FailOn <JobDriver_TakeProductOutOfUniversalFermenter>(this, () => !comp.Fermented);
            ToilFailConditions.FailOnDestroyedNullOrForbidden <JobDriver_TakeProductOutOfUniversalFermenter>(this, (TargetIndex)1);
            yield return(Toils_Reserve.Reserve((TargetIndex)1, 1, -1, null));

            yield return(Toils_Goto.GotoThing((TargetIndex)1, (PathEndMode)3));

            yield return(ToilEffects.WithProgressBarToilDelay(ToilFailConditions.FailOnDestroyedNullOrForbidden <Toil>(Toils_General.Wait(200, 0), (TargetIndex)1), (TargetIndex)1, false, -0.5f));

            yield return(new Toil
            {
                initAction = delegate()
                {
                    Thing thing = comp.TakeOutProduct();
                    GenPlace.TryPlaceThing(thing, this.pawn.Position, this.Map, (ThingPlaceMode)1, null, null);
                    StoragePriority storagePriority = StoreUtility.CurrentStoragePriorityOf(thing);
                    IntVec3 intVec;
                    if (StoreUtility.TryFindBestBetterStoreCellFor(thing, this.pawn, this.Map, storagePriority, this.pawn.Faction, out intVec, true))
                    {
                        this.job.SetTarget((TargetIndex)2, thing);
                        this.job.count = thing.stackCount;
                        this.job.SetTarget((TargetIndex)3, intVec);
                        return;
                    }
                    this.EndJobWith((JobCondition)3);
                },
                defaultCompleteMode = (ToilCompleteMode)1
            });

            yield return(Toils_Reserve.Reserve((TargetIndex)2, 1, -1, null));

            yield return(Toils_Reserve.Reserve((TargetIndex)3, 1, -1, null));

            yield return(Toils_Goto.GotoThing((TargetIndex)2, (PathEndMode)3));

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

            Toil carry = Toils_Haul.CarryHauledThingToCell((TargetIndex)3);

            yield return(carry);

            yield return(Toils_Haul.PlaceHauledThingInCell((TargetIndex)3, carry, true));

            yield break;
        }
        public static bool Prefix(Pawn pawn, Thing thing, ref Job __result)
        {
            StoragePriority currentPriority = StoreUtility.CurrentStoragePriorityOf(thing);

            if (StoreUtility.TryFindBestBetterStoreCellFor(thing, pawn, pawn.Map, currentPriority, pawn.Faction, out IntVec3 storeCell, true))
            {
                SlotGroup slotGroup = StoreUtility.GetSlotGroup(storeCell, thing.Map);
                if (Limits.HasLimit(slotGroup.Settings))
                {
                    __result = HaulAIUtility.HaulToStorageJob(pawn, thing);
                    return(false);
                }
            }

            return(true);
        }
        public override bool HasJobOnThing(Pawn pawn, Thing thing, bool forced = false)
        {
            //bulky gear (power armor + minigun) so don't bother.
            if (MassUtility.GearMass(pawn) / MassUtility.Capacity(pawn) >= 0.8f)
            {
                return(false);
            }

            if (!GoodThingToHaul(thing, pawn) || !HaulAIUtility.PawnCanAutomaticallyHaulFast(pawn, thing, forced))
            {
                return(false);
            }

            StoragePriority currentPriority = StoreUtility.CurrentStoragePriorityOf(thing);

            return(StoreUtility.TryFindBestBetterStoreCellFor(thing, pawn, pawn.Map, currentPriority, pawn.Faction, out IntVec3 _));
        }
Esempio n. 16
0
        //pick up stuff until you can't anymore,
        //while you're up and about, pick up something and haul it
        //before you go out, empty your pockets

        public override Job JobOnThing(Pawn pawn, Thing thing, bool forced = false)
        {
            //bulky gear (power armor + minigun) so don't bother.
            if (MassUtility.GearMass(pawn) / MassUtility.Capacity(pawn) >= 0.8f)
            {
                return(null);
            }

            DesignationDef HaulUrgentlyDesignation = DefDatabase <DesignationDef> .GetNamed("HaulUrgentlyDesignation", false);

            //This WorkGiver gets hijacked by AllowTool and expects us to urgently haul corpses.
            if (ModCompatibilityCheck.AllowToolIsActive && thing is Corpse && pawn.Map.designationManager.DesignationOn(thing)?.def == HaulUrgentlyDesignation && HaulAIUtility.PawnCanAutomaticallyHaulFast(pawn, thing, forced))
            {
                return(HaulAIUtility.HaulToStorageJob(pawn, thing));
            }

            if (!GoodThingToHaul(thing, pawn) || !HaulAIUtility.PawnCanAutomaticallyHaulFast(pawn, thing, forced))
            {
                return(null);
            }

            StoragePriority currentPriority = StoreUtility.CurrentStoragePriorityOf(thing);

            if (StoreUtility.TryFindBestBetterStoreCellFor(thing, pawn, pawn.Map, currentPriority, pawn.Faction, out IntVec3 storeCell, true))
            {
                //since we've gone through all the effort of getting the loc, might as well use it.
                //Don't multi-haul food to hoppers.
                if (thing.def.IsNutritionGivingIngestible)
                {
                    if (thing.def.ingestible.preferability == FoodPreferability.RawBad || thing.def.ingestible.preferability == FoodPreferability.RawTasty)
                    {
                        List <Thing> thingList = storeCell.GetThingList(thing.Map);
                        for (int i = 0; i < thingList.Count; i++)
                        {
                            if (thingList[i].def == ThingDefOf.Hopper)
                            {
                                return(HaulAIUtility.HaulToStorageJob(pawn, thing));
                            }
                        }
                    }
                }
            }
Esempio n. 17
0
            // "Optimize hauling"
            public static Job HaulBeforeCarry(Pawn pawn, IntVec3 destCell, Thing thing)
            {
                if (thing.ParentHolder is Pawn_InventoryTracker)
                {
                    return(null);
                }
                if (!JooStoreUtility.TryFindBestBetterStoreCellFor_ClosestToDestCell(
                        thing, destCell, pawn, pawn.Map, StoreUtility.CurrentStoragePriorityOf(thing), pawn.Faction, out var storeCell, true))
                {
                    return(null);
                }

                var supplyFromHereDist  = thing.Position.DistanceTo(destCell);
                var supplyFromStoreDist = storeCell.DistanceTo(destCell);

//                Debug.WriteLine($"Carry from here: {supplyFromHereDist}; carry from store: {supplyFromStoreDist}");

                // [KV] Infinite Storage https://steamcommunity.com/sharedfiles/filedetails/?id=1233893175
                // infinite storage has an interaction spot 1 tile away from itself
                if (supplyFromStoreDist + 1 < supplyFromHereDist)
                {
                    //                    Debug.WriteLine(
                    //                        $"'{pawn}' prefixed job with haul for '{thing.Label}' because '{storeCell.GetSlotGroup(pawn.Map)}' is closer to original destination '{destCell}'.");

#if RELEASE
                    if (DebugViewSettings.drawOpportunisticJobs)
                    {
#endif
                    pawn.Map.debugDrawer.FlashLine(pawn.Position, thing.Position, 600, SimpleColor.White);      // unchanged
                    pawn.Map.debugDrawer.FlashLine(thing.Position, destCell, 600, SimpleColor.Magenta);
                    pawn.Map.debugDrawer.FlashLine(thing.Position, storeCell, 600, SimpleColor.Cyan);
                    pawn.Map.debugDrawer.FlashLine(storeCell, destCell, 600, SimpleColor.Cyan);
#if RELEASE
                }
#endif

                    var haulTracker = HaulTracker.CreateAndAdd(SpecialHaulType.HaulBeforeCarry, pawn, destCell);
                    return(PuahJob(haulTracker, pawn, thing, storeCell) ?? HaulAIUtility.HaulToCellStorageJob(pawn, thing, storeCell, false));
                }

                return(null);
            }
Esempio n. 18
0
        public static Job HaulToStorageJob(Pawn p, Thing t)
        {
            StoragePriority currentPriority = StoreUtility.CurrentStoragePriorityOf(t);

            if (!StoreUtility.TryFindBestBetterStorageFor(t, p, p.Map, currentPriority, p.Faction, out IntVec3 foundCell, out IHaulDestination haulDestination))
            {
                JobFailReason.Is(NoEmptyPlaceLowerTrans);
                return(null);
            }
            if (haulDestination is ISlotGroupParent)
            {
                return(HaulToCellStorageJob(p, t, foundCell, fitInStoreCell: false));
            }
            Thing thing = haulDestination as Thing;

            if (thing != null && thing.TryGetInnerInteractableThingOwner() != null)
            {
                return(HaulToContainerJob(p, t, thing));
            }
            Log.Error("Don't know how to handle HaulToStorageJob for storage " + haulDestination.ToStringSafe() + ". thing=" + t.ToStringSafe());
            return(null);
        }
        /// <summary>
        /// Make reservation for job targets before doing the job.
        /// </summary>
        /// <param name="errorOnFailed"> If true, log result as error if failed to make a reservation. </param>
        /// <returns> Returns true if a reservation is made. </returns>
        public override bool TryMakePreToilReservations(bool errorOnFailed)
        {
            StoragePriority currentPriority = StoreUtility.CurrentStoragePriorityOf(TargetThingA);

            if (!StoreUtility.TryFindBestBetterStorageFor(TargetThingA, pawn, pawn.Map, currentPriority, pawn.Faction, out IntVec3 foundCell, out IHaulDestination haulDestination))
            {
                JobFailReason.Is(UIText.NoEmptyPlaceLower);
                Messages.Message(
                    UIText.NoEmptyPlaceLower.TranslateSimple()
                    , new TargetInfo(this.pawn.PositionHeld, this.pawn.MapHeld), MessageTypeDefOf.NeutralEvent);
                return(false);
            }

            this.Init(foundCell, haulDestination);

            if (pawn.Reserve(TargetB, this.job, 1, -1, null, errorOnFailed))
            {
                return(pawn.Reserve(TargetA, this.job, 1, -1, null, errorOnFailed));
            }

            return(false);
        }
        public static bool TryGiveJob(ref Job __result, Pawn pawn)
        {
            int validationChecks        = 0;
            int validatorFalses1        = 0;
            int validatorFalses2        = 0;
            int validatorFalses3        = 0;
            int validatorFalses4        = 0;
            Predicate <Thing> validator = delegate(Thing t)
            {
                validationChecks++;
                if (t.IsForbidden(pawn))
                {
                    validatorFalses1++;
                    return(false);
                }

                if (!HaulAIUtility.PawnCanAutomaticallyHaulFast(pawn, t, forced: false))
                {
                    validatorFalses2++;
                    return(false);
                }

                if (pawn.carryTracker.MaxStackSpaceEver(t.def) <= 0)
                {
                    validatorFalses3++;
                    return(false);
                }

                IntVec3 foundCell;
                bool    tryFindBestBetterStoreCellFor = StoreUtility.TryFindBestBetterStoreCellFor(t, pawn, pawn.Map, StoreUtility.CurrentStoragePriorityOf(t), pawn.Faction, out foundCell) ? true : false;
                if (!tryFindBestBetterStoreCellFor)
                {
                    validatorFalses4++;
                }
                return(tryFindBestBetterStoreCellFor);
            };
            //Log.Error(pawn.Map.listerHaulables.ThingsPotentiallyNeedingHauling().Count.ToString());
            Thing thing = GenClosest.ClosestThing_Global_Reachable(pawn.Position, pawn.Map, pawn.Map.listerHaulables.ThingsPotentiallyNeedingHauling(), PathEndMode.OnCell, TraverseParms.For(pawn), 9999f, validator);

            if (validationChecks > 10)
            {
                Log.Error("Validator Checks: " + validationChecks.ToString() + " " + validatorFalses1.ToString() + " " + validatorFalses2.ToString() + " " + validatorFalses3.ToString() + " " + validatorFalses4.ToString() + " ");
            }
            if (thing != null)
            {
                __result = HaulAIUtility.HaulToStorageJob(pawn, thing);
                return(false);
            }
            __result = null;
            return(false);
        }
Esempio n. 21
0
        // This is a janky mess and a half, but works!
        protected override Job TryGiveJob(Pawn pawn)
        {
            Pawn_SurvivalToolAssignmentTracker assignmentTracker = pawn.TryGetComp <Pawn_SurvivalToolAssignmentTracker>();

            // Pawn can't use tools, lacks a tool assignment tracker or it isn't yet time to re-optimise tools
            if (!pawn.CanUseSurvivalTools() || assignmentTracker == null || Find.TickManager.TicksGame < assignmentTracker.nextSurvivalToolOptimizeTick)
            {
                return(null);
            }

            if (SurvivalToolsSettings.toolAutoDropExcess)
            {
                assignmentTracker.CheckToolsInUse();

                // Check if current tool assignment allows for each tool, auto-removing those that aren't allowed.
                SurvivalToolAssignment curAssignment = assignmentTracker.CurrentSurvivalToolAssignment;
                List <SurvivalTool>    heldTools     = pawn.GetHeldSurvivalTools();
                foreach (SurvivalTool tool in heldTools)
                {
                    if ((!curAssignment.filter.Allows(tool) || !pawn.NeedsSurvivalTool(tool) || !tool.InUse) && !tool.Forced &&
                        StoreUtility.TryFindBestBetterStoreCellFor(tool, pawn, pawn.Map, StoreUtility.CurrentStoragePriorityOf(tool), pawn.Faction, out IntVec3 c))
                    {
                        return(pawn.DequipAndTryStoreSurvivalTool(tool, true, c));
                    }
                }
            }
            if (SurvivalToolsSettings.toolOptimization)
            {
                SurvivalToolAssignment curAssignment     = assignmentTracker.CurrentSurvivalToolAssignment;
                List <StatDef>         workRelevantStats = pawn.AssignedToolRelevantWorkGiversStatDefs();
                List <Thing>           mapTools          = pawn.MapHeld.listerThings.AllThings.Where(t => t is SurvivalTool).ToList();

                SurvivalTool curTool    = null;
                SurvivalTool newTool    = null;
                float        optimality = 0f;
                foreach (StatDef stat in workRelevantStats)
                {
                    curTool    = pawn.GetBestSurvivalTool(stat);
                    optimality = SurvivalToolScore(curTool, workRelevantStats);
                    foreach (SurvivalTool potentialTool in mapTools)
                    {
                        if (StatUtility.StatListContains(potentialTool.WorkStatFactors.ToList(), stat) && curAssignment.filter.Allows(potentialTool) && potentialTool.BetterThanWorkingToollessFor(stat) &&
                            pawn.CanUseSurvivalTool(potentialTool.def) && potentialTool.IsInAnyStorage() && !potentialTool.IsForbidden(pawn) && !potentialTool.IsBurning())
                        {
                            float potentialOptimality = SurvivalToolScore(potentialTool, workRelevantStats);
                            float delta = potentialOptimality - optimality;
                            if (delta > 0f && pawn.CanReserveAndReach(potentialTool, PathEndMode.OnCell, pawn.NormalMaxDanger()))
                            {
                                newTool    = potentialTool;
                                optimality = potentialOptimality;
                            }
                        }
                    }
                    if (newTool != null)
                    {
                        break;
                    }
                }

                // Return a job based on whether or not a better tool was located

                // Failure
                if (newTool == null)
                {
                    SetNextOptimizeTick(pawn);
                    return(null);
                }

                // Success
                int heldToolOffset = 0;
                if (curTool != null && !curTool.Forced)
                {
                    pawn.jobs.jobQueue.EnqueueFirst(pawn.DequipAndTryStoreSurvivalTool(curTool, false));
                    heldToolOffset = -1;
                }
                if (pawn.CanCarryAnyMoreSurvivalTools(heldToolOffset))
                {
                    Job pickupJob = new Job(JobDefOf.TakeInventory, newTool)
                    {
                        count = 1
                    };
                    return(pickupJob);
                }
            }

            // Final failure state
            SetNextOptimizeTick(pawn);
            return(null);
        }
Esempio n. 22
0
        public static void RegisterHaulableItem(Thing haulableThing)
        {
            Map map = haulableThing.Map;

            if (map == null)
            {
                return;
            }

            if (haulableThing.IsForbidden(Faction.OfPlayer))
            {
                return;
            }
            //---SHOULD HELP WITH NOT HAULING ROCK CHUNKS---
            if (!haulableThing.def.EverHaulable)
            {
                return;
            }
            if (!haulableThing.def.alwaysHaulable && (map.designationManager.DesignationOn(haulableThing, DesignationDefOf.Haul) == null))
            {
                return;
            }
            //---SHOULD HELP WITH NOT HAULING ROCK CHUNKS---


            int num      = haulableThing.stackCount;
            int maxPawns = 1;

            if (map.physicalInteractionReservationManager.IsReserved(haulableThing))
            {
                //Log.Warning("IsReserved");
                return;
            }
            List <Reservation> reservations = ReservationManager_Patch.getReservationTargetList(map.reservationManager, haulableThing);

            if (reservations != null && reservations.Count > 0)
            {
                return;
            }
            int num3 = 0;
            int num4 = 0;
            List <Reservation> reservationTargetList = ReservationManager_Patch.getReservationTargetList(map.reservationManager, haulableThing);

            foreach (Reservation reservation in reservationTargetList)
            {
                if (reservation.Layer == null)
                {
                    if (reservation.Claimant != null && (reservation.StackCount == -1 || reservation.StackCount >= num))
                    {
                        break;
                    }
                    if (reservation.Claimant != null)
                    {
                        if (reservation.MaxPawns != maxPawns)
                        {
                            //Log.Warning("maxPawns");
                            return;
                        }

                        num3++;
                        num4 = (reservation.StackCount != -1) ? (num4 + reservation.StackCount) : (num4 + num);
                        if (num3 >= maxPawns || num + num4 > num)
                        {
                            //Log.Warning(reservation.Claimant.ToString() + " StackCount");
                            return;
                        }
                    }
                }
            }

            int storagePriority = (int)StoreUtility.CurrentStoragePriorityOf(haulableThing);

            if (TryFindBestBetterStoreCellFor(haulableThing, null, map, StoreUtility.CurrentStoragePriorityOf(haulableThing), null, out _, false) && //fast check
                HaulToStorageJobTest(haulableThing))                                                                                                 //slower check
            {
                AddThingToAwaitingHaulingHashSets(haulableThing);
            }
            else
            {
                HashSet <Thing> things = getWaitingForZoneBetterThan(map)[storagePriority];
                lock (things)
                {
                    things.Add(haulableThing);
                }
            }
        }
            static ProximityStage CanHaul(ProximityStage proximityStage, Pawn pawn, Thing thing, IntVec3 jobCell, ProximityCheck proximityCheck, out IntVec3 storeCell)
            {
                storeCell = IntVec3.Invalid;
                var pawnToJob = pawn.Position.DistanceTo(jobCell);

                var pawnToThing = pawn.Position.DistanceTo(thing.Position);

                if (proximityStage < ProximityStage.StoreToJob)
                {
                    var atMax           = maxStartToThing.Value > 0 && pawnToThing > maxStartToThing.Value;
                    var atMaxPct        = maxStartToThingPctOrigTrip.Value > 0 && pawnToThing > pawnToJob * maxStartToThingPctOrigTrip.Value;
                    var pawnToThingFail = atMax || atMaxPct;
                    switch (proximityCheck)
                    {
                    case ProximityCheck.Both when pawnToThingFail: return(ProximityStage.PawnToThing);
                    }

                    var thingToJob = thing.Position.DistanceTo(jobCell);
                    // if this one exceeds the maximum the next maxTotalTripPctOrigTrip check certainly will
                    if (maxTotalTripPctOrigTrip.Value > 0 && pawnToThing + thingToJob > pawnToJob * maxTotalTripPctOrigTrip.Value)
                    {
                        return(ProximityStage.Fail);
                    }
                    if (pawn.Map.reservationManager.FirstRespectedReserver(thing, pawn) != null)
                    {
                        return(ProximityStage.Fail);
                    }
                    if (thing.IsForbidden(pawn))
                    {
                        return(ProximityStage.Fail);
                    }
                    if (!HaulAIUtility.PawnCanAutomaticallyHaulFast(pawn, thing, false))
                    {
                        return(ProximityStage.Fail);
                    }
                }

                // we need storeCell everywhere, so cache it
                if (!cachedStoreCell.TryGetValue(thing, out storeCell))
                {
                    var currentPriority = StoreUtility.CurrentStoragePriorityOf(thing);
                    if (!StoreUtility.TryFindBestBetterStoreCellFor(thing, pawn, pawn.Map, currentPriority, pawn.Faction, out storeCell))
                    {
                        return(ProximityStage.Fail);
                    }
                }

                cachedStoreCell.SetOrAdd(thing, storeCell);

                var storeToJob = storeCell.DistanceTo(jobCell);

                if (proximityStage < ProximityStage.PawnToThingRegion)
                {
                    var atMax2         = maxStoreToJob.Value > 0 && storeToJob > maxStoreToJob.Value;
                    var atMaxPct2      = maxStoreToJobPctOrigTrip.Value > 0 && storeToJob > pawnToJob * maxStoreToJobPctOrigTrip.Value;
                    var storeToJobFail = atMax2 || atMaxPct2;
                    switch (proximityCheck)
                    {
                    case ProximityCheck.Both when storeToJobFail: return(ProximityStage.StoreToJob);

                    case ProximityCheck.Either when proximityStage == ProximityStage.PawnToThing && storeToJobFail: return(ProximityStage.StoreToJob);
                    }

                    var thingToStore = thing.Position.DistanceTo(storeCell);
                    if (maxTotalTripPctOrigTrip.Value > 0 && pawnToThing + thingToStore + storeToJob > pawnToJob * maxTotalTripPctOrigTrip.Value)
                    {
                        return(ProximityStage.Fail);
                    }
                    if (maxNewLegsPctOrigTrip.Value > 0 && pawnToThing + storeToJob > pawnToJob * maxNewLegsPctOrigTrip.Value)
                    {
                        return(ProximityStage.Fail);
                    }
                }

                bool PawnToThingRegionFail()
                {
                    return(maxStartToThingRegionLookCount.Value > 0 && !pawn.Position.WithinRegions(thing.Position, pawn.Map, maxStartToThingRegionLookCount.Value, TraverseParms.For(pawn)));
                }

                bool StoreToJobRegionFail(IntVec3 _storeCell)
                {
                    return(maxStoreToJobRegionLookCount.Value > 0 && !_storeCell.WithinRegions(jobCell, pawn.Map, maxStoreToJobRegionLookCount.Value, TraverseParms.For(pawn)));
                }

                switch (proximityCheck)
                {
                case ProximityCheck.Both when PawnToThingRegionFail(): return(ProximityStage.PawnToThingRegion);

                case ProximityCheck.Both when StoreToJobRegionFail(storeCell): return(ProximityStage.Fail);

                case ProximityCheck.Either when proximityStage == ProximityStage.PawnToThingRegion && StoreToJobRegionFail(storeCell): return(ProximityStage.Fail);
                }

                return(ProximityStage.Success);
            }
        /// <inheritdoc/>
        public override ThinkResult TryIssueJobPackage(Pawn pawn, JobIssueParams jobParams)
        {
            if (pawn?.inventory?.innerContainer == null)
            {
                return(ThinkResult.NoJob);
            }

            if (!pawn.UseLoadout(out CompAwesomeInventoryLoadout comp))
            {
                return(ThinkResult.NoJob);
            }

            foreach (Thing thing in pawn.inventory.innerContainer)
            {
                if (thing is Apparel apparel)
                {
                    bool extra = true;
                    CompAwesomeInventoryLoadout.ThingGroupSelectorPool pool = comp.FindPotentialThingGroupSelectors(thing, comp.Loadout);
                    if (pool.OrderedSelectorTuples.Any())
                    {
                        foreach (var tuple in pool.OrderedSelectorTuples)
                        {
                            if (!(comp.InventoryMargins[tuple.Item2] > 0))
                            {
                                extra = false;
                                break;
                            }
                        }
                    }

                    if (extra)
                    {
                        if (StoreUtility.TryFindBestBetterStorageFor(apparel, pawn, pawn.Map, StoreUtility.CurrentStoragePriorityOf(apparel), pawn.Faction, out _, out _))
                        {
                            UnloadApparelJob job = new UnloadApparelJob(thing);
                            return(new ThinkResult(job, this, JobTag.UnloadingOwnInventory));
                        }
                    }
                }
            }

            return(ThinkResult.NoJob);
        }
        public Job TryOpportunisticJob(Job job)
        {
            Job result;

            if (this.pawn.def.race.intelligence < Intelligence.Humanlike)
            {
                result = null;
            }
            else if (this.pawn.Faction != Faction.OfPlayer)
            {
                result = null;
            }
            else if (this.pawn.Drafted)
            {
                result = null;
            }
            else if (job.playerForced)
            {
                result = null;
            }
            else if (this.pawn.RaceProps.intelligence < Intelligence.Humanlike)
            {
                result = null;
            }
            else if (!job.def.allowOpportunisticPrefix)
            {
                result = null;
            }
            else if (this.pawn.story.WorkTagIsDisabled(WorkTags.ManualDumb | WorkTags.Hauling))
            {
                result = null;
            }
            else if (this.pawn.InMentalState)
            {
                result = null;
            }
            else
            {
                IntVec3 cell = job.targetA.Cell;
                if (!cell.IsValid)
                {
                    result = null;
                }
                else
                {
                    float num = this.pawn.Position.DistanceTo(cell);
                    if (num < AITuning.OpportunisticJobMinDistPawnToDest)
                    {
                        result = null;
                    }
                    else
                    {
                        List <Thing> list = this.pawn.Map.listerHaulables.ThingsPotentiallyNeedingHauling();
                        for (int i = 0; i < list.Count; i++)
                        {
                            Thing thing = list[i];
                            if (this.pawn.Map.reservationManager.FirstRespectedReserver(thing, this.pawn) == null)
                            {
                                float num2 = this.pawn.Position.DistanceTo(thing.Position);
                                if (num2 <= AITuning.OpportunisticJobMaxDistPawnToItem)
                                {
                                    if (num2 <= num * AITuning.OpportunisticJobMaxPickupDistanceFactor)
                                    {
                                        if (num2 + thing.Position.DistanceTo(cell) <= num * AITuning.OpportunisticJobMaxRatioOppHaulDistanceToDestDistance)
                                        {
                                            if (HaulAIUtility.PawnCanAutomaticallyHaulFast(this.pawn, thing, false))
                                            {
                                                StoragePriority currentPriority = StoreUtility.CurrentStoragePriorityOf(thing);
                                                IntVec3         invalid         = IntVec3.Invalid;
                                                if (StoreUtility.TryFindBestBetterStoreCellFor(thing, this.pawn, this.pawn.Map, currentPriority, this.pawn.Faction, out invalid, true))
                                                {
                                                    float num3 = invalid.DistanceTo(cell);
                                                    if (num3 <= AITuning.OpportunisticJobMaxDistDestToDropoff)
                                                    {
                                                        if (num3 <= num * AITuning.OpportunisticJobMaxDistDestToDropoffFactor)
                                                        {
                                                            if (num2 + thing.Position.DistanceTo(invalid) + num3 <= num * AITuning.OpportunisticJobMaxRatioOppHaulDistanceToDestDistance)
                                                            {
                                                                if (num2 + num3 <= num)
                                                                {
                                                                    if (this.pawn.Position.WithinRegions(thing.Position, this.pawn.Map, AITuning.OpportunisticJobMaxPickupRegions, TraverseParms.For(this.pawn, Danger.Deadly, TraverseMode.ByPawn, false), RegionType.Set_Passable))
                                                                    {
                                                                        if (invalid.WithinRegions(cell, this.pawn.Map, AITuning.OpportunisticJobMaxDropoffRegions, TraverseParms.For(this.pawn, Danger.Deadly, TraverseMode.ByPawn, false), RegionType.Set_Passable))
                                                                        {
                                                                            if (DebugViewSettings.drawOpportunisticJobs)
                                                                            {
                                                                                Log.Message("Opportunistic job spawned", false);
                                                                                this.pawn.Map.debugDrawer.FlashLine(this.pawn.Position, thing.Position, 600, SimpleColor.Red);
                                                                                this.pawn.Map.debugDrawer.FlashLine(thing.Position, invalid, 600, SimpleColor.Green);
                                                                                this.pawn.Map.debugDrawer.FlashLine(invalid, cell, 600, SimpleColor.Blue);
                                                                            }
                                                                            return(HaulAIUtility.HaulToCellStorageJob(this.pawn, thing, invalid, false));
                                                                        }
                                                                    }
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        result = null;
                    }
                }
            }
            return(result);
        }
Esempio n. 26
0
        // Token: 0x0600005B RID: 91 RVA: 0x00004104 File Offset: 0x00002304
        protected override IEnumerable <Toil> MakeNewToils()
        {
            var   toilSwapback    = new Toil();
            var   toilReturnStock = new Toil();
            var   toilDrop        = new Toil();
            var   toilDropHome    = new Toil();
            Thing resultingThing  = null;
            var   FETakeBack      = (ThingWithComps)job.GetTarget(TargetIndex.A).Thing;
            var   FETBSwapType    = (FETakeBack as FireWardenData)?.FWSwapType;
            var   DebugMsg        = "";

            toilSwapback.initAction = delegate
            {
                if (!FWHasFE(pawn) || resultingThing == null)
                {
                    return;
                }

                if (FWDebug)
                {
                    DebugMsg = pawn.Label + " in toil Swapback";
                    Messages.Message(DebugMsg, pawn, MessageTypeDefOf.NeutralEvent, false);
                }

                if (job.GetTarget(TargetIndex.B) != null)
                {
                    var RemoveThing    = job.GetTarget(TargetIndex.B).Thing;
                    var invGearToEquip = (ThingWithComps)RemoveThing;
                    if (pawn.inventory.innerContainer.Contains(RemoveThing) && pawn.equipment.Primary != invGearToEquip)
                    {
                        pawn.inventory.innerContainer.Remove(RemoveThing);
                        pawn.equipment.MakeRoomFor(invGearToEquip);
                        pawn.equipment.AddEquipment(invGearToEquip);
                    }
                }

                FETakeBack = (ThingWithComps)job.GetTarget(TargetIndex.A).Thing;
                FEResetVars(FETakeBack);
                FETBSwapType = (FETakeBack as FireWardenData)?.FWSwapType;
                pawn.jobs.EndCurrentJob(JobCondition.Succeeded);
            };
            toilSwapback.AddFailCondition(() => FETBSwapType != "ER");
            toilSwapback.FailOnDespawnedOrNull(TargetIndex.A);
            toilSwapback.FailOnDespawnedOrNull(TargetIndex.B);
            toilSwapback.defaultCompleteMode = ToilCompleteMode.Delay;
            yield return(toilSwapback);

            if (pawn.equipment.Primary == null || pawn.equipment.Primary.def.defName != FEDefName ||
                (pawn.equipment.Primary as FireWardenData)?.FWSwapType != "ER" ||
                ((FireWardenData)pawn.equipment.Primary).FWPawnID != pawn.thingIDNumber)
            {
                yield break;
            }

            var currentPriority = StoreUtility.CurrentStoragePriorityOf(job.GetTarget(TargetIndex.A).Thing);
            var dumpAtHome      = false;

            if (Controller.Settings.ReturnToSpot)
            {
                dumpAtHome = true;
            }
            else
            {
                if (pawn.equipment.Primary == (ThingWithComps)job.GetTarget(TargetIndex.A).Thing)
                {
                    pawn.equipment.TryDropEquipment(pawn.equipment.Primary, out _, pawn.Position, false);
                    pawn.carryTracker.TryStartCarry(job.GetTarget(TargetIndex.A).Thing, 1);
                }

                if (!StoreUtility.TryFindBestBetterStorageFor(job.GetTarget(TargetIndex.A).Thing, pawn, pawn.Map,
                                                              currentPriority, pawn.Faction, out _, out var haulDestination))
                {
                    dumpAtHome = true;
                }
                else
                {
                    toilReturnStock.initAction = delegate
                    {
                        if (FWDebug)
                        {
                            DebugMsg = pawn.Label + " in toil ReturnStock";
                            Messages.Message(DebugMsg, pawn, MessageTypeDefOf.NeutralEvent, false);
                        }

                        if (pawn.carryTracker.CarriedThing != job.GetTarget(TargetIndex.A).Thing)
                        {
                            return;
                        }

                        var destCell = haulDestination.Position;
                        pawn.Map.pawnDestinationReservationManager.Reserve(pawn, job, destCell);
                        pawn.pather.StartPath(destCell, PathEndMode.ClosestTouch);
                    };
                    toilReturnStock.AddFailCondition(() => FETBSwapType != "ER");
                    toilReturnStock.FailOnDespawnedOrNull(TargetIndex.A);
                    toilReturnStock.defaultCompleteMode = ToilCompleteMode.PatherArrival;
                    yield return(toilReturnStock);

                    toilDrop.initAction = delegate
                    {
                        if (!((haulDestination.Position - pawn.Position).LengthHorizontal <= 2f))
                        {
                            return;
                        }

                        if (pawn.carryTracker.CarriedThing == job.GetTarget(TargetIndex.A).Thing)
                        {
                            if (!pawn.carryTracker.TryDropCarriedThing(pawn.Position, ThingPlaceMode.Near,
                                                                       out resultingThing))
                            {
                                return;
                            }

                            dumpAtHome = false;
                            if (job.GetTarget(TargetIndex.B) != null)
                            {
                                return;
                            }

                            FETakeBack = (ThingWithComps)job.GetTarget(TargetIndex.A).Thing;
                            FEResetVars(FETakeBack);
                            FETBSwapType = (FETakeBack as FireWardenData)?.FWSwapType;
                            pawn.jobs.EndCurrentJob(JobCondition.Succeeded);
                        }
                        else
                        {
                            dumpAtHome = true;
                        }
                    };
                    toilSwapback.AddFailCondition(() => FETBSwapType != "ER");
                    toilDrop.FailOnDespawnedOrNull(TargetIndex.A);
                    toilDrop.defaultCompleteMode = ToilCompleteMode.FinishedBusy;
                    yield return(toilDrop);
                }
            }

            if (!dumpAtHome)
            {
                yield break;
            }

            var ReturnCell = pawn.Position;

//            if (false)
//            {
//                /*
//                            {
//                                toilReturnHome.initAction = delegate
//                                {
//                                    if (FWDebug)
//                                    {
//                                        DebugMsg = pawn.Label + " in toil ReturnHome";
//                                        Messages.Message(DebugMsg, pawn, MessageTypeDefOf.NeutralEvent, false);
//                                    }
//                                    if (pawn.equipment.Primary == (ThingWithComps)job.GetTarget(TargetIndex.A).Thing)
//                                    {
//                                        pawn.equipment.TryDropEquipment(pawn.equipment.Primary, out _, pawn.Position, false);
//                                        pawn.carryTracker.TryStartCarry(job.GetTarget(TargetIndex.A).Thing, 1);
//                                    }
//
//                                    if (pawn.carryTracker.CarriedThing != job.GetTarget(TargetIndex.A).Thing)
//                                    {
//                                        return;
//                                    }
//
//                                    pawn.Map.pawnDestinationReservationManager.Reserve(pawn, job, ReturnCell);
//                                    pawn.pather.StartPath(ReturnCell, PathEndMode.ClosestTouch);
//                                };
//                                toilReturnHome.AddFailCondition(() => FETBSwapType != "ER");
//                                toilReturnHome.FailOnDespawnedOrNull(TargetIndex.A);
//                                toilReturnHome.defaultCompleteMode = ToilCompleteMode.PatherArrival;
//                                yield return toilReturnHome;
//                            }
//                */
//            }
            if (pawn.equipment.Primary == (ThingWithComps)job.GetTarget(TargetIndex.A).Thing)
            {
                pawn.equipment.TryDropEquipment(pawn.equipment.Primary, out _, pawn.Position, false);
                pawn.carryTracker.TryStartCarry(job.GetTarget(TargetIndex.A).Thing, 1);
            }

            toilDropHome.initAction = delegate
            {
                if (!((ReturnCell - pawn.Position).LengthHorizontal <= 2f) ||
                    pawn.carryTracker.CarriedThing != job.GetTarget(TargetIndex.A).Thing ||
                    !pawn.carryTracker.TryDropCarriedThing(pawn.Position, ThingPlaceMode.Near, out resultingThing) ||
                    job.GetTarget(TargetIndex.B) != null)
                {
                    return;
                }

                FETakeBack = (ThingWithComps)job.GetTarget(TargetIndex.A).Thing;
                FEResetVars(FETakeBack);
                FETBSwapType = (FETakeBack as FireWardenData)?.FWSwapType;
                pawn.jobs.EndCurrentJob(JobCondition.Succeeded);
            };
            toilDropHome.AddFailCondition(() => FETBSwapType != "ER");
            toilDropHome.FailOnDespawnedOrNull(TargetIndex.A);
            toilDropHome.defaultCompleteMode = ToilCompleteMode.FinishedBusy;
            yield return(toilDropHome);
        }
Esempio n. 27
0
        public Job TryOpportunisticJob(Job job)
        {
            if ((int)pawn.def.race.intelligence < 2)
            {
                return(null);
            }
            if (pawn.Faction != Faction.OfPlayer)
            {
                return(null);
            }
            if (pawn.Drafted)
            {
                return(null);
            }
            if (job.playerForced)
            {
                return(null);
            }
            if ((int)pawn.RaceProps.intelligence < 2)
            {
                return(null);
            }
            if (!job.def.allowOpportunisticPrefix)
            {
                return(null);
            }
            if (pawn.WorkTagIsDisabled(WorkTags.ManualDumb | WorkTags.Hauling))
            {
                return(null);
            }
            if (pawn.InMentalState || pawn.IsBurning())
            {
                return(null);
            }
            IntVec3 cell = job.targetA.Cell;

            if (!cell.IsValid || cell.IsForbidden(pawn))
            {
                return(null);
            }
            float num = pawn.Position.DistanceTo(cell);

            if (num < 3f)
            {
                return(null);
            }
            List <Thing> list = pawn.Map.listerHaulables.ThingsPotentiallyNeedingHauling();

            for (int i = 0; i < list.Count; i++)
            {
                Thing thing = list[i];
                float num2  = pawn.Position.DistanceTo(thing.Position);
                if (num2 > 30f || num2 > num * 0.5f || num2 + thing.Position.DistanceTo(cell) > num * 1.7f || pawn.Map.reservationManager.FirstRespectedReserver(thing, pawn) != null || thing.IsForbidden(pawn) || !HaulAIUtility.PawnCanAutomaticallyHaulFast(pawn, thing, forced: false))
                {
                    continue;
                }
                StoragePriority currentPriority = StoreUtility.CurrentStoragePriorityOf(thing);
                IntVec3         foundCell       = IntVec3.Invalid;
                if (!StoreUtility.TryFindBestBetterStoreCellFor(thing, pawn, pawn.Map, currentPriority, pawn.Faction, out foundCell))
                {
                    continue;
                }
                float num3 = foundCell.DistanceTo(cell);
                if (!(num3 > 50f) && !(num3 > num * 0.6f) && !(num2 + thing.Position.DistanceTo(foundCell) + num3 > num * 1.7f) && !(num2 + num3 > num) && pawn.Position.WithinRegions(thing.Position, pawn.Map, 25, TraverseParms.For(pawn)) && foundCell.WithinRegions(cell, pawn.Map, 25, TraverseParms.For(pawn)))
                {
                    if (DebugViewSettings.drawOpportunisticJobs)
                    {
                        Log.Message("Opportunistic job spawned");
                        pawn.Map.debugDrawer.FlashLine(pawn.Position, thing.Position, 600, SimpleColor.Red);
                        pawn.Map.debugDrawer.FlashLine(thing.Position, foundCell, 600, SimpleColor.Green);
                        pawn.Map.debugDrawer.FlashLine(foundCell, cell, 600, SimpleColor.Blue);
                    }
                    return(HaulAIUtility.HaulToCellStorageJob(pawn, thing, foundCell, fitInStoreCell: false));
                }
            }
            return(null);
        }
Esempio n. 28
0
        private Toil Collect()
        {
            return(new Toil()
            {
                initAction = delegate
                {
                    // Increment the record for how many cells this pawn has mined since this counts as mining
                    // TODO: B19 - change to quarry m3
                    pawn.records.Increment(RecordDefOf.CellsMined);

                    // Start with None to act as a fallback. Rubble will be returned with this parameter
                    ResourceRequest req = ResourceRequest.None;

                    // Use the mineModeToggle to determine the request
                    req = (ResourceRequest)(((int)Quarry.mineModeToggle) + 1);

                    MoteType mote = MoteType.None;
                    int stackCount = 1;

                    // Get the resource from the quarry
                    ThingDef def = Quarry.GiveResources(req, out mote, out bool singleSpawn, out bool eventTriggered);
                    // If something went wrong, bail out
                    if (def == null || def.thingClass == null)
                    {
                        Log.Warning("Quarry:: Tried to quarry mineable ore, but the ore given was null.");
                        mote = MoteType.None;
                        singleSpawn = true;
                        // This shouldn't happen at all, but if it does let's add a little reward instead of just giving rubble
                        def = ThingDefOf.ChunkSlagSteel;
                    }

                    Thing haulableResult = ThingMaker.MakeThing(def);
                    if (!singleSpawn && def != ThingDefOf.ComponentIndustrial)
                    {
                        int sub = (int)(def.BaseMarketValue / 2f);
                        sub = Mathf.Clamp(sub, 0, 10);

                        stackCount += Mathf.Min(Rand.RangeInclusive(15 - sub, 40 - (sub * 2)), def.stackLimit - 1);
                    }

                    if (def == ThingDefOf.ComponentIndustrial)
                    {
                        stackCount += Random.Range(0, 1);
                    }

                    haulableResult.stackCount = stackCount;

                    if (stackCount >= 30)
                    {
                        mote = MoteType.LargeVein;
                    }

                    bool usesQuality = false;
                    // Adjust quality for items that use it
                    if (haulableResult.TryGetComp <CompQuality>() != null)
                    {
                        usesQuality = true;
                        haulableResult.TryGetComp <CompQuality>().SetQuality(QualityUtility.GenerateQualityTraderItem(), ArtGenerationContext.Outsider);
                    }
                    // Adjust hitpoints, this was just mined from under the ground after all
                    if (def.useHitPoints && !def.thingCategories.Contains(QuarryDefOf.StoneChunks) && def != ThingDefOf.ComponentIndustrial)
                    {
                        float minHpThresh = 0.25f;
                        if (usesQuality)
                        {
                            minHpThresh = Mathf.Clamp((float)haulableResult.TryGetComp <CompQuality>().Quality / 10f, 0.1f, 0.7f);
                        }
                        int hp = Mathf.RoundToInt(Rand.Range(minHpThresh, 1f) * haulableResult.MaxHitPoints);
                        hp = Mathf.Max(1, hp);
                        haulableResult.HitPoints = hp;
                    }

                    // Place the resource near the pawn
                    GenPlace.TryPlaceThing(haulableResult, pawn.Position, Map, ThingPlaceMode.Near);

                    // If the resource had a mote, throw it
                    if (mote == MoteType.LargeVein)
                    {
                        MoteMaker.ThrowText(haulableResult.DrawPos, Map, Static.TextMote_LargeVein, Color.green, 3f);
                    }
                    else if (mote == MoteType.Failure)
                    {
                        MoteMaker.ThrowText(haulableResult.DrawPos, Map, Static.TextMote_MiningFailed, Color.red, 3f);
                    }

                    // If the sinkhole event was triggered, damage the pawn and end this job
                    // Even if the sinkhole doesn't incapacitate the pawn, they will probably want to seek medical attention
                    if (eventTriggered)
                    {
                        NamedArgument pawnName = new NamedArgument(0, pawn.NameShortColored);
                        Messages.Message("QRY_MessageSinkhole".Translate(pawnName), pawn, MessageTypeDefOf.NegativeEvent);
                        DamageInfo dInfo = new DamageInfo(DamageDefOf.Crush, 9, category: DamageInfo.SourceCategory.Collapse);
                        dInfo.SetBodyRegion(BodyPartHeight.Bottom, BodyPartDepth.Inside);
                        pawn.TakeDamage(dInfo);

                        EndJobWith(JobCondition.Succeeded);
                    }
                    else
                    {
                        // Prevent the colonists from trying to haul rubble, which just makes them visit the platform
                        if (def == ThingDefOf.Filth_RubbleRock)
                        {
                            EndJobWith(JobCondition.Succeeded);
                        }
                        else
                        {
                            // If this is a chunk or slag, mark it as haulable if allowed to
                            if (def.designateHaulable && Quarry.autoHaul)
                            {
                                Map.designationManager.AddDesignation(new Designation(haulableResult, DesignationDefOf.Haul));
                            }

                            // Try to find a suitable storage spot for the resource, removing it from the quarry
                            // If there are no platforms with free space, or if the resource is a chunk, try to haul it to a storage area
                            if (Quarry.autoHaul)
                            {
                                if (!def.thingCategories.Contains(QuarryDefOf.StoneChunks) && Quarry.HasConnectedPlatform && Quarry.TryFindBestPlatformCell(haulableResult, pawn, Map, pawn.Faction, out IntVec3 c))
                                {
                                    job.SetTarget(TargetIndex.B, haulableResult);
                                    job.count = haulableResult.stackCount;
                                    job.SetTarget(TargetIndex.C, c);
                                }
                                else
                                {
                                    StoragePriority currentPriority = StoreUtility.CurrentStoragePriorityOf(haulableResult);
                                    Job result;
                                    if (!StoreUtility.TryFindBestBetterStorageFor(haulableResult, pawn, Map, currentPriority, pawn.Faction, out c, out IHaulDestination haulDestination, true))
                                    {
                                        JobFailReason.Is("NoEmptyPlaceLower".Translate(), null);
                                    }
                                    else if (haulDestination is ISlotGroupParent)
                                    {
                                        result = HaulAIUtility.HaulToCellStorageJob(pawn, haulableResult, c, false);
                                    }
                                    else
                                    {
                                        job.SetTarget(TargetIndex.B, haulableResult);
                                        job.count = haulableResult.stackCount;
                                        job.SetTarget(TargetIndex.C, c);
                                    }
                                }
                            }
Esempio n. 29
0
 private bool HasNoHaulDestination(Thing t)
 {
     return(!StoreUtility.TryFindBestBetterStorageFor(t, null, t.Map, StoreUtility.CurrentStoragePriorityOf(t),
                                                      Faction.OfPlayer, out IntVec3 _, out IHaulDestination _));
 }
        protected override IEnumerable <Toil> MakeNewToils()
        {
            CompUniversalFermenter comp = Fermenter.TryGetComp <CompUniversalFermenter>();

            // Verify fermenter validity
            this.FailOn(() => !comp.Fermented);
            this.FailOnDestroyedNullOrForbidden(FermenterInd);

            // Reserve fermenter
            yield return(Toils_Reserve.Reserve(FermenterInd));

            // Go to the fermenter
            yield return(Toils_Goto.GotoThing(FermenterInd, PathEndMode.ClosestTouch));

            // Add delay for collecting product from fermenter, if it is ready
            yield return(Toils_General.Wait(Duration).FailOnDestroyedNullOrForbidden(FermenterInd).WithProgressBarToilDelay(FermenterInd));

            // Collect product
            Toil collect = new Toil();

            collect.initAction = () =>
            {
                Thing product = comp.TakeOutProduct();
                GenPlace.TryPlaceThing(product, pawn.Position, Map, ThingPlaceMode.Near);
                StoragePriority storagePriority = StoreUtility.CurrentStoragePriorityOf(product);
                IntVec3         c;

                // Try to find a suitable storage spot for the product
                if (StoreUtility.TryFindBestBetterStoreCellFor(product, pawn, Map, storagePriority, pawn.Faction, out c))
                {
                    this.job.SetTarget(TargetIndex.B, product);
                    this.job.count = product.stackCount;
                    this.job.SetTarget(TargetIndex.C, c);
                }
                // If there is no spot to store the product, end this job
                else
                {
                    EndJobWith(JobCondition.Incompletable);
                }
            };
            collect.defaultCompleteMode = ToilCompleteMode.Instant;
            yield return(collect);

            // Reserve the product
            yield return(Toils_Reserve.Reserve(ProductToHaulInd));

            // Reserve the storage cell
            yield return(Toils_Reserve.Reserve(StorageCellInd));

            // Go to the product
            yield return(Toils_Goto.GotoThing(ProductToHaulInd, PathEndMode.ClosestTouch));

            // Pick up the product
            yield return(Toils_Haul.StartCarryThing(ProductToHaulInd));

            // Carry the product to the storage cell, then place it down
            Toil carry = Toils_Haul.CarryHauledThingToCell(StorageCellInd);

            yield return(carry);

            yield return(Toils_Haul.PlaceHauledThingInCell(StorageCellInd, carry, true));

            // End the current job
            yield break;
        }