Example #1
0
 protected override Thing           FindFeedInAnyHopper()
 {
     // Check for generic hoppers
     if (compHopperUser != null)
     {
         var hoppers = compHopperUser.FindHoppers();
         if (!hoppers.NullOrEmpty())
         {
             foreach (var hopper in hoppers)
             {
                 var resources = hopper.GetAllResources(compHopperUser.Resources);
                 if (!resources.NullOrEmpty())
                 {
                     foreach (var resource in resources)
                     {
                         // This check shouldn't be needed, but we'll do it as a fail-safe
                         if (Building_NutrientPasteDispenser.IsAcceptableFeedstock(resource.def))
                         {
                             return(resource);
                         }
                     }
                 }
             }
         }
     }
     // Check for vanilla hoppers
     return(base.FindFeedInAnyHopper());
 }
        public static bool Prefix(ref Job __result, Pawn pawn, Thing thing)
        {
            __result = null;
            if (!(thing is ISlotGroupParent hopperSgp))
            {
                return(false);
            }

            var setting = hopperSgp.GetStoreSettings();
            var limit   = setting.GetStacklimit();

            if (setting.IsRefillingDisabled() || limit == 0)
            {
                return(false);
            }

            foreach (var thing2 in pawn.Map.thingGrid.ThingsListAt(thing.Position))
            {
                if (Building_NutrientPasteDispenser.IsAcceptableFeedstock(thing2.def))
                {
                    if ((thing2.stackCount * 100) >= ((limit < 0 ? thing2.def.stackLimit : limit) * setting.GetRefillPercent()))
                    {
                        return(false);
                    }
                }
            }
            return(true);
        }
        static bool Prefix(Building_NutrientPasteDispenser __instance, ref Thing __result)
        {
            var fc = FridgeCache.GetFridgeCache(__instance.Map);

            foreach (IntVec3 cell in __instance.AdjCellsCardinalInBounds)
            {
                Thing thing  = null;
                Thing holder = null;
                foreach (Thing t in cell.GetThingList(__instance.Map))
                {
                    if (Building_NutrientPasteDispenser.IsAcceptableFeedstock(t.def))
                    {
                        thing = t;
                    }
                    if (t.def == ThingDefOf.Hopper || fc?.HasFridgeAt(cell) == true)
                    {
                        holder = t;
                    }
                }
                if (thing != null && holder != null)
                {
                    __result = thing;
                    return(false);
                }
            }
            return(false);
        }
        public static bool HasEnoughFeedstockInStorage(ref bool __result, Building_NutrientPasteDispenser __instance)
        {
            if (!(__instance.def.GetModExtension <NPDModExtension>() is null))
            {
                bool empty = __instance.def.GetModExtension <NPDModExtension>().ingredientList is null ||
                             !__instance.def.GetModExtension <NPDModExtension>().ingredientList.Any();
                if (!empty && !(__instance.def.GetCompProperties <CompProperties_Refillable>() is null))
                {
                    __result = false;
                    List <IngredientAndCostClass> ingredientList = __instance.def.GetModExtension <NPDModExtension>().ingredientList;

                    for (int i = 0; i < ingredientList.Count; i++)
                    {
                        IngredientAndCostClass ingredient = ingredientList[i];
                        if (__instance.GetComp <CompRefillable>().items[i] < ingredient.nutritionCost)
                        {
                            __result = false;
                            return(false);
                        }
                    }
                    __result = true;
                    return(false);
                }
                Log.Error("Must include ingredient list if using CompRefillable comp class");
            }
            return(true);
        }
        static bool Prefix(Building_NutrientPasteDispenser __instance, ref bool __result)
        {
            var fc = FridgeCache.GetFridgeCache(__instance.Map);

            float num = 0f;

            foreach (IntVec3 cell in __instance.AdjCellsCardinalInBounds)
            {
                Thing thing  = null;
                Thing holder = null;
                foreach (Thing t in cell.GetThingList(__instance.Map))
                {
                    if (Building_NutrientPasteDispenser.IsAcceptableFeedstock(t.def))
                    {
                        thing = t;
                    }
                    if (t.def == ThingDefOf.Hopper || fc?.HasFridgeAt(cell) == true)
                    {
                        holder = t;
                    }

                    if (thing != null && holder != null)
                    {
                        num += (float)thing.stackCount * thing.GetStatValue(StatDefOf.Nutrition, true);
                        if (num >= __instance.def.building.nutritionCostPerDispense)
                        {
                            __result = true;
                            return(false);
                        }
                        break;
                    }
                }
            }
            return(false);
        }
Example #6
0
 public static bool FindFeedInAnyCustomHopper(Building_NutrientPasteDispenser __instance, ref Thing __result, ref List <IntVec3> ___cachedAdjCellsCardinal)
 {
     if (___cachedAdjCellsCardinal is null)
     {
         ___cachedAdjCellsCardinal = (from c in GenAdj.CellsAdjacentCardinal(__instance)
                                      where c.InBounds(__instance.Map)
                                      select c).ToList <IntVec3>();
     }
     foreach (IntVec3 c in ___cachedAdjCellsCardinal)
     {
         Thing        thing     = null;
         Thing        thing2    = null;
         List <Thing> thingList = c.GetThingList(__instance.Map);
         foreach (Thing t in thingList)
         {
             if (Building_NutrientPasteDispenser.IsAcceptableFeedstock(t.def))
             {
                 thing = t;
             }
             if (t.def == ThingDefOf.Hopper || t.def.thingClass == typeof(NPDHopper_Storage))
             {
                 thing2 = t;
             }
         }
         if (thing != null && thing2 != null)
         {
             __result = thing;
             return(false);
         }
     }
     __result = null;
     return(true);
 }
Example #7
0
 public Thing FindNextIngredientInHopper(List <IntVec3> cachedCells, Building_NutrientPasteDispenser instance, float[] nutrition)
 {
     foreach (IntVec3 c in cachedCells)
     {
         Thing        thing     = null;
         Thing        thing2    = null;
         List <Thing> thingList = c.GetThingList(instance.Map);
         foreach (Thing t in thingList)
         {
             if (Building_NutrientPasteDispenser.IsAcceptableFeedstock(t.def) && this.ingredientList.Any(x => x.thingDef == t.def) &&
                 nutrition[ingredientList.FindIndex(x => x.thingDef == t.def)] > 0f)
             {
                 thing = t;
             }
             if (t.def == ThingDefOf.Hopper || t.def.thingClass == typeof(NPDHopper_Storage))
             {
                 thing2 = t;
             }
         }
         if (!(thing is null) && !(thing2 is null))
         {
             return(thing);
         }
     }
     return(null);
 }
Example #8
0
        public static bool AdjacentReachableHopperCustom(Pawn reacher, Building_NutrientPasteDispenser __instance, ref Building __result,
                                                         List <IntVec3> ___cachedAdjCellsCardinal)
        {
            if (__instance.def.HasModExtension <NutrientPasteCustom>())
            {
                if (___cachedAdjCellsCardinal is null)
                {
                    ___cachedAdjCellsCardinal = (from c in GenAdj.CellsAdjacentCardinal(__instance)
                                                 where c.InBounds(__instance.Map)
                                                 select c).ToList <IntVec3>();
                }
                foreach (IntVec3 c in ___cachedAdjCellsCardinal)
                {
                    Building edifice = c.GetEdifice(__instance.Map);

                    if (!(edifice is null) && (edifice.def == ThingDefOf.Hopper || edifice.def.thingClass == typeof(NPDHopper_Storage)) &&
                        reacher.CanReach(edifice, PathEndMode.Touch, Danger.Deadly, false, TraverseMode.ByPawn))
                    {
                        __result = edifice;
                        return(false);
                    }
                }
            }
            return(true);
        }
Example #9
0
 internal static List <IntVec3> _AdjCellsCardinalInBounds(Building_NutrientPasteDispenser obj)
 {
     if (__AdjCellsCardinalInBounds == null)
     {
         __AdjCellsCardinalInBounds = typeof(Building_NutrientPasteDispenser).GetProperty("AdjCellsCardinalInBounds", BindingFlags.Instance | BindingFlags.NonPublic);
     }
     return(__AdjCellsCardinalInBounds.GetValue(obj, null) as List <IntVec3>);
 }
Example #10
0
        internal static Thing           _FindFeedInAnyHopper(this Building_NutrientPasteDispenser obj)
        {
            // Check for generic hoppers
            var CompHopperUser = obj.TryGetComp <CompHopperUser>();

            if (CompHopperUser != null)
            {
                var hoppers = CompHopperUser.FindHoppers();
                if (!hoppers.NullOrEmpty())
                {
                    foreach (var hopper in hoppers)
                    {
                        var resources = hopper.GetAllResources(CompHopperUser.Resources);
                        if (!resources.NullOrEmpty())
                        {
                            foreach (var resource in resources)
                            {
                                // This check shouldn't be needed, but we'll do it as a fail-safe
                                if (Building_NutrientPasteDispenser.IsAcceptableFeedstock(resource.def))
                                {
                                    return(resource);
                                }
                            }
                        }
                    }
                }
            }
            // Check for vanilla hoppers
            var adjCells = _AdjCellsCardinalInBounds(obj);

            for (int cellIndex = 0; cellIndex < adjCells.Count; ++cellIndex)
            {
                IntVec3      c         = adjCells[cellIndex];
                Thing        resource  = (Thing)null;
                Thing        hopper    = (Thing)null;
                List <Thing> thingList = c.GetThingList();
                for (int thingIndex = 0; thingIndex < thingList.Count; ++thingIndex)
                {
                    Thing thisThing = thingList[thingIndex];
                    if (Building_NutrientPasteDispenser.IsAcceptableFeedstock(thisThing.def))
                    {
                        resource = thisThing;
                    }
                    if (thisThing.def == ThingDefOf.Hopper)
                    {
                        hopper = thisThing;
                    }
                }
                if (
                    (resource != null) &&
                    (hopper != null)
                    )
                {
                    return(resource);
                }
            }
            return((Thing)null);
        }
Example #11
0
 public static bool DispensableDefCustom(ref ThingDef __result, Building_NutrientPasteDispenser __instance)
 {
     if (__instance.def.HasModExtension <NutrientPasteCustom>())
     {
         __result = __instance.def.GetModExtension <NutrientPasteCustom>().customMeal;
         return(false);
     }
     return(true);
 }
Example #12
0
        internal static bool            _HasEnoughFeedstockInHoppers(this Building_NutrientPasteDispenser obj)
        {
            int costPerDispense = obj.def.building.foodCostPerDispense;

            /* Research Project cut from A13
             * if( ResearchProjectDef.Named( "NutrientResynthesis" ).IsFinished )
             * {
             *  costPerDispense--;
             * }
             */
            // Check for generic hoppers
            var CompHopperUser = obj.TryGetComp <CompHopperUser>();

            if (CompHopperUser != null)
            {
                if (CompHopperUser.EnoughResourcesInHoppers(costPerDispense))
                {
                    return(true);
                }
            }
            // Check for vanilla hoppers
            var adjCells      = _AdjCellsCardinalInBounds(obj);
            int resourceCount = 0;

            for (int cellIndex = 0; cellIndex < adjCells.Count; ++cellIndex)
            {
                IntVec3      c         = adjCells[cellIndex];
                Thing        resource  = (Thing)null;
                Thing        hopper    = (Thing)null;
                List <Thing> thingList = GridsUtility.GetThingList(c);
                for (int thingIndex = 0; thingIndex < thingList.Count; ++thingIndex)
                {
                    Thing thisThing = thingList[thingIndex];
                    if (Building_NutrientPasteDispenser.IsAcceptableFeedstock(thisThing.def))
                    {
                        resource = thisThing;
                    }
                    if (thisThing.def == ThingDefOf.Hopper)
                    {
                        hopper = thisThing;
                    }
                }
                if (
                    (resource != null) &&
                    (hopper != null)
                    )
                {
                    resourceCount += resource.stackCount;
                }
                if (resourceCount >= costPerDispense)
                {
                    return(true);
                }
            }
            return(false);
        }
        // RimWorld.Building_NutrientPasteDispenser
        //static private List<IntVec3> AdjCellsCardinalInBounds(this Building_NutrientPasteDispenser self)
        //{
        //	return (List<IntVec3>)typeof(RimWorld.Building_NutrientPasteDispenser).GetProperty("AdjCellsCardinalInBounds", Helpers.AllBindingFlags).GetValue(self,null);
        //}

        static private List <IntVec3> AdjCellsCardinalInBounds(this Building_NutrientPasteDispenser self)
        {
            if (self.cachedAdjCellsCardinal() == null)
            {
                var value = (from c in GenAdj.CellsAdjacentCardinal(self)
                             where c.InBounds(self.Map)
                             select c).ToList <IntVec3>();

                self.cachedAdjCellsCardinal_set_(value);
            }
            return(self.cachedAdjCellsCardinal());
        }
Example #14
0
        static void Postfix(Building __instance, ref IEnumerable <Gizmo> __result)
        {
            if (__instance is Building_NutrientPasteDispenser)
            {
                //Log.Message("Hello from Harmony Postfix Patch_Building_GetGizmos " + __result.Count());

                //Building_NutrientPasteDispenser myThis = (Building_NutrientPasteDispenser)__instance;
                //MethodInfo CanDispenseNow = myThis.GetType().GetMethod("CanDispenseNow", BindingFlags.Instance | BindingFlags.Public);
                //MethodInfo TryDispenseFood = myThis.GetType().GetMethod("TryDispenseFood", BindingFlags.Instance | BindingFlags.Public);

                //int[] numbers = { 1, 5, 25 };
                //foreach (int i in numbers)
                //{
                //    Gizmo newGizmo = new Command_Action
                //    {
                //        defaultLabel = "Dispense " + i,
                //        action = delegate
                //        {
                //            int k = i;
                //            for (int j = 0; j < k && (bool) CanDispenseNow.Invoke(myThis, null); j++)
                //            {
                //                TryDispenseFood.Invoke(myThis, null);
                //            }
                //        }
                //    };
                //    __result.Add(newGizmo);
                //}

                Building_NutrientPasteDispenser myThis = (Building_NutrientPasteDispenser)__instance;

                int[] numbers = { 1, 5, 25 };
                foreach (int i in numbers)
                {
                    Gizmo newGizmo = new Command_Action
                    {
                        defaultLabel = "Dispense " + i,
                        icon         = ContentFinder <Texture2D> .Get("UI/Designators/Open"),
                        action       = delegate
                        {
                            for (int j = 0; j < i && myThis.CanDispenseNow; j++)
                            {
                                Thing meal = myThis.TryDispenseFood();
                                GenPlace.TryPlaceThing(meal, myThis.InteractionCell, myThis.Map, ThingPlaceMode.Near);
                            }
                        }
                    };
                    __result = __result.AddItem(newGizmo);
                }
                //Log.Message("Goodbye from Harmony Postfix Patch_Building_GetGizmos " + __result.Count());
            }
        }
        static List <Thing> IngredientsFor(Building_NutrientPasteDispenser self, DispenseMode mode)
        {
            var list = GetAllHoppersThings(self);

            int[] foodCountByRank = new int[4];

            for (int i = 0; i < 4; i++)
            {
                var current = foodCountByRank[i];
                foodCountByRank[i] = list.Where((arg) => rankForPawn(mode, arg.def) == i).Sum((arg) => arg.stackCount);
            }

            FoodCategory[] ranking;

            if (mode == DispenseMode.Cannibal || mode == DispenseMode.CannibalClean)
            {
                ranking = ranksForCannibals;
            }
            else if (mode == DispenseMode.Animal)
            {
                ranking = ranksForAnimals;
            }
            else
            {
                ranking = ranksForOthers;
            }

            var rawbadindex   = Array.IndexOf(ranking, FoodCategory.RawBad);
            var rawtastyindex = Array.IndexOf(ranking, FoodCategory.RawTasty);

            foodCountByRank[rawbadindex] = foodCountByRank[rawtastyindex] = foodCountByRank[rawbadindex] + foodCountByRank[rawtastyindex];

            var query = (from e in list
                         orderby foodCountByRank[rankForPawn(mode, e.def)] < 6, rankForPawn(mode, e.def), (e.TryGetComp <CompRottable>() != null ? e.TryGetComp <CompRottable>().TicksUntilRotAtCurrentTemp : -9999999)
                         select e).ToList();

            if (mode == DispenseMode.Clean)
            {
                query = query.Where((Thing arg) => !RimWorld.FoodUtility.IsHumanlikeMeat(arg.def) && arg.def.DetermineFoodCategory() != FoodCategory.RawInsect).ToList();
            }
            else if (mode == DispenseMode.CannibalClean)
            {
                query = query.Where((Thing arg) => arg.def.DetermineFoodCategory() != FoodCategory.RawInsect).ToList();
            }

            return(query);
        }
Example #16
0
        internal static Building        _AdjacentReachableHopper(this Building_NutrientPasteDispenser obj, Pawn reacher)
        {
            // Check for generic hoppers
            var CompHopperUser = obj.TryGetComp <CompHopperUser>();

            if (CompHopperUser != null)
            {
                var hoppers = CompHopperUser.FindHoppers();
                if (!hoppers.NullOrEmpty())
                {
                    foreach (var hopper in hoppers)
                    {
                        if (
                            reacher.CanReach(
                                ( TargetInfo )(( Thing )hopper.parent),
                                PathEndMode.Touch,
                                reacher.NormalMaxDanger(),
                                false)
                            )
                        {
                            return((Building)hopper.parent);
                        }
                    }
                }
            }
            // Check for vanilla hoppers
            var adjCells = _AdjCellsCardinalInBounds(obj);

            for (int index = 0; index < adjCells.Count; ++index)
            {
                Building edifice = adjCells[index].GetEdifice();
                if (
                    (edifice != null) &&
                    (edifice.def == ThingDefOf.Hopper) &&
                    (reacher.CanReach(
                         ( TargetInfo )(( Thing )edifice),
                         PathEndMode.Touch,
                         reacher.NormalMaxDanger(),
                         false))
                    )
                {
                    return(edifice);
                }
            }
            return((Building)null);
        }
        static List <Thing> GetAllHoppersThings(this RimWorld.Building_NutrientPasteDispenser self)
        {
            var list = new List <Thing>();

            for (int i = 0; i < self.AdjCellsCardinalInBounds().Count; i++)
            {
                IntVec3  c       = self.AdjCellsCardinalInBounds()[i];
                Building edifice = c.GetEdifice(self.Map);
                if (edifice != null && edifice.def == ThingDefOf.Hopper
                    // && eater.CanReach(edifice, PathEndMode.Touch, Danger.Deadly, false, TraverseMode.ByPawn)
                    )
                {
                    List <Thing> thingList = self.AdjCellsCardinalInBounds()[i].GetThingList(self.Map).ToList();

                    list.AddRange(thingList.Where((Thing arg) => Building_NutrientPasteDispenser.IsAcceptableFeedstock(arg.def)));
                }
            }

            return(list);
        }
Example #18
0
 static void Postfix(Building_NutrientPasteDispenser __instance, ref Thing __result)
 {
     if (__result == null)
     {
         //loop over Inputs
         for (int i = 0; i < __instance.AdjCellsCardinalInBounds.Count; i++)
         {
             //Get list of Items
             INutrientPasteDispenserInput input = (INutrientPasteDispenserInput)__instance.AdjCellsCardinalInBounds[i].GetThingList(__instance.Map).Where(thing => thing is INutrientPasteDispenserInput).FirstOrDefault();
             if (input == null || input.NPDI_Item == null)
             {
                 continue;
             }
             if (Building_NutrientPasteDispenser.IsAcceptableFeedstock(input.NPDI_Item.def))
             {
                 __result = input.NPDI_Item;
             }
             if (__result != null)
             {
                 break;
             }
         }
     }
 }
Example #19
0
        public static bool HasEnoughFeedstockInCustomHoppers(ref bool __result, Building_NutrientPasteDispenser __instance, ref List <IntVec3> ___cachedAdjCellsCardinal)
        {
            if (!(__instance.def.GetModExtension <NutrientPasteCustom>() is null))
            {
                if (___cachedAdjCellsCardinal is null)
                {
                    ___cachedAdjCellsCardinal = (from c in GenAdj.CellsAdjacentCardinal(__instance)
                                                 where c.InBounds(__instance.Map)
                                                 select c).ToList <IntVec3>();
                }

                float num   = 0f;
                bool  empty = __instance.def.GetModExtension <NutrientPasteCustom>().ingredientList is null ||
                              !__instance.def.GetModExtension <NutrientPasteCustom>().ingredientList.Any();
                if (!empty)
                {
                    __result = false;
                    List <IngredientAndCostClass> ingredientList = __instance.def.GetModExtension <NutrientPasteCustom>().ingredientList;
                    bool[]  ingredientFulfilled = new bool[ingredientList.Count];
                    float[] nutritionCost       = new float[ingredientList.Count];
                    foreach (IntVec3 c in ___cachedAdjCellsCardinal)
                    {
                        Thing        thing     = null;
                        Thing        thing2    = null;
                        List <Thing> thingList = c.GetThingList(__instance.Map);
                        foreach (Thing t in thingList)
                        {
                            if (Building_NutrientPasteDispenser.IsAcceptableFeedstock(t.def) && ingredientList.Any(x => x.thingDef == t.def) &&
                                nutritionCost[ingredientList.FindIndex(x => x.thingDef == t.def)] <= 0f)
                            {
                                thing = t;
                            }
                            if (t.def == ThingDefOf.Hopper || t.def.thingClass == typeof(NPDHopper_Storage))
                            {
                                thing2 = t;
                            }
                        }
                        if (!(thing is null) && !(thing2 is null))
                        {
                            nutritionCost[ingredientList.FindIndex(x => x.thingDef == thing.def)] += (float)thing.stackCount * thing.GetStatValue(StatDefOf.Nutrition, true);
                            if (nutritionCost[ingredientList.FindIndex(x => x.thingDef == thing.def)] >= ingredientList.Find(x => x.thingDef == thing.def).nutritionCost)
                            {
                                ingredientFulfilled[ingredientList.FindIndex(x => x.thingDef == thing.def)] = true;
                            }
                        }

                        if (ingredientFulfilled.All(x => x))
                        {
                            __result = true;
                            return(false);
                        }
                    }
                    return(false);
                }
                foreach (IntVec3 c in ___cachedAdjCellsCardinal)
                {
                    Thing        thing     = null;
                    Thing        thing2    = null;
                    List <Thing> thingList = c.GetThingList(__instance.Map);
                    foreach (Thing t in thingList)
                    {
                        if (Building_NutrientPasteDispenser.IsAcceptableFeedstock(t.def))
                        {
                            thing = t;
                        }
                        if (t.def == ThingDefOf.Hopper || t.def.thingClass == typeof(NPDHopper_Storage))
                        {
                            thing2 = t;
                        }
                    }
                    if (thing != null && thing2 != null)
                    {
                        num += (float)thing.stackCount * thing.GetStatValue(StatDefOf.Nutrition, true);
                    }
                    if (num >= __instance.def.building.nutritionCostPerDispense)
                    {
                        __result = true;
                        return(false);
                    }
                }
                __result = false;
                return(false);
            }
            return(true);
        }
Example #20
0
        public Thing BestFoodSourceOnMap(Pawn getter, Pawn eater, bool desperate, out ThingDef foodDef, FoodPreferability maxPref = FoodPreferability.MealLavish, bool allowPlant = true, bool allowDrug = true, bool allowCorpse = true, bool allowDispenserFull = true, bool allowDispenserEmpty = true, bool allowForbidden = false, bool allowSociallyImproper = false, bool allowHarvest = false, bool forceScanWholeMap = false, bool ignoreReservations = false, bool calculateWantedStackCount = false, FoodPreferability minPrefOverride = FoodPreferability.Undefined, float?minNutrition = null)
        {
            foodDef = null;

            FoodPreferability minPref;

            if (minPrefOverride == FoodPreferability.Undefined)
            {
                if (eater.NonHumanlikeOrWildMan())
                {
                    minPref = FoodPreferability.NeverForNutrition;
                }
                else if (desperate)
                {
                    minPref = FoodPreferability.DesperateOnly;
                }
                else
                {
                    minPref = (((int)eater.needs.food.CurCategory >= 2) ? FoodPreferability.RawBad : FoodPreferability.MealAwful);
                }
            }
            else
            {
                minPref = minPrefOverride;
            }
            Predicate <Thing> foodValidator = delegate(Thing t)
            {
                Building_NutrientPasteDispenser building_NutrientPasteDispenser = t as Building_NutrientPasteDispenser;
                if (building_NutrientPasteDispenser != null)
                {
                    if (!allowDispenserFull || (int)ThingDefOf.MealNutrientPaste.ingestible.preferability < (int)minPref || (int)ThingDefOf.MealNutrientPaste.ingestible.preferability > (int)maxPref || !eater.WillEat(ThingDefOf.MealNutrientPaste, getter) || (t.Faction != getter.Faction && t.Faction != getter.HostFaction) || (!allowForbidden && t.IsForbidden(getter)) || !building_NutrientPasteDispenser.powerComp.PowerOn || (!allowDispenserEmpty && !building_NutrientPasteDispenser.HasEnoughFeedstockInHoppers()) || !t.InteractionCell.Standable(t.Map) || !IsFoodSourceOnMapSociallyProper(t, getter, eater, allowSociallyImproper) || !getter.Map.reachability.CanReachNonLocal(getter.Position, new TargetInfo(t.InteractionCell, t.Map), PathEndMode.OnCell, TraverseParms.For(getter, Danger.Some)))
                    {
                        return(false);
                    }
                }
                else
                {
                    int   stackCount = 1;
                    float statValue  = t.GetStatValue(StatDefOf.Nutrition);
                    if (minNutrition.HasValue)
                    {
                        stackCount = FoodUtility.StackCountForNutrition(minNutrition.Value, statValue);
                    }
                    else if (calculateWantedStackCount)
                    {
                        stackCount = FoodUtility.WillIngestStackCountOf(eater, t.def, statValue);
                    }
                    if ((int)t.def.ingestible.preferability < (int)minPref || (int)t.def.ingestible.preferability > (int)maxPref || !eater.WillEat(t, getter) || !t.def.IsNutritionGivingIngestible || !t.IngestibleNow || (!allowCorpse && t is Corpse) || (!allowDrug && t.def.IsDrug) || (!allowForbidden && t.IsForbidden(getter)) || (!desperate && t.IsNotFresh()) || t.IsDessicated() || !IsFoodSourceOnMapSociallyProper(t, getter, eater, allowSociallyImproper) || (!getter.AnimalAwareOf(t) && !forceScanWholeMap) || (!ignoreReservations && !getter.CanReserve(t, 10, stackCount)))
                    {
                        return(false);
                    }
                }
                return(true);
            };
            ThingRequest thingRequest = ((eater.RaceProps.foodType & (FoodTypeFlags.Plant | FoodTypeFlags.Tree)) == 0 || !allowPlant) ? ThingRequest.ForGroup(ThingRequestGroup.FoodSourceNotPlantOrTree) : ThingRequest.ForGroup(ThingRequestGroup.FoodSource);
            Thing        bestThing;

            if (getter.RaceProps.Humanlike)
            {
                bestThing = SpawnedFoodSearchInnerScan(eater, getter.Position, getter.Map.listerThings.ThingsMatching(thingRequest), PathEndMode.ClosestTouch, TraverseParms.For(getter), 9999f, foodValidator);
                if (allowHarvest)
                {
                    Thing thing = GenClosest.ClosestThingReachable(searchRegionsMax : (!forceScanWholeMap || bestThing != null) ? 30 : (-1), root : getter.Position, map : getter.Map, thingReq : ThingRequest.ForGroup(ThingRequestGroup.HarvestablePlant), peMode : PathEndMode.Touch, traverseParams : TraverseParms.For(getter), maxDistance : 9999f, validator : delegate(Thing x)
                    {
                        Plant plant = (Plant)x;
                        if (!plant.HarvestableNow)
                        {
                            return(false);
                        }
                        ThingDef harvestedThingDef = plant.def.plant.harvestedThingDef;
                        if (!harvestedThingDef.IsNutritionGivingIngestible)
                        {
                            return(false);
                        }
                        if (!eater.WillEat(harvestedThingDef, getter))
                        {
                            return(false);
                        }
                        if (!getter.CanReserve(plant))
                        {
                            return(false);
                        }
                        if (!allowForbidden && plant.IsForbidden(getter))
                        {
                            return(false);
                        }
                        return((bestThing == null || (int)FoodUtility.GetFinalIngestibleDef(bestThing).ingestible.preferability < (int)harvestedThingDef.ingestible.preferability) ? true : false);
                    });
                    if (thing != null)
                    {
                        bestThing = thing;
                        foodDef   = FoodUtility.GetFinalIngestibleDef(thing, harvest: true);
                    }
                }
                if (foodDef == null && bestThing != null)
                {
                    foodDef = FoodUtility.GetFinalIngestibleDef(bestThing);
                }
            }
            else
            {
                int maxRegionsToScan = GetMaxRegionsToScan(getter, forceScanWholeMap);
                filtered.Clear();
                foreach (Thing item in GenRadial.RadialDistinctThingsAround(getter.Position, getter.Map, 2f, useCenter: true))
                {
                    Pawn pawn = item as Pawn;
                    if (pawn != null && pawn != getter && pawn.RaceProps.Animal && pawn.CurJob != null && pawn.CurJob.def == JobDefOf.Ingest && pawn.CurJob.GetTarget(TargetIndex.A).HasThing)
                    {
                        filtered.Add(pawn.CurJob.GetTarget(TargetIndex.A).Thing);
                    }
                }
                bool ignoreEntirelyForbiddenRegions = !allowForbidden && ForbidUtility.CaresAboutForbidden(getter, cellTarget: true) && getter.playerSettings != null && getter.playerSettings.EffectiveAreaRestrictionInPawnCurrentMap != null;
                Predicate <Thing> validator         = delegate(Thing t)
                {
                    if (!foodValidator(t))
                    {
                        return(false);
                    }
                    if (filtered.Contains(t))
                    {
                        return(false);
                    }
                    if (!(t is Building_NutrientPasteDispenser) && (int)t.def.ingestible.preferability <= 2)
                    {
                        return(false);
                    }
                    return((!t.IsNotFresh()) ? true : false);
                };
                bestThing = GenClosest.ClosestThingReachable(getter.Position, getter.Map, thingRequest, PathEndMode.ClosestTouch, TraverseParms.For(getter), 9999f, validator, null, 0, maxRegionsToScan, forceAllowGlobalSearch: false, RegionType.Set_Passable, ignoreEntirelyForbiddenRegions);
                filtered.Clear();
                if (bestThing == null)
                {
                    desperate = true;
                    bestThing = GenClosest.ClosestThingReachable(getter.Position, getter.Map, thingRequest, PathEndMode.ClosestTouch, TraverseParms.For(getter), 9999f, foodValidator, null, 0, maxRegionsToScan, forceAllowGlobalSearch: false, RegionType.Set_Passable, ignoreEntirelyForbiddenRegions);
                }
                if (bestThing != null)
                {
                    foodDef = FoodUtility.GetFinalIngestibleDef(bestThing);
                }
            }
            return(bestThing);
        }
 static private List <IntVec3> cachedAdjCellsCardinal(this Building_NutrientPasteDispenser self)
 {
     return((List <IntVec3>) typeof(RimWorld.Building_NutrientPasteDispenser).GetField("cachedAdjCellsCardinal", Helpers.AllBindingFlags).GetValue(self));
 }
 static private void cachedAdjCellsCardinal_set_(this Building_NutrientPasteDispenser self, List <IntVec3> value)
 {
     typeof(RimWorld.Building_NutrientPasteDispenser).GetField("cachedAdjCellsCardinal", Helpers.AllBindingFlags).SetValue(self, value);
 }
Example #23
0
        internal static Job HopperFillFoodJob(Pawn pawn, Building hopper, Thing parent)
        {
            var hopperSgp = hopper as ISlotGroupParent;

            if (
                (!pawn.CanReserveAndReach(
                     hopper.Position,
                     PathEndMode.Touch,
                     pawn.NormalMaxDanger(),
                     1)
                )
                )
            {
                return(null);
            }
            ThingDef resourceDef = null;
            var      firstItem   = hopper.Position.GetFirstItem();

            if (firstItem != null)
            {
                if (
                    (
                        (parent is Building_NutrientPasteDispenser) &&
                        (Building_NutrientPasteDispenser.IsAcceptableFeedstock(firstItem.def))
                    ) ||
                    (
                        (parent is Building_AutomatedFactory) &&
                        (((Building_AutomatedFactory)parent).CompHopperUser.ResourceSettings.AllowedToAccept(firstItem))
                    )
                    )
                {
                    resourceDef = firstItem.def;
                }
                else
                {
                    if (firstItem.IsForbidden(pawn))
                    {
                        return(( Job )null);
                    }
                    return(HaulAIUtility.HaulAsideJobFor(pawn, firstItem));
                }
            }
            List <Thing> list =
                resourceDef != null
                ? Find.Map.listerThings.ThingsOfDef(resourceDef)
                : Find.Map.listerThings.ThingsInGroup(ThingRequestGroup.FoodSourceNotPlantOrTree);

            for (int index = 0; index < list.Count; ++index)
            {
                Thing t = list[index];
                if (
                    (t.def.IsNutritionGivingIngestible) &&
                    (
                        (t.def.ingestible.preferability == FoodPreferability.RawBad) ||
                        (t.def.ingestible.preferability == FoodPreferability.RawTasty)
                    ) &&
                    (HaulAIUtility.PawnCanAutomaticallyHaul(pawn, t)) &&
                    (
                        (Find.SlotGroupManager.SlotGroupAt(hopper.Position).Settings.AllowedToAccept(t)) &&
                        (HaulAIUtility.StoragePriorityAtFor(t.Position, t) < hopperSgp.GetSlotGroup().Settings.Priority)
                    )
                    )
                {
                    Job job = HaulAIUtility.HaulMaxNumToCellJob(pawn, t, hopper.Position, true);
                    if (job != null)
                    {
                        return(job);
                    }
                }
            }
            return(null);
        }
 static private void cachedAdjCellsCardinal_set_(this Building_NutrientPasteDispenser self, List <IntVec3> value)
 {
     typeof(RimWorld.Building_NutrientPasteDispenser).GetField("cachedAdjCellsCardinal", AccessTools.all).SetValue(self, value);
 }
Example #25
0
        public static bool TryDispenseCustomFood(ref Thing __result, Building_NutrientPasteDispenser __instance, ref List <IntVec3> ___cachedAdjCellsCardinal)
        {
            if (__instance.def.HasModExtension <NutrientPasteCustom>())
            {
                if (!__instance.CanDispenseNow)
                {
                    __result = null;
                    return(false);
                }
                List <ThingDef> list = new List <ThingDef>();
                List <IngredientAndCostClass> ingredientList = __instance.def.GetModExtension <NutrientPasteCustom>().ingredientList;
                bool empty = !__instance.def.GetModExtension <NutrientPasteCustom>().ingredientList.Any();
                Log.Message("-" + empty);
                if (!empty)
                {
                    float[] nutritionLeft = new float[ingredientList.Count];
                    for (int i = 0; i < nutritionLeft.Length; i++)
                    {
                        nutritionLeft[i] = ingredientList[i].nutritionCost;
                    }
                    for (; ;)
                    {
                        Thing thing = __instance.def.GetModExtension <NutrientPasteCustom>().FindNextIngredientInHopper(___cachedAdjCellsCardinal, __instance, nutritionLeft);
                        if (thing is null)
                        {
                            break;
                        }
                        int index = ingredientList.FindIndex(x => x.thingDef == thing.def);
                        int num2  = Mathf.Min(thing.stackCount, Mathf.CeilToInt(nutritionLeft[index] / thing.GetStatValue(StatDefOf.Nutrition, true)));
                        nutritionLeft[index] -= (float)num2 * thing.GetStatValue(StatDefOf.Nutrition, true);
                        list.Add(thing.def);
                        thing.SplitOff(num2);
                        if (!nutritionLeft.Any(x => x > 0f))
                        {
                            goto Block_3;
                        }
                    }
                }
                else
                {
                    Log.Message("2");
                    float num = __instance.def.building.nutritionCostPerDispense - 0.0001f;
                    for (; ;)
                    {
                        Thing thing = __instance.FindFeedInAnyHopper();
                        if (thing is null)
                        {
                            break;
                        }
                        int num2 = Mathf.Min(thing.stackCount, Mathf.CeilToInt(num / thing.GetStatValue(StatDefOf.Nutrition, true)));
                        num -= (float)num2 * thing.GetStatValue(StatDefOf.Nutrition, true);
                        list.Add(thing.def);
                        thing.SplitOff(num2);
                        if (num <= 0f)
                        {
                            goto Block_3;
                        }
                    }
                }

                Log.Error("Did not find enough food in hoppers while trying to dispense.", false);
                __result = null;
                return(false);

Block_3:
                __instance.def.building.soundDispense.PlayOneShot(new TargetInfo(__instance.Position, __instance.Map, false));
                Thing           thing2          = ThingMaker.MakeThing(__instance.def.GetModExtension <NutrientPasteCustom>().customMeal, null);
                CompIngredients compIngredients = thing2.TryGetComp <CompIngredients>();
                foreach (ThingDef ingredient in list)
                {
                    if (!__instance.def.GetModExtension <NutrientPasteCustom>().mysteryIngredients)
                    {
                        compIngredients.RegisterIngredient(ingredient);
                    }
                }
                __result = thing2;
                return(false);
            }
            return(true);
        }
 static private List <IntVec3> cachedAdjCellsCardinal(this Building_NutrientPasteDispenser self)
 {
     return((List <IntVec3>) typeof(RimWorld.Building_NutrientPasteDispenser).GetField("cachedAdjCellsCardinal", AccessTools.all).GetValue(self));
 }
Example #27
0
        static void Postfix(Building_NutrientPasteDispenser __instance, ref bool __result)
        {
            //Sadly witth the current valilla implementation adding support between mods is difficult.
            //Each mod needs to patch this but cant build on the progress of the other one.
            //
            //If for example Rimfrige supplies 50% of the nutriants then we will never know about it
            //If we want to support the input of other mods we need a patch for them.

            if (__result == false)
            {
                //Support for Rimfrige
                object rimFridgeCache = null;
                if (ProjectRimFactory_ModComponent.ModSupport_RrimFrige_Dispenser)
                {
                    rimFridgeCache = ProjectRimFactory_ModComponent.ModSupport_RrimFridge_GetFridgeCache.Invoke(null, new object[] { (object)__instance.Map });
                }


                float num = 0f;
                for (int i = 0; i < __instance.AdjCellsCardinalInBounds.Count; i++)
                {
                    IntVec3 c = __instance.AdjCellsCardinalInBounds[i];
                    INutrientPasteDispenserInput input = (INutrientPasteDispenserInput)c.GetThingList(__instance.Map).Where(thing => thing is INutrientPasteDispenserInput).FirstOrDefault();
                    if (input != null && input.NPDI_Item != null && Building_NutrientPasteDispenser.IsAcceptableFeedstock(input.NPDI_Item.def))
                    {
                        num += (float)input.NPDI_Item.stackCount * input.NPDI_Item.GetStatValue(StatDefOf.Nutrition);
                    }
                    else
                    {
                        Thing        thing     = null;
                        Thing        thing2    = null;
                        List <Thing> thingList = c.GetThingList(__instance.Map);
                        for (int j = 0; j < thingList.Count; j++)
                        {
                            Thing thing3 = thingList[j];
                            if (Building_NutrientPasteDispenser.IsAcceptableFeedstock(thing3.def))
                            {
                                thing = thing3;
                            }

                            //Support for Rimfrige
                            if (rimFridgeCache != null)
                            {
                                bool isfc = (bool)ProjectRimFactory_ModComponent.ModSupport_RrimFridge_HasFridgeAt.Invoke(rimFridgeCache, new object[] { (object)c });
                                if (isfc)
                                {
                                    thing2 = thing3;
                                }
                            }

                            if (thing3.def == ThingDefOf.Hopper)
                            {
                                thing2 = thing3;
                            }
                        }
                        if (thing != null && thing2 != null)
                        {
                            num += (float)thing.stackCount * thing.GetStatValue(StatDefOf.Nutrition);
                        }
                    }

                    if (num >= __instance.def.building.nutritionCostPerDispense)
                    {
                        __result = true;
                        break;
                    }
                }
            }
        }