public static void              AddToList(List <HopperSettingsAmount> list, ThingCategoryDef categoryDef, float baseCount, RecipeDef recipe)
            {
                int countNeeded = CountForCategoryDef(categoryDef, baseCount, recipe);

                for (int index = 0; index < list.Count; ++index)
                {
                    if (list[index].fixedCategoryDef == categoryDef)
                    {
                        if (countNeeded > list[index].fixedCount)
                        {
                            list[index] = new HopperSettingsAmount(list[index].fixedCategoryDef, countNeeded);
                        }
                        return;
                    }
                }
                list.Add(new HopperSettingsAmount(categoryDef, countNeeded));
            }
        private void                        MergeIngredientIntoHopperSettings(IngredientCount ingredient, RecipeDef recipe)
        {
            //Log.Message( string.Format( "{0}.CompHopperUser.MergeIngredientIntoHopperSettings( IngredientCount, {1} )", this.parent.ThingID, recipe == null ? "null" : recipe.defName ) );
            if (ingredient.filter != null)
            {
                if (!ingredient.filter.Categories().NullOrEmpty())
                {
                    foreach (var category in ingredient.filter.Categories())
                    {
                        var categoryDef = DefDatabase <ThingCategoryDef> .GetNamed(category, true);

                        HopperSettingsAmount.AddToList(hopperSettings, categoryDef, ingredient.GetBaseCount(), recipe);
                    }
                }
                if (!ingredient.filter.ThingDefs().NullOrEmpty())
                {
                    foreach (var thingDef in ingredient.filter.ThingDefs())
                    {
                        HopperSettingsAmount.AddToList(hopperSettings, thingDef, ingredient.GetBaseCount(), recipe);
                    }
                }
            }
        }
        private void                        BuildHopperSettings()
        {
            //Log.Message( string.Format( "{0}.CompHopperUser.BuildHopperSettings()", this.parent.ThingID ) );
            // Create initial list of hopper settings from recipe ingredients
            foreach (var recipe in recipeFilter)
            {
                if (!recipe.ingredients.NullOrEmpty())
                {
                    foreach (var ingredient in recipe.ingredients)
                    {
                        MergeIngredientIntoHopperSettings(ingredient, recipe);
                    }
                }
            }

            // Assign hopper settings filters from ingredients
            foreach (var hopperSetting in hopperSettings)
            {
                if (hopperSetting.fixedCategoryDef != null)
                {
                    hopperSetting.settings.filter.SetAllow(hopperSetting.fixedCategoryDef, true);
                }
                if (hopperSetting.fixedThingDef != null)
                {
                    hopperSetting.settings.filter.SetAllow(hopperSetting.fixedThingDef, true);
                }
            }

            // Add exceptions to hopper settings filters
            foreach (var recipe in recipeFilter)
            {
                if (recipe.defaultIngredientFilter != null)
                {
                    MergeExceptionsIntoHopperSettings(recipe.defaultIngredientFilter);
                }
                if (recipe.fixedIngredientFilter != null)
                {
                    MergeExceptionsIntoHopperSettings(recipe.fixedIngredientFilter);
                }
            }

            // Exclude categories and things from other categories
            for (int index = 0; index < hopperSettings.Count; index++)
            {
                var settingA = hopperSettings[index];
                if (
                    (settingA.fixedCategoryDef != null) &&
                    (settingA.settings.filter.AllowedDefCount > 1)
                    )
                {
                    for (int index2 = 0; index2 < hopperSettings.Count; index2++)
                    {
                        if (index != index2)
                        {
                            var settingB = hopperSettings[index2];
                            if (
                                (
                                    (settingB.fixedCategoryDef != null) &&
                                    (settingA.fixedCategoryDef.ThisAndChildCategoryDefs.Contains(settingB.fixedCategoryDef))
                                ) ||
                                (
                                    (settingB.fixedThingDef != null) &&
                                    (settingA.fixedCategoryDef.DescendantThingDefs.Contains(settingB.fixedThingDef))
                                )
                                )
                            {
                                foreach (var thingDef in settingB.settings.filter.AllowedThingDefs)
                                {
                                    settingA.settings.filter.SetAllow(thingDef, false);
                                }
                            }
                        }
                    }
                }
            }

            // Recheck hopper settings count requirements for the recipes
            foreach (var hopperSetting in hopperSettings)
            {
                int largest = 0;
                foreach (var recipe in recipeFilter)
                {
                    foreach (var thingDef in hopperSetting.settings.filter.AllowedThingDefs)
                    {
                        int thisThingDefCount = HopperSettingsAmount.CountForThingDef(thingDef, -1, recipe);
                        if (thisThingDefCount > largest)
                        {
                            largest = thisThingDefCount;
                        }
                    }
                }
                hopperSetting.fixedCount = largest;
            }

            // Remove empty hopper settings from the list
            for (int index = 0; index < hopperSettings.Count; index++)
            {
                var hopperSetting = hopperSettings[index];
                if (hopperSetting.settings.filter.AllowedDefCount < 1)
                {
                    hopperSettings.Remove(hopperSetting);
                }
            }

            // Sort the hopper settings from most required ingredients to least
            hopperSettings.Sort((x, y) => (x.fixedCount > y.fixedCount ? -1 : 1));

            // Finalize hopper settings
            for (int index = 0; index < hopperSettings.Count; ++index)
            {
                var hopperSetting = hopperSettings[index];
                hopperSetting.settings.Priority = StoragePriority.Important;
                hopperSetting.settings.filter.ResolveReferences();
                //hopperSetting.settings.filter.BlockDefaultAcceptanceFilters();
                hopperSetting.settings.filter.allowedQualitiesConfigurable = false;
            }

            settingsBuilt = true;
        }
 public static void AddToList( List<HopperSettingsAmount> list, ThingCategoryDef categoryDef, float baseCount, RecipeDef recipe )
 {
     int countNeeded = CountForCategoryDef( categoryDef, baseCount, recipe );
     for( int index = 0; index < list.Count; ++index )
     {
         if( list[ index ].fixedCategoryDef == categoryDef )
         {
             if( countNeeded > list[ index ].fixedCount )
             {
                 list[ index ] = new HopperSettingsAmount( list[ index ].fixedCategoryDef, countNeeded );
             }
             return;
         }
     }
     list.Add( new HopperSettingsAmount( categoryDef, countNeeded ) );
 }