Exemplo n.º 1
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.VisibleMap)
            {
                return;
            }
            Text.Anchor = TextAnchor.MiddleCenter;
            Text.Font   = GameFont.Tiny;

            var policy = eater.GetPolicyAssignedTo();

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

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

            ThingDef dum2;
            // Generates cache
            var foundFood = 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=" + FoodUtility.GetPreyRatio1(getter, current.FoodSource as Pawn);
                        text += "\n" + "ratio2=" + FoodUtility.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.NameStringShort);
            if (getter != eater)
            {
                pawninfo += string.Format(" (gives to) {0}", eater.NameStringShort);
            }

            //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);
        }
Exemplo 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;
        }
        // RimWorld.FoodUtility
        private static bool _TryFindBestFoodSourceFor(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)
        {
#if DEBUG
            Log.Message("_TryFindBestFoodSourceFor() getter=" + getter + " eater=" + eater + " desperate=" + desperate + " canUseInventory=" + canUseInventory + " allowForbidden=" + allowForbidden);
#endif
            Policy policy;

            //taming ? TODO: check for bug free
            if (forcedPolicy != null)
            {
                policy = forcedPolicy;
            }
            else
            {
                policy = eater.GetPolicyAssignedTo(getter);
            }

            if (getter.isWildAnimal() || getter.isInsectFaction() || policy.unrestricted || getter.InMentalState || Config.ControlDisabledForPawn(eater))
            {
                return(Original.FoodUtility.TryFindBestFoodSourceFor(getter, eater, desperate, out foodSource, out foodDef, canRefillDispenser, canUseInventory, allowForbidden, allowCorpse));
            }

            List <FoodSourceRating> FoodListForPawn;

            FoodSearchCache.PawnEntry pawnEntry;

            if (!FoodSearchCache.TryGetEntryForPawn(getter, eater, out pawnEntry, allowForbidden))
            {
                bool foundFood = 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)
            {
                foodDef = null;
                return(false);
            }

            foodDef = RimWorld.FoodUtility.GetFinalIngestibleDef(foodSource);
            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;
        }