예제 #1
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));
                }
예제 #2
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);
            }
예제 #3
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);
            }