// RimWorld.Planet.CaravanInventoryUtility public static bool _TryGetBestFood(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 = FoodUtility.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); }
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); }