예제 #1
0
        private static bool TryFindBestBillIngredients(Bill bill, Pawn pawn, Thing billGiver, List <ThingCount> chosen)
        {
            chosen.Clear();
            newRelevantThings.Clear();
            if (bill.recipe.ingredients.Count == 0)
            {
                return(true);
            }
            IntVec3 rootCell = GetBillGiverRootCell(billGiver, pawn);
            Region  rootReg  = rootCell.GetRegion(pawn.Map);

            if (rootReg == null)
            {
                return(false);
            }
            MakeIngredientsListInProcessingOrder(ingredientsOrdered, bill);
            relevantThings.Clear();
            processedThings.Clear();
            bool foundAll = false;
            Predicate <Thing> baseValidator = (Thing t) => t.Spawned && !t.IsForbidden(pawn) && (float)(t.Position - billGiver.Position).LengthHorizontalSquared < bill.ingredientSearchRadius * bill.ingredientSearchRadius && bill.IsFixedOrAllowedIngredient(t) && bill.recipe.ingredients.Any((IngredientCount ingNeed) => ingNeed.filter.Allows(t)) && pawn.CanReserve(t);
            bool billGiverIsPawn            = billGiver is Pawn;

            if (billGiverIsPawn)
            {
                AddEveryMedicineToRelevantThings(pawn, billGiver, relevantThings, baseValidator, pawn.Map);
                if (TryFindBestBillIngredientsInSet(relevantThings, bill, chosen, rootCell, billGiverIsPawn))
                {
                    relevantThings.Clear();
                    ingredientsOrdered.Clear();
                    return(true);
                }
            }
            TraverseParms        traverseParams = TraverseParms.For(pawn);
            RegionEntryPredicate entryCondition = null;

            if (Math.Abs(999f - bill.ingredientSearchRadius) >= 1f)
            {
                float radiusSq = bill.ingredientSearchRadius * bill.ingredientSearchRadius;
                entryCondition = delegate(Region from, Region r)
                {
                    if (!r.Allows(traverseParams, isDestination: false))
                    {
                        return(false);
                    }
                    CellRect extentsClose = r.extentsClose;
                    int      num2         = Math.Abs(billGiver.Position.x - Math.Max(extentsClose.minX, Math.Min(billGiver.Position.x, extentsClose.maxX)));
                    if ((float)num2 > bill.ingredientSearchRadius)
                    {
                        return(false);
                    }
                    int num3 = Math.Abs(billGiver.Position.z - Math.Max(extentsClose.minZ, Math.Min(billGiver.Position.z, extentsClose.maxZ)));
                    return(!((float)num3 > bill.ingredientSearchRadius) && (float)(num2 * num2 + num3 * num3) <= radiusSq);
                };
            }
            else
            {
                entryCondition = ((Region from, Region r) => r.Allows(traverseParams, isDestination: false));
            }
            int adjacentRegionsAvailable = rootReg.Neighbors.Count((Region region) => entryCondition(rootReg, region));
            int regionsProcessed         = 0;

            processedThings.AddRange(relevantThings);
            RegionProcessor regionProcessor = delegate(Region r)
            {
                List <Thing> list = r.ListerThings.ThingsMatching(ThingRequest.ForGroup(ThingRequestGroup.HaulableEver));
                for (int i = 0; i < list.Count; i++)
                {
                    Thing thing = list[i];
                    if (!processedThings.Contains(thing) && ReachabilityWithinRegion.ThingFromRegionListerReachable(thing, r, PathEndMode.ClosestTouch, pawn) && baseValidator(thing) && !(thing.def.IsMedicine & billGiverIsPawn))
                    {
                        newRelevantThings.Add(thing);
                        processedThings.Add(thing);
                    }
                }
                int num = ++regionsProcessed;
                if (newRelevantThings.Count > 0 && regionsProcessed > adjacentRegionsAvailable)
                {
                    relevantThings.AddRange(newRelevantThings);
                    newRelevantThings.Clear();
                    if (TryFindBestBillIngredientsInSet(relevantThings, bill, chosen, rootCell, billGiverIsPawn))
                    {
                        foundAll = true;
                        return(true);
                    }
                }
                return(false);
            };

            RegionTraverser.BreadthFirstTraverse(rootReg, entryCondition, regionProcessor, 99999);
            relevantThings.Clear();
            newRelevantThings.Clear();
            processedThings.Clear();
            ingredientsOrdered.Clear();
            return(foundAll);
        }
예제 #2
0
        private static bool TryFindBestBillIngredients(Bill bill, Pawn pawn, Thing billGiver, List <ThingCount> chosen)
        {
            chosen.Clear();
            WorkGiver_DoBill.newRelevantThings.Clear();
            if (bill.recipe.ingredients.Count == 0)
            {
                return(true);
            }
            IntVec3 rootCell = WorkGiver_DoBill.GetBillGiverRootCell(billGiver, pawn);
            Region  rootReg  = rootCell.GetRegion(pawn.Map, RegionType.Set_Passable);

            if (rootReg == null)
            {
                return(false);
            }
            WorkGiver_DoBill.MakeIngredientsListInProcessingOrder(WorkGiver_DoBill.ingredientsOrdered, bill);
            WorkGiver_DoBill.relevantThings.Clear();
            WorkGiver_DoBill.processedThings.Clear();
            bool foundAll = false;
            Predicate <Thing> baseValidator = (Thing t) => t.Spawned && !t.IsForbidden(pawn) && (float)(t.Position - billGiver.Position).LengthHorizontalSquared < bill.ingredientSearchRadius * bill.ingredientSearchRadius && bill.IsFixedOrAllowedIngredient(t) && bill.recipe.ingredients.Any((IngredientCount ingNeed) => ingNeed.filter.Allows(t)) && pawn.CanReserve(t, 1, -1, null, false);
            bool billGiverIsPawn            = billGiver is Pawn;

            if (billGiverIsPawn)
            {
                WorkGiver_DoBill.AddEveryMedicineToRelevantThings(pawn, billGiver, WorkGiver_DoBill.relevantThings, baseValidator, pawn.Map);
                if (WorkGiver_DoBill.TryFindBestBillIngredientsInSet(WorkGiver_DoBill.relevantThings, bill, chosen))
                {
                    WorkGiver_DoBill.relevantThings.Clear();
                    WorkGiver_DoBill.ingredientsOrdered.Clear();
                    return(true);
                }
            }
            TraverseParms        traverseParams = TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false);
            RegionEntryPredicate entryCondition = (Region from, Region r) => r.Allows(traverseParams, false);
            int adjacentRegionsAvailable        = rootReg.Neighbors.Count((Region region) => entryCondition(rootReg, region));
            int regionsProcessed = 0;

            WorkGiver_DoBill.processedThings.AddRange(WorkGiver_DoBill.relevantThings);
            RegionProcessor regionProcessor = delegate(Region r)
            {
                List <Thing> list = r.ListerThings.ThingsMatching(ThingRequest.ForGroup(ThingRequestGroup.HaulableEver));
                for (int i = 0; i < list.Count; i++)
                {
                    Thing thing = list[i];
                    if (!WorkGiver_DoBill.processedThings.Contains(thing))
                    {
                        if (ReachabilityWithinRegion.ThingFromRegionListerReachable(thing, r, PathEndMode.ClosestTouch, pawn))
                        {
                            if (baseValidator(thing) && (!thing.def.IsMedicine || !billGiverIsPawn))
                            {
                                WorkGiver_DoBill.newRelevantThings.Add(thing);
                                WorkGiver_DoBill.processedThings.Add(thing);
                            }
                        }
                    }
                }
                regionsProcessed++;
                if (WorkGiver_DoBill.newRelevantThings.Count > 0 && regionsProcessed > adjacentRegionsAvailable)
                {
                    Comparison <Thing> comparison = delegate(Thing t1, Thing t2)
                    {
                        float num   = (float)(t1.Position - rootCell).LengthHorizontalSquared;
                        float value = (float)(t2.Position - rootCell).LengthHorizontalSquared;
                        return(num.CompareTo(value));
                    };
                    WorkGiver_DoBill.newRelevantThings.Sort(comparison);
                    WorkGiver_DoBill.relevantThings.AddRange(WorkGiver_DoBill.newRelevantThings);
                    WorkGiver_DoBill.newRelevantThings.Clear();
                    if (WorkGiver_DoBill.TryFindBestBillIngredientsInSet(WorkGiver_DoBill.relevantThings, bill, chosen))
                    {
                        foundAll = true;
                        return(true);
                    }
                }
                return(false);
            };

            RegionTraverser.BreadthFirstTraverse(rootReg, entryCondition, regionProcessor, 99999, RegionType.Set_Passable);
            WorkGiver_DoBill.relevantThings.Clear();
            WorkGiver_DoBill.newRelevantThings.Clear();
            WorkGiver_DoBill.processedThings.Clear();
            WorkGiver_DoBill.ingredientsOrdered.Clear();
            return(foundAll);
        }