Esempio n. 1
0
 static bool UsePuahFirstUnloadableThing(ref ThingCount __result, Pawn pawn)
 {
     if (!haulToInventory.Value || !enabled.Value)
     {
         return(true);
     }
     __result = JooStoreUtility.PuahFirstUnloadableThing(pawn);
     return(false);
 }
Esempio n. 2
0
 static bool UsePuahAllocateThingAtCell_GetStore(ref bool __result, Thing thing, Pawn carrier, Map map, StoragePriority currentPriority, Faction faction,
                                                 ref IntVec3 foundCell)
 {
     if (!haulToInventory.Value || !enabled.Value)
     {
         return(true);
     }
     __result = JooStoreUtility.PuahAllocateThingAtCell_GetStore(thing, carrier, map, currentPriority, faction, out foundCell);
     return(false);
 }
Esempio n. 3
0
                static Job HaulBeforeSupply(Pawn pawn, Thing constructible, Thing th)
                {
                    if (!haulBeforeSupply.Value || !enabled.Value)
                    {
                        return(null);
                    }
                    if (JooStoreUtility.PuahHasThingsHauled(pawn))
                    {
                        Debug.WriteLine($"{RealTime.frameCount} {pawn} Aborting {MethodBase.GetCurrentMethod().Name}() already holding items.");
                        return(null);
                    }

                    return(Helper.CatchStanding(pawn, Hauling.HaulBeforeCarry(pawn, constructible.Position, th)));
                }
Esempio n. 4
0
                static bool UseTryFindBestBetterStoreCellFor_ClosestToDestCell(Thing t, Pawn carrier, Map map, StoragePriority currentPriority, Faction faction,
                                                                               out IntVec3 foundCell,
                                                                               bool needAccurateResult)
                {
                    if (!haulToInventory.Value || !enabled.Value)
                    {
                        return(StoreUtility.TryFindBestBetterStoreCellFor(t, carrier, map, currentPriority, faction, out foundCell, needAccurateResult));
                    }

                    var haulTracker = haulTrackers.GetValueSafe(carrier);

                    return(JooStoreUtility.TryFindBestBetterStoreCellFor_ClosestToDestCell(
                               t, haulTracker?.destCell ?? IntVec3.Invalid, carrier, map, currentPriority, faction, out foundCell, haulTracker?.destCell.IsValid ?? false));
                }
            static Job TryOpportunisticJob(Pawn_JobTracker jobTracker, Job job)
            {
//                Debug.WriteLine($"Opportunity checking {job}");
                var pawn = Traverse.Create(jobTracker).Field("pawn").GetValue <Pawn>();

                if (JooStoreUtility.PuahHasThingsHauled(pawn))
                {
                    Debug.WriteLine($"{RealTime.frameCount} {pawn} Aborting {MethodBase.GetCurrentMethod().Name}() during {job}; already holding items.");
                    return(null);
                }

                var jobCell = job.targetA.Cell;

                if (job.def == JobDefOf.DoBill && haulBeforeBill.Value && enabled.Value)
                {
//                    Debug.WriteLine($"Bill: '{job.bill}' label: '{job.bill.Label}'");
//                    Debug.WriteLine($"Recipe: '{job.bill.recipe}' workerClass: '{job.bill.recipe.workerClass}'");
                    foreach (var localTargetInfo in job.targetQueueB)
                    {
                        if (localTargetInfo.Thing == null)
                        {
                            continue;
                        }

                        if (HaulAIUtility.PawnCanAutomaticallyHaulFast(pawn, localTargetInfo.Thing, false))
                        {
                            // permitted when bleeding because facilitates whatever bill is important enough to do while bleeding
                            //  may save precious time going back for ingredients... unless we want only 1 medicine ASAP; it's a trade-off
                            var storeJob = Hauling.HaulBeforeCarry(pawn, jobCell, localTargetInfo.Thing);
                            if (storeJob != null)
                            {
                                return(Helper.CatchStanding(pawn, storeJob));
                            }
                        }
                    }
                }

                if (skipIfBleeding.Value && pawn.health.hediffSet.BleedRateTotal > 0.001f)
                {
                    return(null);
                }
//                return Helper.CatchStanding(pawn, Hauling.TryHaul(pawn, jobCell) ?? Cleaning.TryClean(pawn, jobCell));
                return(Helper.CatchStanding(pawn, Hauling.TryHaul(pawn, jobCell)));
            }
Esempio n. 6
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. 7
0
            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);
                    }
                }

                var currentPriority = StoreUtility.CurrentStoragePriorityOf(thing);

                if (!JooStoreUtility.TryFindBestBetterStoreCellFor_ClosestToDestCell(thing, IntVec3.Invalid, pawn, pawn.Map, currentPriority, pawn.Faction, out storeCell, true))
                {
                    return(ProximityStage.Fail);
                }

                // we need storeCell everywhere, so cache it
                cachedOpportunityStoreCell.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);
            }