示例#1
0
 private static bool TryFindBestBillIngredientsInSet_AllowMix(List <Thing> availableThings, Building_CokeFurnace bill, List <ThingCount> chosen)
 {
     chosen.Clear();
     for (int i = 0; i < bill.SelectedRecipe.ingredients.Count; i++)
     {
         IngredientCount ingredientCount = bill.SelectedRecipe.ingredients[i];
         float           num             = ingredientCount.GetBaseCount();
         for (int j = 0; j < availableThings.Count; j++)
         {
             Thing thing = availableThings[j];
             if (ingredientCount.filter.Allows(thing) && ingredientCount.IsFixedIngredient)
             {
                 float num2 = bill.SelectedRecipe.IngredientValueGetter.ValuePerUnitOf(thing.def);
                 int   num3 = Mathf.Min(Mathf.CeilToInt(num / num2), thing.stackCount);
                 ThingCountUtility.AddToList(chosen, thing, num3);
                 num -= (float)num3 * num2;
                 if (num <= 0.0001f)
                 {
                     break;
                 }
             }
         }
         if (num > 0.0001f)
         {
             return(false);
         }
     }
     return(true);
 }
示例#2
0
    public static bool TryFindBestRecipeIngredientsInSet_AllowMix(this RecipeDef recipeDef,
                                                                  List <Thing> availableThings, List <ThingCount> chosen)
    {
        chosen.Clear();
        foreach (var ingredientCount in recipeDef.ingredients)
        {
            var baseCount = ingredientCount.GetBaseCount();
            foreach (var thing in availableThings)
            {
                if (!ingredientCount.filter.Allows(thing))
                {
                    continue;
                }

                var ingredientValue = recipeDef.IngredientValueGetter.ValuePerUnitOf(thing.def);
                var countToAdd      = Mathf.Min(Mathf.CeilToInt(baseCount / ingredientValue), thing.stackCount);
                ThingCountUtility.AddToList(chosen, thing, countToAdd);
                baseCount -= countToAdd * ingredientValue;
                if (baseCount <= 9.99999974737875E-05)
                {
                    break;
                }
            }

            if (baseCount > 9.99999974737875E-05)
            {
                return(false);
            }
        }

        return(true);
    }
示例#3
0
 private static bool TryFindBestBillIngredientsInSet_AllowMix(
     List <Thing> availableThings,
     Bill bill,
     List <ThingCount> chosen)
 {
     chosen.Clear();
     availableThings.Sort((t, t2) => bill.recipe.IngredientValueGetter.ValuePerUnitOf(t2.def).CompareTo(bill.recipe.IngredientValueGetter.ValuePerUnitOf(t.def)));
     for (int index1 = 0; index1 < bill.recipe.ingredients.Count; ++index1)
     {
         IngredientCount ingredient = bill.recipe.ingredients[index1];
         float           baseCount  = ingredient.GetBaseCount();
         for (int index2 = 0; index2 < availableThings.Count; ++index2)
         {
             Thing availableThing = availableThings[index2];
             if (ingredient.filter.Allows(availableThing) && (ingredient.IsFixedIngredient || bill.ingredientFilter.Allows(availableThing)))
             {
                 float num        = bill.recipe.IngredientValueGetter.ValuePerUnitOf(availableThing.def);
                 int   countToAdd = Mathf.Min(Mathf.CeilToInt(baseCount / num), availableThing.stackCount);
                 ThingCountUtility.AddToList(chosen, availableThing, countToAdd);
                 baseCount -= countToAdd * num;
                 if (baseCount <= 9.99999974737875E-05)
                 {
                     break;
                 }
             }
         }
         if (baseCount > 9.99999974737875E-05)
         {
             return(false);
         }
     }
     return(true);
 }
        public static bool Prefix(List <Thing> availableThings, Bill bill, List <ThingCount> chosen, ref bool __result)
        {
            Pawn trainee = WorkGiver_DoBill_TryFindBestBillIngredients.Trainee;

            if (trainee != null)
            {
                chosen.Clear();
                availableThings.Sort((Thing t, Thing t2) => bill.recipe.IngredientValueGetter.ValuePerUnitOf(t2.def).CompareTo(bill.recipe.IngredientValueGetter.ValuePerUnitOf(t.def)));
                for (int i = 0; i < bill.recipe.ingredients.Count; i++)
                {
                    IngredientCount ingredientCount = bill.recipe.ingredients[i];
                    for (int j = 0; j < availableThings.Count; j++)
                    {
                        Thing thing = availableThings[j];
                        if (ingredientCount.filter.Allows(thing) && (ingredientCount.IsFixedIngredient || bill.ingredientFilter.Allows(thing)))
                        {
                            ThingCountUtility.AddToList(chosen, thing, 1);
                        }
                    }
                }
                __result = true;
                return(false);
            }
            return(true);
        }
 public static bool TryFindBestRecipeIngredientsInSet_AllowMix(this RecipeDef recipeDef, List <Thing> availableThings, List <ThingCount> chosen)
 {
     chosen.Clear();
     for (int ingredientIndex = 0; ingredientIndex < recipeDef.ingredients.Count; ++ingredientIndex)
     {
         IngredientCount ingredientCount = recipeDef.ingredients[ingredientIndex];
         float           baseCount       = ingredientCount.GetBaseCount();
         for (int thingIndex = 0; thingIndex < availableThings.Count; ++thingIndex)
         {
             Thing thing = availableThings[thingIndex];
             if (ingredientCount.filter.Allows(thing))
             {
                 float ingredientValue = recipeDef.IngredientValueGetter.ValuePerUnitOf(thing.def);
                 int   countToAdd      = Mathf.Min(Mathf.CeilToInt(baseCount / ingredientValue), thing.stackCount);
                 ThingCountUtility.AddToList(chosen, thing, countToAdd);
                 baseCount -= (float)countToAdd * ingredientValue;
                 if ((double)baseCount <= 9.99999974737875E-05)
                 {
                     break;
                 }
             }
         }
         if ((double)baseCount > 9.99999974737875E-05)
         {
             return(false);
         }
     }
     return(true);
 }
示例#6
0
        private static bool TryFindBestBillIngredientsInSet(List <Thing> availableThings, ActivityTask task, List <ThingCount> chosenIngThings)
        {
            IEnumerable <ThingDefsCount> thingDefsCount = task.ActivityTaskDef.ThingDefsCount;

            chosenIngThings.Clear();

            for (int index1 = 0; index1 < thingDefsCount.Count(); ++index1)
            {
                float baseCount = thingDefsCount.ElementAt(index1).Count;
                for (int index2 = 0; index2 < availableThings.Count; ++index2)
                {
                    Thing availableThing = availableThings[index2];
                    if (task.ThingFilter.Allows(availableThing.def))
                    {
                        float num        = task.ActivityTaskDef.IngredientValueGetter.ValuePerUnitOf(availableThing.def);
                        int   countToAdd = Mathf.Min(Mathf.CeilToInt(baseCount / num), availableThing.stackCount);
                        ThingCountUtility.AddToList(chosenIngThings, availableThing, countToAdd);
                        baseCount -= (float)countToAdd * num;
                        if ((double)baseCount <= 9.99999974737875E-05)
                        {
                            break;
                        }
                    }
                }
                if ((double)baseCount > 9.99999974737875E-05)
                {
                    return(false);
                }
            }
            return(true);
        }
示例#7
0
 internal static bool TryFindBestMixInSet_AllowMix(List <Thing> availableThings, Bill bill, List <ThingCount> chosen)
 {
     chosen.Clear();
     for (var i = 0; i < bill.recipe.ingredients.Count; i++)
     {
         IngredientCount ingredientCount = bill.recipe.ingredients[i];
         var             num             = ingredientCount.GetBaseCount();
         for (var j = 0; j < availableThings.Count; j++)
         {
             Thing thing = availableThings[j];
             if (ingredientCount.filter.Allows(thing) && (ingredientCount.IsFixedIngredient || bill.ingredientFilter.Allows(thing)))
             {
                 var num2 = bill.recipe.IngredientValueGetter.ValuePerUnitOf(thing.def);
                 var num3 = Mathf.Min(Mathf.CeilToInt(num / num2), thing.stackCount);
                 ThingCountUtility.AddToList(chosen, thing, num3);
                 num -= (float)num3 * num2;
                 if (num <= 0.0001f)
                 {
                     break;
                 }
             }
         }
         if (num > 0.0001f)
         {
             return(false);
         }
     }
     return(true);
 }
        private static bool TryFindBestBillIngredientsInSet_NoMix(List <Thing> availableThings, Bill bill, List <ThingCount> chosen)
        {
            RecipeDef recipe = bill.recipe;

            chosen.Clear();
            WorkGiver_DoBill.availableCounts.Clear();
            WorkGiver_DoBill.availableCounts.GenerateFrom(availableThings);
            for (int i = 0; i < WorkGiver_DoBill.ingredientsOrdered.Count; i++)
            {
                IngredientCount ingredientCount = recipe.ingredients[i];
                bool            flag            = false;
                for (int j = 0; j < WorkGiver_DoBill.availableCounts.Count; j++)
                {
                    float num = (float)ingredientCount.CountRequiredOfFor(WorkGiver_DoBill.availableCounts.GetDef(j), bill.recipe);
                    if (num <= WorkGiver_DoBill.availableCounts.GetCount(j))
                    {
                        if (ingredientCount.filter.Allows(WorkGiver_DoBill.availableCounts.GetDef(j)))
                        {
                            if (ingredientCount.IsFixedIngredient || bill.ingredientFilter.Allows(WorkGiver_DoBill.availableCounts.GetDef(j)))
                            {
                                for (int k = 0; k < availableThings.Count; k++)
                                {
                                    if (availableThings[k].def == WorkGiver_DoBill.availableCounts.GetDef(j))
                                    {
                                        int num2 = availableThings[k].stackCount - ThingCountUtility.CountOf(chosen, availableThings[k]);
                                        if (num2 > 0)
                                        {
                                            int num3 = Mathf.Min(Mathf.FloorToInt(num), num2);
                                            ThingCountUtility.AddToList(chosen, availableThings[k], num3);
                                            num -= (float)num3;
                                            if (num < 0.001f)
                                            {
                                                flag = true;
                                                float num4 = WorkGiver_DoBill.availableCounts.GetCount(j);
                                                num4 -= (float)ingredientCount.CountRequiredOfFor(WorkGiver_DoBill.availableCounts.GetDef(j), bill.recipe);
                                                WorkGiver_DoBill.availableCounts.SetCount(j, num4);
                                                break;
                                            }
                                        }
                                    }
                                }
                                if (flag)
                                {
                                    break;
                                }
                            }
                        }
                    }
                }
                if (!flag)
                {
                    return(false);
                }
            }
            return(true);
        }
示例#9
0
        private static bool TryFindBestBillIngredientsInSet_NoMix(List <Thing> availableThings, Building_CokeFurnace bill, List <ThingCount> chosen)
        {
            RecipeDef recipe = bill.SelectedRecipe;

            chosen.Clear();
            availableCounts.Clear();
            availableCounts.GenerateFrom(availableThings);
            for (int i = 0; i < ingredientsOrdered.Count; i++)
            {
                IngredientCount ingredientCount = recipe.ingredients[i];
                bool            flag            = false;
                for (int j = 0; j < availableCounts.Count; j++)
                {
                    float num = ingredientCount.CountRequiredOfFor(availableCounts.GetDef(j), bill.SelectedRecipe);
                    if (num > availableCounts.GetCount(j) || !ingredientCount.filter.Allows(availableCounts.GetDef(j)) || !ingredientCount.IsFixedIngredient)
                    {
                        continue;
                    }
                    for (int k = 0; k < availableThings.Count; k++)
                    {
                        if (availableThings[k].def != availableCounts.GetDef(j))
                        {
                            continue;
                        }
                        int num2 = availableThings[k].stackCount - ThingCountUtility.CountOf(chosen, availableThings[k]);
                        if (num2 > 0)
                        {
                            int num3 = Mathf.Min(Mathf.FloorToInt(num), num2);
                            ThingCountUtility.AddToList(chosen, availableThings[k], num3);

                            num -= (float)num3;
                            if (num < 0.001f)
                            {
                                flag = true;
                                float count = availableCounts.GetCount(j);
                                count -= (float)ingredientCount.CountRequiredOfFor(availableCounts.GetDef(j), bill.SelectedRecipe);
                                availableCounts.SetCount(j, count);
                                break;
                            }
                        }
                    }
                    if (flag)
                    {
                        break;
                    }
                }
                if (!flag)
                {
                    return(false);
                }
            }
            return(true);
        }
示例#10
0
        internal static bool TryFindBestMixInSet_NoMix(List <Thing> availableThings, Bill bill, List <ThingCount> chosen, List <IngredientCount> ingredientsOrdered)
        {
            var       availableCounts = new BMixDefCountList();
            RecipeDef recipe          = bill.recipe;

            chosen.Clear();
            availableCounts.Clear();
            availableCounts.GenerateFrom(availableThings);
            for (var i = 0; i < ingredientsOrdered.Count; i++)
            {
                IngredientCount ingredientCount = recipe.ingredients[i];
                var             flag            = false;
                for (var j = 0; j < availableCounts.Count; j++)
                {
                    float num = ingredientCount.CountRequiredOfFor(availableCounts.GetDef(j), bill.recipe);
                    if (num > availableCounts.GetCount(j) || !ingredientCount.filter.Allows(availableCounts.GetDef(j)) || (!ingredientCount.IsFixedIngredient && !bill.ingredientFilter.Allows(availableCounts.GetDef(j))))
                    {
                        continue;
                    }
                    for (var k = 0; k < availableThings.Count; k++)
                    {
                        if (availableThings[k].def != availableCounts.GetDef(j))
                        {
                            continue;
                        }
                        var num2 = availableThings[k].stackCount - ThingCountUtility.CountOf(chosen, availableThings[k]);
                        if (num2 > 0)
                        {
                            var num3 = Mathf.Min(Mathf.FloorToInt(num), num2);
                            ThingCountUtility.AddToList(chosen, availableThings[k], num3);
                            num -= (float)num3;
                            if (num < 0.001f)
                            {
                                flag = true;
                                var count = availableCounts.GetCount(j);
                                count -= (float)ingredientCount.CountRequiredOfFor(availableCounts.GetDef(j), bill.recipe);
                                availableCounts.SetCount(j, count);
                                break;
                            }
                        }
                    }
                    if (flag)
                    {
                        break;
                    }
                }
                if (!flag)
                {
                    return(false);
                }
            }
            return(true);
        }
示例#11
0
        private static bool TryFindBestBillIngredientsInSet_NoMix(List <Thing> availableThings, List <ThingDefCount> neededIngreds, List <ThingCount> chosen)
        {
            chosen.Clear();
            AssignedThings.Clear();
            AvailableCounts.Clear();
            AvailableCounts.GenerateFrom(availableThings);
            foreach (var ingredientCount in neededIngreds)
            {
                var flag = false;
                for (var index2 = 0; index2 < AvailableCounts.Count; ++index2)
                {
                    float f = ingredientCount.Count;

                    if (!(f <= (double)AvailableCounts.GetCount(index2)) || ingredientCount.ThingDef != AvailableCounts.GetDef(index2))
                    {
                        continue;
                    }

                    foreach (var item in availableThings)
                    {
                        if (item.def != AvailableCounts.GetDef(index2) || AssignedThings.Contains(item))
                        {
                            continue;
                        }

                        var countToAdd = Mathf.Min(Mathf.FloorToInt(f), item.stackCount);
                        ThingCountUtility.AddToList(chosen, item, countToAdd);
                        f -= countToAdd;
                        AssignedThings.Add(item);
                        if (f < 1.0 / 1000.0)
                        {
                            flag = true;
                            var val = AvailableCounts.GetCount(index2) - ingredientCount.Count;
                            AvailableCounts.SetCount(index2, val);
                            break;
                        }
                    }
                    if (flag)
                    {
                        break;
                    }
                }
                if (!flag)
                {
                    return(false);
                }
            }
            return(true);
        }
示例#12
0
        static bool Prefix(WorkGiver_DoBill __instance, Bill bill, Pawn pawn, ref List <ThingCount> chosen, ref bool __result)
        {
            if (bill.recipe == WTH_DefOf.WTH_Craft_VanometricModule)
            {
                Thing thing = pawn.Map.spawnedThings.FirstOrDefault(
                    (Thing t) => (t.GetInnerIfMinified().def == ThingDefOf.VanometricPowerCell) &&
                    bill.IsFixedOrAllowedIngredient(t) &&
                    pawn.CanReach(t, Verse.AI.PathEndMode.Touch, Danger.Deadly) &&
                    !t.IsForbidden(pawn) &&
                    t is MinifiedThing);
                if (thing != null)
                {
                    ThingCountUtility.AddToList(chosen, thing, 1);
                    __result = true;
                    return(false);
                }
            }


            if (bill.recipe.defName.Contains("WTH_Mount"))
            {
                Predicate <Thing> isMounted = (Thing t) => t.TryGetComp <CompMountable>() is CompMountable comp && comp.Active;
                Thing             thing     = pawn.Map.spawnedThings.FirstOrDefault(
                    (Thing t) => (t.GetInnerIfMinified() is Building_TurretGun) &&
                    bill.IsFixedOrAllowedIngredient(t) &&
                    pawn.CanReach(t, Verse.AI.PathEndMode.Touch, Danger.Deadly) &&
                    !t.IsForbidden(pawn) &&
                    !isMounted(t) &&
                    t is MinifiedThing);
                if (thing != null)
                {
                    ThingCountUtility.AddToList(chosen, thing, 1);
                    __result = true;
                    return(false);
                }
            }
            return(true);
        }
示例#13
0
        private static bool TryFindRestrictedIngridients(ActivityTask task, Pawn pawn, Thing giver, List <ThingCount> chosenIngThings)
        {
            chosenIngThings.Clear();
            newRelevantThings.Clear();

            if (task.HumanlikeIngredient.ConcretePawn == null && task.AnimalIngredient.ConcretePawn == null)
            {
                return(false);
            }

            Predicate <Thing> baseValidator = (Predicate <Thing>)(t =>
            {
                if (t.Spawned && !t.IsForbidden(pawn) && ((double)(t.Position - giver.Position).LengthHorizontalSquared < (double)task.IngredientSearchRadius * (double)task.IngredientSearchRadius && task.ThingFilter.Allows(t.def)))
                {
                    return(pawn.CanReserve((LocalTargetInfo)t, 1, -1, (ReservationLayerDef)null, false));
                }
                return(false);
            });

            if (task.HumanlikeIngredient.ConcretePawn != null)
            {
                if (baseValidator(task.HumanlikeIngredient.ConcretePawn))
                {
                    ThingCountUtility.AddToList(chosenIngThings, task.HumanlikeIngredient.ConcretePawn, 1);
                    return(true);
                }
            }
            if (task.AnimalIngredient.ConcretePawn != null)
            {
                if (baseValidator(task.AnimalIngredient.ConcretePawn))
                {
                    ThingCountUtility.AddToList(chosenIngThings, task.AnimalIngredient.ConcretePawn, 1);
                    return(true);
                }
            }
            return(false);
        }
示例#14
0
        private static bool TryFindBestBillIngredients(Bill bill, Pawn pawn, Thing billGiver, List <ThingCount> chosen)
        {
            chosen.Clear();
            newRelevantThings.Clear();
            IntVec3 rootCell = (IntVec3)GetBillGiverRootCellInfo.Invoke(bill, new object[] { billGiver, pawn });
            Region  rootReg  = rootCell.GetRegion(pawn.Map, RegionType.Set_Passable);

            if (rootReg == null)
            {
                return(false);
            }
            relevantThings.Clear();
            bool foundAll = false;
            Predicate <Thing>    baseValidator  = (Thing t) => t.Spawned && !t.IsForbidden(pawn) && (t.Position - billGiver.Position).LengthHorizontalSquared < bill.ingredientSearchRadius * bill.ingredientSearchRadius && ((!t.def.tradeTags.NullOrEmpty() && t.def.tradeTags.Contains(TechStrings.bookTraderTag)) || t is Building_BookStore) && pawn.CanReserve(t, 1, -1, null, false);
            TraverseParms        traverseParams = TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false);
            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, false))
                    {
                        return(false);
                    }
                    CellRect extentsClose = r.extentsClose;
                    int      num          = Math.Abs(billGiver.Position.x - Math.Max(extentsClose.minX, Math.Min(billGiver.Position.x, extentsClose.maxX)));
                    if (num > bill.ingredientSearchRadius)
                    {
                        return(false);
                    }
                    int num2 = Math.Abs(billGiver.Position.z - Math.Max(extentsClose.minZ, Math.Min(billGiver.Position.z, extentsClose.maxZ)));
                    return(num2 <= bill.ingredientSearchRadius && (num * num + num2 * num2) <= radiusSq);
                };
            }
            else
            {
                entryCondition = ((Region from, Region r) => r.Allows(traverseParams, false));
            }
            int             adjacentRegionsAvailable = rootReg.Neighbors.Count((Region region) => entryCondition(rootReg, region));
            int             regionsProcessed         = 0;
            RegionProcessor regionProcessor          = delegate(Region r)
            {
                List <Thing> items = r.ListerThings.ThingsMatching(ThingRequest.ForGroup(ThingRequestGroup.HaulableEver));
                for (int i = 0; i < items.Count; i++)
                {
                    Thing thing = items[i];
                    if (ReachabilityWithinRegion.ThingFromRegionListerReachable(thing, r, PathEndMode.ClosestTouch, pawn) && baseValidator(thing) && IsSelected(thing, bill))
                    {
                        newRelevantThings.Add(thing);
                    }
                }
                List <Thing> buildings = r.ListerThings.ThingsMatching(ThingRequest.ForGroup(ThingRequestGroup.BuildingArtificial));
                for (int i = 0; i < buildings.Count; i++)
                {
                    Thing thing = buildings[i];
                    if (ReachabilityWithinRegion.ThingFromRegionListerReachable(thing, r, PathEndMode.ClosestTouch, pawn) && baseValidator(thing))
                    {
                        List <Thing> innerList = ContainsSelected(thing, bill);
                        if (!innerList.NullOrEmpty())
                        {
                            newRelevantThings.AddRange(innerList);
                        }
                    }
                }
                regionsProcessed++;
                if (newRelevantThings.Count > 0 && regionsProcessed > adjacentRegionsAvailable)
                {
                    relevantThings.AddRange(newRelevantThings);
                    newRelevantThings.Clear();
                    ThingCountUtility.AddToList(chosen, FindNearest(relevantThings, rootCell), 1);
                    foundAll = true;
                    return(true);
                }
                return(false);
            };

            RegionTraverser.BreadthFirstTraverse(rootReg, entryCondition, regionProcessor, 99999, RegionType.Set_Passable);
            relevantThings.Clear();
            newRelevantThings.Clear();
            return(foundAll);
        }
        public static bool TryFindBestRecipeIngredientsInSet_NoMix(this RecipeDef recipeDef, List <Thing> availableThings, List <ThingCount> chosen)
        {
            chosen.Clear();
            List <IngredientCount> ingredientsOrdered = new List <IngredientCount>();
            HashSet <Thing>        assignedThings     = new HashSet <Thing>();
            DefCountList           availableCounts    = new DefCountList();

            availableCounts.GenerateFrom(availableThings);

            for (int ingredientIndex = 0; ingredientIndex < recipeDef.ingredients.Count; ++ingredientIndex)
            {
                IngredientCount ingredientCount = recipeDef.ingredients[ingredientIndex];
                if (ingredientCount.filter.AllowedDefCount == 1)
                {
                    ingredientsOrdered.Add(ingredientCount);
                }
            }
            for (int ingredientIndex = 0; ingredientIndex < recipeDef.ingredients.Count; ++ingredientIndex)
            {
                IngredientCount ingredientCount = recipeDef.ingredients[ingredientIndex];
                if (!ingredientsOrdered.Contains(ingredientCount))
                {
                    ingredientsOrdered.Add(ingredientCount);
                }
            }

            for (int orderedIndex = 0; orderedIndex < ingredientsOrdered.Count; ++orderedIndex)
            {
                IngredientCount ingredientCount = recipeDef.ingredients[orderedIndex];
                bool            hasAllRequired  = false;
                for (int countsIndex = 0; countsIndex < availableCounts.Count; ++countsIndex)
                {
                    float countRequiredFor = (float)ingredientCount.CountRequiredOfFor(availableCounts.GetDef(countsIndex), recipeDef);
                    if (
                        ((double)countRequiredFor <= (double)availableCounts.GetCount(countsIndex)) &&
                        (ingredientCount.filter.Allows(availableCounts.GetDef(countsIndex)))
                        )
                    {
                        for (int thingsIndex = 0; thingsIndex < availableThings.Count; ++thingsIndex)
                        {
                            if (
                                (availableThings[thingsIndex].def == availableCounts.GetDef(countsIndex)) &&
                                (!assignedThings.Contains(availableThings[thingsIndex]))
                                )
                            {
                                int countToAdd = Mathf.Min(Mathf.FloorToInt(countRequiredFor), availableThings[thingsIndex].stackCount);
                                ThingCountUtility.AddToList(chosen, availableThings[thingsIndex], countToAdd);
                                countRequiredFor -= (float)countToAdd;
                                assignedThings.Add(availableThings[thingsIndex]);
                                if ((double)countRequiredFor < 1.0 / 1000.0)
                                {
                                    hasAllRequired = true;
                                    float val = availableCounts.GetCount(countsIndex) - ingredientCount.GetBaseCount();
                                    availableCounts.SetCount(countsIndex, val);
                                    break;
                                }
                            }
                        }
                        if (hasAllRequired)
                        {
                            break;
                        }
                    }
                }
                if (!hasAllRequired)
                {
                    return(false);
                }
            }
            return(true);
        }
示例#16
0
    public static bool TryFindBestRecipeIngredientsInSet_NoMix(this RecipeDef recipeDef,
                                                               List <Thing> availableThings, List <ThingCount> chosen)
    {
        chosen.Clear();
        var ingredientsOrdered = new List <IngredientCount>();
        var assignedThings     = new HashSet <Thing>();
        var availableCounts    = new DefCountList();

        availableCounts.GenerateFrom(availableThings);

        foreach (var ingredientCount in recipeDef.ingredients)
        {
            if (ingredientCount.filter.AllowedDefCount == 1)
            {
                ingredientsOrdered.Add(ingredientCount);
            }
        }

        foreach (var ingredientCount in recipeDef.ingredients)
        {
            if (!ingredientsOrdered.Contains(ingredientCount))
            {
                ingredientsOrdered.Add(ingredientCount);
            }
        }

        for (var orderedIndex = 0; orderedIndex < ingredientsOrdered.Count; ++orderedIndex)
        {
            var ingredientCount = recipeDef.ingredients[orderedIndex];
            var hasAllRequired  = false;
            for (var countsIndex = 0; countsIndex < availableCounts.Count; ++countsIndex)
            {
                var countRequiredFor =
                    (float)ingredientCount.CountRequiredOfFor(availableCounts.GetDef(countsIndex), recipeDef);
                if (!(countRequiredFor <= (double)availableCounts.GetCount(countsIndex)) ||
                    !ingredientCount.filter.Allows(availableCounts.GetDef(countsIndex)))
                {
                    continue;
                }

                foreach (var thing in availableThings)
                {
                    if (thing.def != availableCounts.GetDef(countsIndex) || assignedThings.Contains(thing))
                    {
                        continue;
                    }

                    var countToAdd = Mathf.Min(Mathf.FloorToInt(countRequiredFor),
                                               thing.stackCount);
                    ThingCountUtility.AddToList(chosen, thing, countToAdd);
                    countRequiredFor -= countToAdd;
                    assignedThings.Add(thing);
                    if (!(countRequiredFor < 1.0 / 1000.0))
                    {
                        continue;
                    }

                    hasAllRequired = true;
                    var val = availableCounts.GetCount(countsIndex) - ingredientCount.GetBaseCount();
                    availableCounts.SetCount(countsIndex, val);
                    break;
                }

                if (hasAllRequired)
                {
                    break;
                }
            }

            if (!hasAllRequired)
            {
                return(false);
            }
        }

        return(true);
    }
示例#17
0
        private static bool TryFindBestBillIngredientsInSet_NoMix2(
            List <Thing> availableThings,
            Bill bill,
            List <ThingCount> chosen,
            IntVec3 rootCell,
            bool alreadySorted, List <IngredientCount> ingredientsOrdered)
        {
            if (!alreadySorted)
            {
                Comparison <Thing> comparison = (t1, t2) => ((float)(t1.Position - rootCell).LengthHorizontalSquared).CompareTo((t2.Position - rootCell).LengthHorizontalSquared);
                availableThings.Sort(comparison);
            }
            RecipeDef recipe = bill.recipe;

            chosen.Clear();
            //WorkGiver_DoBill.availableCounts.Clear();
            DefCountList availableCounts = new DefCountList();

            availableCounts.GenerateFrom(availableThings);
            for (int index1 = 0; index1 < ingredientsOrdered.Count; ++index1)
            {
                IngredientCount ingredient = recipe.ingredients[index1];
                bool            flag       = false;
                for (int index2 = 0; index2 < availableCounts.Count; ++index2)
                {
                    float f = ingredient.CountRequiredOfFor(availableCounts.GetDef(index2), bill.recipe);
                    if ((recipe.ignoreIngredientCountTakeEntireStacks || f <= availableCounts.GetCount(index2)) && ingredient.filter.Allows(availableCounts.GetDef(index2)) && (ingredient.IsFixedIngredient || bill.ingredientFilter.Allows(availableCounts.GetDef(index2))))
                    {
                        for (int index3 = 0; index3 < availableThings.Count; ++index3)
                        {
                            if (availableThings[index3].def == availableCounts.GetDef(index2))
                            {
                                int num = availableThings[index3].stackCount - ThingCountUtility.CountOf(chosen, availableThings[index3]);
                                if (num > 0)
                                {
                                    if (recipe.ignoreIngredientCountTakeEntireStacks)
                                    {
                                        ThingCountUtility.AddToList(chosen, availableThings[index3], num);
                                        return(true);
                                    }
                                    int countToAdd = Mathf.Min(Mathf.FloorToInt(f), num);
                                    ThingCountUtility.AddToList(chosen, availableThings[index3], countToAdd);
                                    f -= countToAdd;
                                    if (f < 1.0 / 1000.0)
                                    {
                                        flag = true;
                                        float val = availableCounts.GetCount(index2) - ingredient.CountRequiredOfFor(availableCounts.GetDef(index2), bill.recipe);
                                        availableCounts.SetCount(index2, val);
                                        break;
                                    }
                                }
                            }
                        }
                        if (flag)
                        {
                            break;
                        }
                    }
                }
                if (!flag)
                {
                    return(false);
                }
            }
            return(true);
        }
示例#18
0
        static bool TryFindBestBillIngredientsInSet_AllowMix(List <Thing> availableThings, Bill bill, List <ThingCount> chosen)
        {
            chosen.Clear();
            List <ThingCount> chosenInThisStep = new List <ThingCount>();

            for (int i = 0; i < bill.recipe.ingredients.Count; i++)
            {
                IngredientCount ingredientCount = bill.recipe.ingredients[i];
                float           num             = ingredientCount.GetBaseCount();
                chosenInThisStep.Clear();
                for (int j = 0; j < availableThings.Count; j++)
                {
                    Thing thing = availableThings[j];
                    if (ingredientCount.filter.Allows(thing))
                    {
                        if (ingredientCount.IsFixedIngredient || bill.ingredientFilter.Allows(thing))
                        {
                            float num2 = bill.recipe.IngredientValueGetter.ValuePerUnitOf(thing.def);
                            int   num3 = Mathf.Min(Mathf.CeilToInt(num / num2), thing.stackCount);
                            ThingCountUtility.AddToList(chosen, thing, num3);
                            ThingCountUtility.AddToList(chosenInThisStep, thing, num3);
                            num -= (float)num3 * num2;
                            if (num <= 0.0001f)
                            {
                                break;
                            }
                        }
                    }
                }
                if (num > 0.0001f)
                {
                    return(false);
                }
                //patch: do another pass eliminating as many resources as possible. starting with the biggest resources,
                //have we allocated more than we may need? And at least 2 different things.
                if (num < -0.0001f && chosenInThisStep.Count > 1)
                {
                    num = -num;
                    chosenInThisStep.SortByDescending(ta => bill.recipe.IngredientValueGetter.ValuePerUnitOf(ta.Thing.def));
                    for (int j = 0; j < chosenInThisStep.Count && num > 0.0001f; j++)
                    {
                        ThingCount ta           = chosenInThisStep[j];
                        float      valuePerUnit = bill.recipe.IngredientValueGetter.ValuePerUnitOf(ta.Thing.def);
                        //can we remove at least one instance of the current ingredient?
                        if (valuePerUnit < num)
                        {
                            //determine how many instances we can remove
                            int instancesToRemove = 0;
                            while (valuePerUnit < num && instancesToRemove < ta.Count)
                            {
                                num -= valuePerUnit - 0.0001f;                                //adding a small amount since the precision loss of float causes problems where subtraction leads to 0.04999 instead of 0.05
                                instancesToRemove++;
                            }
                            if (instancesToRemove != 0)
                            {
                                ThingCountUtility.AddToList(chosen, ta.Thing, -instancesToRemove);
                            }
                        }
                    }
                }
                chosen.RemoveAll(ta => ta.Count <= 0);
            }
            return(true);
        }
示例#19
0
        private static bool TryFindBestBillIngredientsInSet_NoMix(List <Thing> availableThings, Bill bill, List <ThingCount> chosen, IntVec3 rootCell, bool alreadySorted)
        {
            if (!alreadySorted)
            {
                Comparison <Thing> comparison = delegate(Thing t1, Thing t2)
                {
                    float num4  = (t1.Position - rootCell).LengthHorizontalSquared;
                    float value = (t2.Position - rootCell).LengthHorizontalSquared;
                    return(num4.CompareTo(value));
                };
                availableThings.Sort(comparison);
            }
            RecipeDef recipe = bill.recipe;

            chosen.Clear();
            availableCounts.Clear();
            availableCounts.GenerateFrom(availableThings);
            for (int i = 0; i < ingredientsOrdered.Count; i++)
            {
                IngredientCount ingredientCount = recipe.ingredients[i];
                bool            flag            = false;
                for (int j = 0; j < availableCounts.Count; j++)
                {
                    float num = ingredientCount.CountRequiredOfFor(availableCounts.GetDef(j), bill.recipe);
                    if ((!recipe.ignoreIngredientCountTakeEntireStacks && num > availableCounts.GetCount(j)) || !ingredientCount.filter.Allows(availableCounts.GetDef(j)) || (!ingredientCount.IsFixedIngredient && !bill.ingredientFilter.Allows(availableCounts.GetDef(j))))
                    {
                        continue;
                    }
                    for (int k = 0; k < availableThings.Count; k++)
                    {
                        if (availableThings[k].def != availableCounts.GetDef(j))
                        {
                            continue;
                        }
                        int num2 = availableThings[k].stackCount - ThingCountUtility.CountOf(chosen, availableThings[k]);
                        if (num2 > 0)
                        {
                            if (recipe.ignoreIngredientCountTakeEntireStacks)
                            {
                                ThingCountUtility.AddToList(chosen, availableThings[k], num2);
                                return(true);
                            }
                            int num3 = Mathf.Min(Mathf.FloorToInt(num), num2);
                            ThingCountUtility.AddToList(chosen, availableThings[k], num3);
                            num -= (float)num3;
                            if (num < 0.001f)
                            {
                                flag = true;
                                float count = availableCounts.GetCount(j);
                                count -= (float)ingredientCount.CountRequiredOfFor(availableCounts.GetDef(j), bill.recipe);
                                availableCounts.SetCount(j, count);
                                break;
                            }
                        }
                    }
                    if (flag)
                    {
                        break;
                    }
                }
                if (!flag)
                {
                    return(false);
                }
            }
            return(true);
        }
示例#20
0
        private static bool TryFindBestBillIngredientsInSet_NoMix(
            List <Thing> availableThings,
            Bill bill,
            List <ThingCount> chosen)
        {
            var recipe = bill.recipe;

            chosen.Clear();
            availableCounts.Clear();

            // 利用可能な材料リストとその個数
            // Things側はゲーム中に見えているThingのリスト
            // Counts側は、違うThingでも個数をまとめている
            availableCounts.GenerateFrom(availableThings);

            // レシピが必要としている材料の種類だけループ
            foreach (var ingredientCount in recipe.ingredients)
            {
                var isIngredientFound = false;
                for (var j = 0; j < availableCounts.Count; j++)
                {
                    // 利用可能な物
                    var curDef   = availableCounts.GetDef(j);
                    var curCount = availableCounts.GetCount(j);

                    // レシピ完遂のためにそれが何個必要なのか
                    var requiredCount       = (float)ingredientCount.CountRequiredOfFor(curDef, bill.recipe);
                    var remainRequiredCount = requiredCount;

                    // 利用可能な個数は必要数より少ない
                    if (requiredCount > curCount)
                    {
                        continue;
                    }

                    // レシピとして許可されていない
                    if (!ingredientCount.filter.Allows(curDef))
                    {
                        continue;
                    }

                    // レシピの固定材料でもなければ billとして許可されているわけでもない
                    if (!ingredientCount.IsFixedIngredient && !bill.ingredientFilter.Allows(curDef))
                    {
                        continue;
                    }

                    // Thingの検索
                    foreach (var availableThing in availableThings)
                    {
                        // 探している物ではない
                        if (availableThing.def != curDef)
                        {
                            continue;
                        }

                        // 未使用の材料数(全個数から、既に追加されている個数を引いた数)
                        var unusedCount = availableThing.stackCount - ThingCountUtility.CountOf(chosen, availableThing);

                        // 未使用数0以下
                        if (unusedCount <= 0)
                        {
                            continue;
                        }

                        // そのスタックからいくつ使うか(必要数と未使用数のうち小さい方)
                        var actualUseCount = Mathf.Min(Mathf.FloorToInt(remainRequiredCount), unusedCount);

                        // リストに加える
                        ThingCountUtility.AddToList(chosen, availableThing, actualUseCount);

                        // 残りの必要個数を減らす
                        remainRequiredCount -= actualUseCount;

                        // まだ必要であれば続けて探す
                        if (remainRequiredCount >= 0.001f)
                        {
                            continue;
                        }

                        // その材料は全部見つかった
                        // ⇒残りの利用可能数を減らす
                        isIngredientFound = true;
                        availableCounts.SetCount(j, curCount - requiredCount);
                        break;
                    }

                    // その材料は全部見つかったので残りは探さなくていい
                    if (isIngredientFound)
                    {
                        break;
                    }
                }

                // 1個でも見つからない材料があればダメ
                if (!isIngredientFound)
                {
                    return(false);
                }
            }

            // 全部見つかったのでOK
            return(true);
        }