Ejemplo n.º 1
0
        static bool Internal(Caravan caravan, Pawn forPawn, out Thing food, out Pawn owner)
        {
            List <Thing> list = RimWorld.Planet.CaravanInventoryUtility.AllInventoryItems(caravan)
                                .Where(arg => CaravanPawnsNeedsUtility.CanNowEatForNutrition(arg.def, forPawn)).ToList();
            Thing thing = null;

            Policy policy       = forPawn.GetPolicyAssignedTo();
            var    foodsForPawn = FoodUtils.MakeRatedFoodListFromThingList(list, forPawn, forPawn, forPawn.GetPolicyAssignedTo())
                                  .Where(arg => RimWorld.Planet.CaravanPawnsNeedsUtility.CanNowEatForNutrition(arg.FoodSource.def, forPawn) &&
                                         policy.PolicyAllows(forPawn, arg.FoodSource));

            var foodEntry = foodsForPawn.FirstOrDefault();

            if (foodEntry != null)
            {
                thing = foodsForPawn.FirstOrDefault().FoodSource;
            }
            else
            {
                thing = null;
            }

            if (thing != null)
            {
#if DEBUG
                Log.Message("Caravan: best food for " + forPawn + " = " + thing);
#endif
                food  = thing;
                owner = RimWorld.Planet.CaravanInventoryUtility.GetOwnerOf(caravan, thing);
                return(true);
            }
#if DEBUG
            Log.Message("Caravan: no food found for " + forPawn);
#endif
            food  = null;
            owner = null;
            return(false);
        }
Ejemplo n.º 2
0
        internal static bool Internal(Pawn getter, Pawn eater, bool desperate, out Thing foodSource, out ThingDef foodDef, bool canRefillDispenser = true, bool canUseInventory = true, bool allowForbidden = false, bool allowCorpse = true, Policy forcedPolicy = null)
        {
            List <FoodSourceRating> FoodListForPawn;

            FoodSearchCache.PawnEntry pawnEntry;

            if (!FoodSearchCache.TryGetEntryForPawn(getter, eater, out pawnEntry, allowForbidden))
            {
                Policy policy;

                if (forcedPolicy != null)
                {
                    policy = forcedPolicy;
                }
                else
                {
                    policy = PolicyUtils.GetPolicyAssignedTo(eater, getter);
                }

                bool foundFood = FoodUtils.MakeRatedFoodListForPawn(getter.Map, eater, getter, policy, out FoodListForPawn, canUseInventory, allowForbidden);

                pawnEntry = FoodSearchCache.AddPawnEntry(getter, eater, FoodListForPawn);
            }

            bool flagAllowHunt  = (getter == eater && eater.RaceProps.predator && !eater.health.hediffSet.HasTendableInjury());
            bool flagAllowPlant = (getter == eater);

            // C# 5 :'(
            var foodSourceRating = pawnEntry.GetBestFoodEntry(flagAllowPlant, allowCorpse, flagAllowHunt);

            if (foodSourceRating != null)
            {
                foodSource = foodSourceRating.FoodSource;
            }
            else
            {
                foodSource = null;
            }

            if (foodSource == null)              // ** If no food source is found set food Definition to null and return
            {
                foodDef = null;
                return(false);
            }

            foodDef = RimWorld.FoodUtility.GetFinalIngestibleDef(foodSource);             // ** Set food definition of food source and return
            return(true);

            //bool flag = getter.RaceProps.ToolUser && getter.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation);
            //Thing thing = null;
            //if (canUseInventory)
            //{
            //	if (flag)
            //	{
            //		thing = RimWorld.FoodUtility.BestFoodInInventory(getter, null, FoodPreferability.MealAwful, FoodPreferability.MealLavish, 0f, false);
            //	}
            //	if (thing != null)
            //	{
            //		if (getter.Faction != Faction.OfPlayer)
            //		{
            //			foodSource = thing;
            //			foodDef = RimWorld.FoodUtility.GetFinalIngestibleDef(foodSource);
            //			return true;
            //		}
            //		CompRottable compRottable = thing.TryGetComp<CompRottable>();
            //		if (compRottable != null && compRottable.Stage == RotStage.Fresh && compRottable.TicksUntilRotAtCurrentTemp < 30000)
            //		{
            //			foodSource = thing;
            //			foodDef = RimWorld.FoodUtility.GetFinalIngestibleDef(foodSource);
            //			return true;
            //		}
            //	}
            //}
            //bool allowPlant = getter == eater;
        }
Ejemplo n.º 3
0
        static void _DebugFoodSearchFromMouse_OnGUI()
        {
            IntVec3 a = Verse.UI.MouseCell();

            BestFoodSourceFromMouse = null;
            BestFoodSource          = null;

            // ------------------------------------------------------------------------------

            PawnA = null;
            PawnB = null;

            var pawnSelection = Find.Selector.SelectedObjects.Where(arg => arg is Pawn).Cast <Pawn>();

            PawnA = pawnSelection.FirstOrDefault();
            if (pawnSelection.Count() == 2)
            {
                PawnB = pawnSelection.ElementAt(1);
            }


            if (PawnB != null && PawnA != null && (PawnA.Faction != PawnB.Faction || RimWorld.FoodUtility.ShouldBeFedBySomeone(PawnA) || RimWorld.FoodUtility.ShouldBeFedBySomeone(PawnB)))
            {
                //TODO: watch out for compatibility
                if (PawnA.IsColonist)
                {
                    eater  = PawnB;
                    getter = PawnA;
                }
                else if (PawnB.IsColonist)
                {
                    eater  = PawnA;
                    getter = PawnB;
                }
                else
                {
                    eater = getter = PawnA;
                }
            }
            else
            {
                eater = getter = PawnA;
            }


            // ------------------------------------------------------------------------------

            if (eater == null)
            {
                return;
            }
            if (eater.Map != Find.CurrentMap)
            {
                return;
            }
            Text.Anchor = TextAnchor.MiddleCenter;
            Text.Font   = GameFont.Tiny;

            var policy = eater.GetPolicyAssignedTo();

            var thingAtCursorCell = Find.CurrentMap.thingGrid.ThingsAt(a).FirstOrDefault(delegate(Thing t)
            {
                var category = t.GetFoodCategory();
                if (category == FoodCategory.Null)
                {
                    return(false);
                }

                return(FoodUtils.IsValidFoodSourceForPawn(t, eater, getter, policy, false));
            });

            ThingDef dum2;
            // Generates cache
            var foundFood = RimWorld.FoodUtility.TryFindBestFoodSourceFor(getter, eater, true, out bestFoodSource, out dum2);

            if (!foundFood)
            {
                //goto cursorwidget;
                return;
            }

            // ------------------------------------------------------------------------------

            List <FoodSourceRating> foodsToDisplay;

            var selectedFoods = Find.Selector.SelectedObjects
                                .Where(arg => (arg is Thing) && (arg as Thing).DetermineFoodCategory() != FoodCategory.Null)
                                .Cast <Thing>().ToList();

            FoodSearchCache.PawnEntry pawnEntry;
            //IEnumerable<Thing> foodList =
            //TODO: no score shown with unrestricted policies
            if (getter.isWildAnimal() || policy.unrestricted || !FoodSearchCache.TryGetEntryForPawn(getter, eater, out pawnEntry, true))
            {
                return;
            }

            foodsToDisplay = pawnEntry.AllRankedFoods
                             .OrderBy(arg => (a - arg.FoodSource.Position).LengthManhattan).ToList()
                             .GetRange(0, Math.Min(300, pawnEntry.AllRankedFoods.Count));

            //bool advancedInfoForAll;

            //if (!selectedFoods.Any())
            //{
            //	selectedFoods.Add(bestFoodSource);
            //	selectedFoods.Add(foodList.AllRankedFoods.MinBy((arg) => (a - arg.FoodSource.Position).LengthHorizontal).FoodSource);
            //	advancedInfoForAll = false;
            //}
            //else
            //	advancedInfoForAll = true;

            bool advancedInfoForAll = ModCore.drawFoodSearchMode == ModCore.DrawFoodSearchMode.Advanced;

            // ----------------------- Recalculate food source rating distance factors ------------------------------

            FoodSourceRating bestScoreFromMouse = null;

            for (int i = 0; i < foodsToDisplay.Count; i++)
            {
                var current = foodsToDisplay[i];

                foodsToDisplay[i] = new FoodSourceRating(foodsToDisplay[i]);

                foodsToDisplay[i].SetComp("Distance", -(a - current.FoodSource.Position).LengthManhattan * policy.distanceFactor);
            }

            //bestScoreFromMouse = foodsToDisplay.MaxBy((arg) => arg.Score);

            bestScoreFromMouse      = foodsToDisplay.MaxBy((arg) => arg.ScoreForceSum);
            BestFoodSourceFromMouse = bestScoreFromMouse.FoodSource;

            // ----------------------- Food sources widgets ------------------------------

            foreach (var current in foodsToDisplay)
            {
                //float score = current.Score;

                Vector2 vector = current.FoodSource.DrawPos.MapToUIPosition();
                //Rect rect = new Rect(vector.x - 100f, vector.y - 100f, 200f, 200f);
                Rect rect = new Rect(vector.x, vector.y, 200f, 200f);

                if (getter.inventory == null || !getter.inventory.innerContainer.Contains(current.FoodSource))
                {
                    bool advancedInfo = (advancedInfoForAll);

                    Color widgetColor;
                    if (current == bestScoreFromMouse || current.FoodSource == BestFoodSource || current.FoodSource == thingAtCursorCell)
                    {
                        if (ModCore.drawFoodSearchMode == ModCore.DrawFoodSearchMode.AdvancedForBest)
                        {
                            advancedInfo = true;
                        }
                        if (current.FoodSource == thingAtCursorCell)
                        {
                            widgetColor = Color.green;
                        }
                        else
                        {
                            widgetColor = Resources.Color.Orange;
                        }
                    }
                    else
                    {
                        widgetColor = Color.white;
                    }

                    string text = current.ToWidgetString(advancedInfo, current.FoodSource.DetermineFoodCategory());

#if DEBUG
                    if (current.FoodSource is Pawn)
                    {
                        text += "\n" + "ratio1=" + FoodUtils.GetPreyRatio1(getter, current.FoodSource as Pawn);
                        text += "\n" + "ratio2=" + FoodUtils.GetPreyRatio2(getter, current.FoodSource as Pawn);
                    }
#endif

                    Text.Anchor = TextAnchor.UpperLeft;
                    {
                        var backup = GUI.color;
                        GUI.color = widgetColor;
                        Widgets.Label(rect, text);
                        GUI.color = backup;
                    }
                }
            }

            // ----------------------- Cursor widget -----------------------

            //TODO: cursor widget not drawn when no food found

            string pawninfo;
            pawninfo = string.Format("{0}", getter.Name.ToStringShort);
            if (getter != eater)
            {
                pawninfo += string.Format(" (gives to) {0}", eater.Name.ToStringShort);
            }

            //pawninfo += string.Format(" ---> {4} ({6:F0}){5}\nFood need: {1:F1} / {2:F1}\nPolicy: {3}",
            //						  eater.NameStringShort,
            //eater.needs.food.CurLevel,
            //eater.needs.food.MaxLevel,
            //policy != null ? policy.label : "(no policy)",
            //bestFoodSourceFromMouse != null ? bestFoodSourceFromMouse.Label : "(no reachable food)",
            //(bestFoodSourceFromMouse != null && getter.inventory != null && getter.inventory.innerContainer.Contains(bestFoodSourceFromMouse)) ? " (inventory)" : "",
            //bestScoreFromMouse.Score);


            {
                string score;
                string foodname;

                if (BestFoodSourceFromMouse != null)
                {
                    foodname = BestFoodSourceFromMouse.Label;
                    score    = bestScoreFromMouse.ScoreForceSum.ToString("F0");
                }
                else
                {
                    foodname = "(no reachable food)";
                    score    = "";
                }

                pawninfo += " ---> " + foodname + " (" + score + ")" + "\n";
                pawninfo += "Food need: " + eater.needs.food.CurLevel.ToString("F1") + " / " + eater.needs.food.MaxLevel.ToString("F1") + "\n";
                pawninfo += "Policy: " + (policy != null ? policy.label : "(no policy)") + "\n";
            }

            Text.Anchor = TextAnchor.UpperLeft;
            //TODO: spread or merge widgets +
            Widgets.Label(new Rect((a.ToUIPosition() + new Vector2(-100f, -80f)), new Vector2(200f, 200f)), pawninfo);
        }