public static float ApproxDaysUntilRot(List <ThingCount> potentiallyFood, int tile, WorldPath path = null, float nextTileCostLeft = 0f, int caravanTicksPerMove = 3300) { DaysUntilRotCalculator.tmpTicksToArrive.Clear(); if (path != null && path.Found) { CaravanArrivalTimeEstimator.EstimatedTicksToArriveToEvery(tile, path.LastNode, path, nextTileCostLeft, caravanTicksPerMove, Find.TickManager.TicksAbs, DaysUntilRotCalculator.tmpTicksToArrive); } DaysUntilRotCalculator.tmpNutritions.Clear(); for (int i = 0; i < potentiallyFood.Count; i++) { ThingCount thingCount = potentiallyFood[i]; if (thingCount.Count > 0 && thingCount.Thing.def.IsNutritionGivingIngestible) { CompRottable compRottable = thingCount.Thing.TryGetComp <CompRottable>(); float first; if (compRottable != null && compRottable.Active) { first = (float)DaysUntilRotCalculator.ApproxTicksUntilRot_AssumeTimePassesBy(compRottable, tile, DaysUntilRotCalculator.tmpTicksToArrive) / 60000f; } else { first = 600f; } float second = thingCount.Thing.GetStatValue(StatDefOf.Nutrition, true) * (float)thingCount.Count; DaysUntilRotCalculator.tmpNutritions.Add(new Pair <float, float>(first, second)); } } return(GenMath.WeightedMedian(DaysUntilRotCalculator.tmpNutritions, 600f, 0.5f)); }
public static int EstimatedTicksToArrive(Caravan caravan, bool allowCaching) { if (allowCaching && caravan == CaravanArrivalTimeEstimator.cachedForCaravan && caravan.pather.Destination == CaravanArrivalTimeEstimator.cachedForDest && Find.TickManager.TicksGame - CaravanArrivalTimeEstimator.cacheTicks < 100) { return(CaravanArrivalTimeEstimator.cachedResult); } int to; int result; if (!caravan.Spawned || !caravan.pather.Moving || caravan.pather.curPath == null) { to = -1; result = 0; } else { to = caravan.pather.Destination; result = CaravanArrivalTimeEstimator.EstimatedTicksToArrive(caravan.Tile, to, caravan.pather.curPath, caravan.pather.nextTileCostLeft, caravan.TicksPerMove, Find.TickManager.TicksAbs); } if (allowCaching) { CaravanArrivalTimeEstimator.cacheTicks = Find.TickManager.TicksGame; CaravanArrivalTimeEstimator.cachedForCaravan = caravan; CaravanArrivalTimeEstimator.cachedForDest = to; CaravanArrivalTimeEstimator.cachedResult = result; } return(result); }
private string GetTileTip(int tile, int pathIndex) { int num = paths[pathIndex].NodesReversed.IndexOf(tile); int num2 = ((num > 0) ? paths[pathIndex].NodesReversed[num - 1] : ((pathIndex >= paths.Count - 1 || paths[pathIndex + 1].NodesReversed.Count < 2) ? (-1) : paths[pathIndex + 1].NodesReversed[paths[pathIndex + 1].NodesReversed.Count - 2])); int num3 = cachedTicksToWaypoint[pathIndex] + CaravanArrivalTimeEstimator.EstimatedTicksToArrive(paths[pathIndex].FirstNode, tile, paths[pathIndex], 0f, CaravanTicksPerMove, GenTicks.TicksAbs + cachedTicksToWaypoint[pathIndex]); int num4 = GenTicks.TicksAbs + num3; StringBuilder stringBuilder = new StringBuilder(); if (num3 != 0) { stringBuilder.AppendLine("EstimatedTimeToTile".Translate(num3.ToStringTicksToDays("0.##"))); } stringBuilder.AppendLine("ForagedFoodAmount".Translate() + ": " + Find.WorldGrid[tile].biome.forageability.ToStringPercent()); stringBuilder.Append(VirtualPlantsUtility.GetVirtualPlantsStatusExplanationAt(tile, num4)); if (num2 != -1) { stringBuilder.AppendLine(); stringBuilder.AppendLine(); StringBuilder stringBuilder2 = new StringBuilder(); float num5 = WorldPathGrid.CalculatedMovementDifficultyAt(num2, perceivedStatic: false, num4, stringBuilder2); float roadMovementDifficultyMultiplier = Find.WorldGrid.GetRoadMovementDifficultyMultiplier(tile, num2, stringBuilder2); stringBuilder.Append("TileMovementDifficulty".Translate() + ":\n" + stringBuilder2.ToString().Indented(" ")); stringBuilder.AppendLine(); stringBuilder.Append(" = "); stringBuilder.Append((num5 * roadMovementDifficultyMultiplier).ToString("0.#")); } return(stringBuilder.ToString()); }
private void RecreatePaths() { ReleasePaths(); WorldPathFinder worldPathFinder = Find.WorldPathFinder; for (int i = 1; i < waypoints.Count; i++) { paths.Add(worldPathFinder.FindPath(waypoints[i - 1].Tile, waypoints[i].Tile, null)); } cachedTicksToWaypoint.Clear(); int num = 0; int caravanTicksPerMove = CaravanTicksPerMove; for (int j = 0; j < waypoints.Count; j++) { if (j == 0) { cachedTicksToWaypoint.Add(0); } else { num += CaravanArrivalTimeEstimator.EstimatedTicksToArrive(waypoints[j - 1].Tile, waypoints[j].Tile, paths[j - 1], 0f, caravanTicksPerMove, GenTicks.TicksAbs + num); cachedTicksToWaypoint.Add(num); } } }
public static int EstimatedTicksToArrive(int from, int to, Caravan caravan) { using (WorldPath worldPath = Find.WorldPathFinder.FindPath(from, to, caravan, null)) { if (worldPath == WorldPath.NotFound) { return(0); } return(CaravanArrivalTimeEstimator.EstimatedTicksToArrive(from, to, worldPath, 0f, CaravanTicksPerMoveUtility.GetTicksPerMove(caravan), Find.TickManager.TicksAbs)); } }
public static int EstimatedTicksToArrive(int from, int to, Caravan caravan) { int result; using (WorldPath worldPath = Find.WorldPathFinder.FindPath(from, to, caravan, null)) { if (!worldPath.Found) { result = 0; } else { result = CaravanArrivalTimeEstimator.EstimatedTicksToArrive(from, to, worldPath, 0f, (caravan == null) ? 3300 : caravan.TicksPerMove, Find.TickManager.TicksAbs); } } return(result); }
public override GizmoResult GizmoOnGUI(Vector2 topLeft, float maxWidth) { if (!caravan.Spawned) { return(new GizmoResult(GizmoState.Clear)); } Rect rect = new Rect(topLeft.x, topLeft.y, GetWidth(maxWidth), 75f); Widgets.DrawWindowBackground(rect); GUI.BeginGroup(rect); Rect rect2 = rect.AtZero(); int? ticksToArrive = (caravan.pather.Moving ? new int?(CaravanArrivalTimeEstimator.EstimatedTicksToArrive(caravan, allowCaching: true)) : null); StringBuilder stringBuilder = new StringBuilder(); CaravanUIUtility.DrawCaravanInfo(new CaravanUIUtility.CaravanInfo(tilesPerDay: TilesPerDayCalculator.ApproxTilesPerDay(caravan, stringBuilder), massUsage: caravan.MassUsage, massCapacity: caravan.MassCapacity, massCapacityExplanation: caravan.MassCapacityExplanation, tilesPerDayExplanation: stringBuilder.ToString(), daysWorthOfFood: caravan.DaysWorthOfFood, foragedFoodPerDay: caravan.forage.ForagedFoodPerDay, foragedFoodPerDayExplanation: caravan.forage.ForagedFoodPerDayExplanation, visibility: caravan.Visibility, visibilityExplanation: caravan.VisibilityExplanation), null, caravan.Tile, ticksToArrive, -9999f, rect2, lerpMassColor: true, null, multiline: true); GUI.EndGroup(); GenUI.AbsorbClicksInRect(rect); return(new GizmoResult(GizmoState.Clear)); }
public static int ApproxTicksUntilRot_AssumeTimePassesBy(CompRottable rot, int tile, List <Pair <int, int> > ticksToArrive = null) { float num = 0f; int num2 = Find.TickManager.TicksAbs; while (num < 1f && (float)num2 < (float)Find.TickManager.TicksAbs + 3.606E+07f) { int tile2 = (!ticksToArrive.NullOrEmpty <Pair <int, int> >()) ? CaravanArrivalTimeEstimator.TileIllBeInAt(num2, ticksToArrive, Find.TickManager.TicksAbs) : tile; int num3 = Mathf.FloorToInt((float)rot.ApproxTicksUntilRotWhenAtTempOfTile(tile2, num2) * (1f - num)); if (num3 <= 0) { break; } int num4 = Mathf.Min(num3, 26999); num += (float)num4 / (float)num3; num2 += num4; } return(num2 - Find.TickManager.TicksAbs); }
public override string GetInspectString() { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append(base.GetInspectString()); if (stringBuilder.Length != 0) { stringBuilder.AppendLine(); } int num = 0; int num2 = 0; int num3 = 0; int num4 = 0; int num5 = 0; for (int i = 0; i < pawns.Count; i++) { if (pawns[i].IsColonist) { num++; } else if (pawns[i].RaceProps.Animal) { num2++; } else if (pawns[i].IsPrisoner) { num3++; } if (pawns[i].Downed) { num4++; } if (pawns[i].InMentalState) { num5++; } } stringBuilder.Append("CaravanColonistsCount".Translate(num, (num != 1) ? Faction.OfPlayer.def.pawnsPlural : Faction.OfPlayer.def.pawnSingular)); if (num2 == 1) { stringBuilder.Append(", " + "CaravanAnimal".Translate()); } else if (num2 > 1) { stringBuilder.Append(", " + "CaravanAnimalsCount".Translate(num2)); } if (num3 == 1) { stringBuilder.Append(", " + "CaravanPrisoner".Translate()); } else if (num3 > 1) { stringBuilder.Append(", " + "CaravanPrisonersCount".Translate(num3)); } stringBuilder.AppendLine(); if (num5 > 0) { stringBuilder.Append("CaravanPawnsInMentalState".Translate(num5)); } if (num4 > 0) { if (num5 > 0) { stringBuilder.Append(", "); } stringBuilder.Append("CaravanPawnsDowned".Translate(num4)); } if (num5 > 0 || num4 > 0) { stringBuilder.AppendLine(); } if (pather.Moving) { if (pather.ArrivalAction != null) { stringBuilder.Append(pather.ArrivalAction.ReportString); } else { stringBuilder.Append("CaravanTraveling".Translate()); } } else { SettlementBase settlementBase = CaravanVisitUtility.SettlementVisitedNow(this); if (settlementBase != null) { stringBuilder.Append("CaravanVisiting".Translate(settlementBase.Label)); } else { stringBuilder.Append("CaravanWaiting".Translate()); } } if (pather.Moving) { float num6 = (float)CaravanArrivalTimeEstimator.EstimatedTicksToArrive(this, allowCaching: true) / 60000f; stringBuilder.AppendLine(); stringBuilder.Append("CaravanEstimatedTimeToDestination".Translate(num6.ToString("0.#"))); } if (AllOwnersDowned) { stringBuilder.AppendLine(); stringBuilder.Append("AllCaravanMembersDowned".Translate()); } else if (AllOwnersHaveMentalBreak) { stringBuilder.AppendLine(); stringBuilder.Append("AllCaravanMembersMentalBreak".Translate()); } else if (ImmobilizedByMass) { stringBuilder.AppendLine(); stringBuilder.Append("CaravanImmobilizedByMass".Translate()); } if (needs.AnyPawnOutOfFood(out string malnutritionHediff)) { stringBuilder.AppendLine(); stringBuilder.Append("CaravanOutOfFood".Translate()); if (!malnutritionHediff.NullOrEmpty()) { stringBuilder.Append(" "); stringBuilder.Append(malnutritionHediff); stringBuilder.Append("."); } } if (!pather.MovingNow) { int usedBedCount = beds.GetUsedBedCount(); stringBuilder.AppendLine(); stringBuilder.Append(CaravanBedUtility.AppendUsingBedsLabel("CaravanResting".Translate(), usedBedCount)); } else { string inspectStringLine = carryTracker.GetInspectStringLine(); if (!inspectStringLine.NullOrEmpty()) { stringBuilder.AppendLine(); stringBuilder.Append(inspectStringLine); } string inBedForMedicalReasonsInspectStringLine = beds.GetInBedForMedicalReasonsInspectStringLine(); if (!inBedForMedicalReasonsInspectStringLine.NullOrEmpty()) { stringBuilder.AppendLine(); stringBuilder.Append(inBedForMedicalReasonsInspectStringLine); } } return(stringBuilder.ToString()); }
private static float ApproxDaysWorthOfFood(List <Pawn> pawns, List <ThingDefCount> extraFood, int tile, IgnorePawnsInventoryMode ignoreInventory, Faction faction, WorldPath path = null, float nextTileCostLeft = 0f, int caravanTicksPerMove = 3300, bool assumeCaravanMoving = true) { if (!AnyFoodEatingPawn(pawns)) { return(600f); } if (!assumeCaravanMoving) { path = null; } tmpFood.Clear(); if (extraFood != null) { int i = 0; for (int count = extraFood.Count; i < count; i++) { ThingDefCount item = extraFood[i]; if (item.ThingDef.IsNutritionGivingIngestible && item.Count > 0) { tmpFood.Add(item); } } } int j = 0; for (int count2 = pawns.Count; j < count2; j++) { Pawn pawn = pawns[j]; if (InventoryCalculatorsUtility.ShouldIgnoreInventoryOf(pawn, ignoreInventory)) { continue; } ThingOwner <Thing> innerContainer = pawn.inventory.innerContainer; int k = 0; for (int count3 = innerContainer.Count; k < count3; k++) { Thing thing = innerContainer[k]; if (thing.def.IsNutritionGivingIngestible) { tmpFood.Add(new ThingDefCount(thing.def, thing.stackCount)); } } } tmpFood2.Clear(); tmpFood2.AddRange(tmpFood); tmpFood.Clear(); int l = 0; for (int count4 = tmpFood2.Count; l < count4; l++) { ThingDefCount item2 = tmpFood2[l]; bool flag = false; int m = 0; for (int count5 = tmpFood.Count; m < count5; m++) { ThingDefCount thingDefCount = tmpFood[m]; if (thingDefCount.ThingDef == item2.ThingDef) { tmpFood[m] = thingDefCount.WithCount(thingDefCount.Count + item2.Count); flag = true; break; } } if (!flag) { tmpFood.Add(item2); } } tmpDaysWorthOfFoodForPawn.Clear(); int n = 0; for (int count6 = pawns.Count; n < count6; n++) { tmpDaysWorthOfFoodForPawn.Add(0f); } int ticksAbs = Find.TickManager.TicksAbs; tmpTicksToArrive.Clear(); if (path != null && path.Found) { CaravanArrivalTimeEstimator.EstimatedTicksToArriveToEvery(tile, path.LastNode, path, nextTileCostLeft, caravanTicksPerMove, ticksAbs, tmpTicksToArrive); } cachedNutritionBetweenHungryAndFed.Clear(); cachedTicksUntilHungryWhenFed.Clear(); cachedMaxFoodLevel.Clear(); int num = 0; for (int count7 = pawns.Count; num < count7; num++) { Pawn pawn2 = pawns[num]; if (pawn2.RaceProps.EatsFood) { Need_Food food = pawn2.needs.food; cachedNutritionBetweenHungryAndFed.Add(food.NutritionBetweenHungryAndFed); cachedTicksUntilHungryWhenFed.Add(food.TicksUntilHungryWhenFedIgnoringMalnutrition); cachedMaxFoodLevel.Add(food.MaxLevel); } else { cachedNutritionBetweenHungryAndFed.Add(0f); cachedTicksUntilHungryWhenFed.Add(0); cachedMaxFoodLevel.Add(0f); } } float num2 = 0f; float num3 = 0f; float num4 = 0f; bool flag2 = false; WorldGrid worldGrid = Find.WorldGrid; bool flag3; do { flag3 = false; int num5 = ticksAbs + (int)(num3 * 60000f); int num6 = ((path != null) ? CaravanArrivalTimeEstimator.TileIllBeInAt(num5, tmpTicksToArrive, ticksAbs) : tile); bool flag4 = CaravanNightRestUtility.WouldBeRestingAt(num6, num5); float progressPerTick = ForagedFoodPerDayCalculator.GetProgressPerTick(assumeCaravanMoving && !flag4, flag4); float num7 = 1f / progressPerTick; bool flag5 = VirtualPlantsUtility.EnvironmentAllowsEatingVirtualPlantsAt(num6, num5); float num8 = num3 - num2; if (num8 > 0f) { num4 += num8 * 60000f; if (num4 >= num7) { BiomeDef biome = worldGrid[num6].biome; int num9 = Mathf.RoundToInt(ForagedFoodPerDayCalculator.GetForagedFoodCountPerInterval(pawns, biome, faction)); ThingDef foragedFood = biome.foragedFood; while (num4 >= num7) { num4 -= num7; if (num9 <= 0) { continue; } bool flag6 = false; for (int num10 = tmpFood.Count - 1; num10 >= 0; num10--) { ThingDefCount thingDefCount2 = tmpFood[num10]; if (thingDefCount2.ThingDef == foragedFood) { tmpFood[num10] = thingDefCount2.WithCount(thingDefCount2.Count + num9); flag6 = true; break; } } if (!flag6) { tmpFood.Add(new ThingDefCount(foragedFood, num9)); } } } } num2 = num3; int num11 = 0; for (int count8 = pawns.Count; num11 < count8; num11++) { Pawn pawn3 = pawns[num11]; if (!pawn3.RaceProps.EatsFood) { continue; } if (flag5 && VirtualPlantsUtility.CanEverEatVirtualPlants(pawn3)) { if (tmpDaysWorthOfFoodForPawn[num11] < num3) { tmpDaysWorthOfFoodForPawn[num11] = num3; } else { tmpDaysWorthOfFoodForPawn[num11] += 0.45f; } flag3 = true; } else { float num12 = cachedNutritionBetweenHungryAndFed[num11]; int num13 = cachedTicksUntilHungryWhenFed[num11]; do { int num14 = BestEverEdibleFoodIndexFor(pawn3, tmpFood); if (num14 < 0) { if (tmpDaysWorthOfFoodForPawn[num11] < num3) { flag2 = true; } break; } ThingDefCount thingDefCount3 = tmpFood[num14]; float num15 = Mathf.Min(thingDefCount3.ThingDef.ingestible.CachedNutrition, num12); float num16 = num15 / num12 * (float)num13 / 60000f; int num17 = Mathf.Min(Mathf.CeilToInt(Mathf.Min(0.2f, cachedMaxFoodLevel[num11]) / num15), thingDefCount3.Count); tmpDaysWorthOfFoodForPawn[num11] += num16 * (float)num17; tmpFood[num14] = thingDefCount3.WithCount(thingDefCount3.Count - num17); flag3 = true; }while (tmpDaysWorthOfFoodForPawn[num11] < num3); } if (flag2) { break; } num3 = Mathf.Max(num3, tmpDaysWorthOfFoodForPawn[num11]); } }while (!(!flag3 || flag2) && !(num3 > 601f)); float num18 = 600f; int num19 = 0; for (int count9 = pawns.Count; num19 < count9; num19++) { if (pawns[num19].RaceProps.EatsFood) { num18 = Mathf.Min(num18, tmpDaysWorthOfFoodForPawn[num19]); } } return(num18); }
public static void EstimatedTicksToArriveToEvery(int from, int to, WorldPath path, float nextTileCostLeft, int caravanTicksPerMove, int curTicksAbs, List <Pair <int, int> > outTicksToArrive) { outTicksToArrive.Clear(); outTicksToArrive.Add(new Pair <int, int>(from, 0)); if (from == to) { outTicksToArrive.Add(new Pair <int, int>(to, 0)); return; } int num = 0; int num2 = from; int num3 = 0; int num4 = Mathf.CeilToInt(20000f) - 1; int num5 = 60000 - num4; int num6 = 0; int num7 = 0; int num9; if (CaravanNightRestUtility.WouldBeRestingAt(from, (long)curTicksAbs)) { if (Caravan_PathFollower.IsValidFinalPushDestination(to) && (path.Peek(0) == to || (nextTileCostLeft <= 0f && path.NodesLeftCount >= 2 && path.Peek(1) == to))) { float costToMove = CaravanArrivalTimeEstimator.GetCostToMove(nextTileCostLeft, path.Peek(0) == to, curTicksAbs, num, caravanTicksPerMove, from, to); int num8 = Mathf.CeilToInt(costToMove / 1f); if (num8 <= 10000) { num += num8; outTicksToArrive.Add(new Pair <int, int>(to, num)); return; } } num += CaravanNightRestUtility.LeftRestTicksAt(from, (long)curTicksAbs); num9 = num5; } else { num9 = CaravanNightRestUtility.LeftNonRestTicksAt(from, (long)curTicksAbs); } for (;;) { num7++; if (num7 >= 10000) { break; } if (num6 <= 0) { if (num2 == to) { goto Block_10; } bool firstInPath = num3 == 0; int num10 = num2; num2 = path.Peek(num3); num3++; outTicksToArrive.Add(new Pair <int, int>(num10, num)); float costToMove2 = CaravanArrivalTimeEstimator.GetCostToMove(nextTileCostLeft, firstInPath, curTicksAbs, num, caravanTicksPerMove, num10, num2); num6 = Mathf.CeilToInt(costToMove2 / 1f); } if (num9 < num6) { num += num9; num6 -= num9; if (num2 == to && num6 <= 10000 && Caravan_PathFollower.IsValidFinalPushDestination(to)) { goto Block_14; } num += num4; num9 = num5; } else { num += num6; num9 -= num6; num6 = 0; } } Log.ErrorOnce("Could not calculate estimated ticks to arrive. Too many iterations.", 1837451324, false); outTicksToArrive.Add(new Pair <int, int>(to, num)); return; Block_10: outTicksToArrive.Add(new Pair <int, int>(to, num)); return; Block_14: num += num6; outTicksToArrive.Add(new Pair <int, int>(to, num)); }
public static int EstimatedTicksToArrive(int from, int to, WorldPath path, float nextTileCostLeft, int caravanTicksPerMove, int curTicksAbs) { CaravanArrivalTimeEstimator.tmpTicksToArrive.Clear(); CaravanArrivalTimeEstimator.EstimatedTicksToArriveToEvery(from, to, path, nextTileCostLeft, caravanTicksPerMove, curTicksAbs, CaravanArrivalTimeEstimator.tmpTicksToArrive); return(CaravanArrivalTimeEstimator.EstimatedTicksToArrive(to, CaravanArrivalTimeEstimator.tmpTicksToArrive)); }
private static float ApproxDaysWorthOfFood(List <Pawn> pawns, List <ThingDefCount> extraFood, int tile, IgnorePawnsInventoryMode ignoreInventory, Faction faction, WorldPath path = null, float nextTileCostLeft = 0f, int caravanTicksPerMove = 3500, bool assumeCaravanMoving = true) { float result; if (!DaysWorthOfFoodCalculator.AnyFoodEatingPawn(pawns)) { result = 600f; } else { if (!assumeCaravanMoving) { path = null; } DaysWorthOfFoodCalculator.tmpFood.Clear(); if (extraFood != null) { int i = 0; int count = extraFood.Count; while (i < count) { ThingDefCount item = extraFood[i]; if (item.ThingDef.IsNutritionGivingIngestible && item.Count > 0) { DaysWorthOfFoodCalculator.tmpFood.Add(item); } i++; } } int j = 0; int count2 = pawns.Count; while (j < count2) { Pawn pawn = pawns[j]; if (!InventoryCalculatorsUtility.ShouldIgnoreInventoryOf(pawn, ignoreInventory)) { ThingOwner <Thing> innerContainer = pawn.inventory.innerContainer; int k = 0; int count3 = innerContainer.Count; while (k < count3) { Thing thing = innerContainer[k]; if (thing.def.IsNutritionGivingIngestible) { DaysWorthOfFoodCalculator.tmpFood.Add(new ThingDefCount(thing.def, thing.stackCount)); } k++; } } j++; } DaysWorthOfFoodCalculator.tmpFood2.Clear(); DaysWorthOfFoodCalculator.tmpFood2.AddRange(DaysWorthOfFoodCalculator.tmpFood); DaysWorthOfFoodCalculator.tmpFood.Clear(); int l = 0; int count4 = DaysWorthOfFoodCalculator.tmpFood2.Count; while (l < count4) { ThingDefCount item2 = DaysWorthOfFoodCalculator.tmpFood2[l]; bool flag = false; int m = 0; int count5 = DaysWorthOfFoodCalculator.tmpFood.Count; while (m < count5) { ThingDefCount thingDefCount = DaysWorthOfFoodCalculator.tmpFood[m]; if (thingDefCount.ThingDef == item2.ThingDef) { DaysWorthOfFoodCalculator.tmpFood[m] = thingDefCount.WithCount(thingDefCount.Count + item2.Count); flag = true; break; } m++; } if (!flag) { DaysWorthOfFoodCalculator.tmpFood.Add(item2); } l++; } DaysWorthOfFoodCalculator.tmpDaysWorthOfFoodForPawn.Clear(); int n = 0; int count6 = pawns.Count; while (n < count6) { DaysWorthOfFoodCalculator.tmpDaysWorthOfFoodForPawn.Add(0f); n++; } int ticksAbs = Find.TickManager.TicksAbs; DaysWorthOfFoodCalculator.tmpTicksToArrive.Clear(); if (path != null && path.Found) { CaravanArrivalTimeEstimator.EstimatedTicksToArriveToEvery(tile, path.LastNode, path, nextTileCostLeft, caravanTicksPerMove, ticksAbs, DaysWorthOfFoodCalculator.tmpTicksToArrive); } DaysWorthOfFoodCalculator.cachedNutritionBetweenHungryAndFed.Clear(); DaysWorthOfFoodCalculator.cachedTicksUntilHungryWhenFed.Clear(); DaysWorthOfFoodCalculator.cachedMaxFoodLevel.Clear(); int num = 0; int count7 = pawns.Count; while (num < count7) { Pawn pawn2 = pawns[num]; Need_Food food = pawn2.needs.food; DaysWorthOfFoodCalculator.cachedNutritionBetweenHungryAndFed.Add(food.NutritionBetweenHungryAndFed); DaysWorthOfFoodCalculator.cachedTicksUntilHungryWhenFed.Add(food.TicksUntilHungryWhenFed); DaysWorthOfFoodCalculator.cachedMaxFoodLevel.Add(food.MaxLevel); num++; } float num2 = 0f; float num3 = 0f; float num4 = 0f; bool flag2 = false; WorldGrid worldGrid = Find.WorldGrid; bool flag3; do { flag3 = false; int num5 = ticksAbs + (int)(num3 * 60000f); int num6 = (path == null) ? tile : CaravanArrivalTimeEstimator.TileIllBeInAt(num5, DaysWorthOfFoodCalculator.tmpTicksToArrive, ticksAbs); bool flag4 = CaravanRestUtility.WouldBeRestingAt(num6, (long)num5); float progressPerTick = ForagedFoodPerDayCalculator.GetProgressPerTick(assumeCaravanMoving && !flag4, flag4, null); float num7 = 1f / progressPerTick; bool flag5 = VirtualPlantsUtility.EnvironmentAllowsEatingVirtualPlantsAt(num6, num5); float num8 = num3 - num2; if (num8 > 0f) { num4 += num8 * 60000f; if (num4 >= num7) { BiomeDef biome = worldGrid[num6].biome; int num9 = Mathf.RoundToInt(ForagedFoodPerDayCalculator.GetForagedFoodCountPerInterval(pawns, biome, faction, null)); ThingDef foragedFood = biome.foragedFood; while (num4 >= num7) { num4 -= num7; if (num9 > 0) { bool flag6 = false; for (int num10 = DaysWorthOfFoodCalculator.tmpFood.Count - 1; num10 >= 0; num10--) { ThingDefCount thingDefCount2 = DaysWorthOfFoodCalculator.tmpFood[num10]; if (thingDefCount2.ThingDef == foragedFood) { DaysWorthOfFoodCalculator.tmpFood[num10] = thingDefCount2.WithCount(thingDefCount2.Count + num9); flag6 = true; break; } } if (!flag6) { DaysWorthOfFoodCalculator.tmpFood.Add(new ThingDefCount(foragedFood, num9)); } } } } } num2 = num3; int num11 = 0; int count8 = pawns.Count; while (num11 < count8) { Pawn pawn3 = pawns[num11]; if (pawn3.RaceProps.EatsFood) { if (flag5 && VirtualPlantsUtility.CanEverEatVirtualPlants(pawn3)) { if (DaysWorthOfFoodCalculator.tmpDaysWorthOfFoodForPawn[num11] < num3) { DaysWorthOfFoodCalculator.tmpDaysWorthOfFoodForPawn[num11] = num3; } else { List <float> list; int index; (list = DaysWorthOfFoodCalculator.tmpDaysWorthOfFoodForPawn)[index = num11] = list[index] + 0.45f; } flag3 = true; } else { float num12 = DaysWorthOfFoodCalculator.cachedNutritionBetweenHungryAndFed[num11]; int num13 = DaysWorthOfFoodCalculator.cachedTicksUntilHungryWhenFed[num11]; do { int num14 = DaysWorthOfFoodCalculator.BestEverEdibleFoodIndexFor(pawn3, DaysWorthOfFoodCalculator.tmpFood); if (num14 < 0) { goto Block_27; } ThingDefCount thingDefCount3 = DaysWorthOfFoodCalculator.tmpFood[num14]; float num15 = Mathf.Min(thingDefCount3.ThingDef.ingestible.CachedNutrition, num12); float num16 = num15 / num12 * (float)num13 / 60000f; int num17 = Mathf.Min(Mathf.CeilToInt(Mathf.Min(0.2f, DaysWorthOfFoodCalculator.cachedMaxFoodLevel[num11]) / num15), thingDefCount3.Count); List <float> list; int index2; (list = DaysWorthOfFoodCalculator.tmpDaysWorthOfFoodForPawn)[index2 = num11] = list[index2] + num16 * (float)num17; DaysWorthOfFoodCalculator.tmpFood[num14] = thingDefCount3.WithCount(thingDefCount3.Count - num17); flag3 = true; }while (DaysWorthOfFoodCalculator.tmpDaysWorthOfFoodForPawn[num11] < num3); goto IL_633; Block_27: if (DaysWorthOfFoodCalculator.tmpDaysWorthOfFoodForPawn[num11] < num3) { flag2 = true; } } IL_633: if (flag2) { break; } num3 = Mathf.Max(num3, DaysWorthOfFoodCalculator.tmpDaysWorthOfFoodForPawn[num11]); } num11++; } }while (flag3 && !flag2 && num3 <= 601f); float num18 = 600f; int num19 = 0; int count9 = pawns.Count; while (num19 < count9) { if (pawns[num19].RaceProps.EatsFood) { num18 = Mathf.Min(num18, DaysWorthOfFoodCalculator.tmpDaysWorthOfFoodForPawn[num19]); } num19++; } result = num18; } return(result); }
public override string GetInspectString() { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append(base.GetInspectString()); if (stringBuilder.Length != 0) { stringBuilder.AppendLine(); } if (this.Resting) { stringBuilder.Append("CaravanResting".Translate()); } else if (this.AnyPawnHasExtremeMentalBreak) { stringBuilder.Append("CaravanMemberMentalBreak".Translate(new object[] { this.FirstPawnWithExtremeMentalBreak.LabelShort })); } else if (this.AllOwnersDowned) { stringBuilder.Append("AllCaravanMembersDowned".Translate()); } else if (this.AllOwnersHaveMentalBreak) { stringBuilder.Append("AllCaravanMembersMentalBreak".Translate()); } else if (this.pather.Moving) { if (this.pather.arrivalAction != null) { stringBuilder.Append(this.pather.arrivalAction.ReportString); } else { stringBuilder.Append("CaravanTraveling".Translate()); } } else { Settlement settlement = CaravanVisitUtility.SettlementVisitedNow(this); if (settlement != null) { stringBuilder.Append("CaravanVisiting".Translate(new object[] { settlement.Label })); } else { stringBuilder.Append("CaravanWaiting".Translate()); } } if (this.pather.Moving) { float num = (float)CaravanArrivalTimeEstimator.EstimatedTicksToArrive(this, true) / 60000f; stringBuilder.AppendLine(); stringBuilder.Append("CaravanEstimatedTimeToDestination".Translate(new object[] { num.ToString("0.#") })); } if (this.ImmobilizedByMass) { stringBuilder.AppendLine(); stringBuilder.Append("CaravanImmobilizedByMass".Translate()); } string text; if (CaravanPawnsNeedsUtility.AnyPawnOutOfFood(this, out text)) { stringBuilder.AppendLine(); stringBuilder.Append("CaravanOutOfFood".Translate()); if (!text.NullOrEmpty()) { stringBuilder.Append(" "); stringBuilder.Append(text); stringBuilder.Append("."); } } else if (this.DaysWorthOfFood.First < 1000f) { Pair <float, float> daysWorthOfFood = this.DaysWorthOfFood; stringBuilder.AppendLine(); if (daysWorthOfFood.Second < 1000f) { stringBuilder.Append("CaravanDaysOfFoodRot".Translate(new object[] { daysWorthOfFood.First.ToString("0.#"), daysWorthOfFood.Second.ToString("0.#") })); } else { stringBuilder.Append("CaravanDaysOfFood".Translate(new object[] { daysWorthOfFood.First.ToString("0.#") })); } } stringBuilder.AppendLine(); stringBuilder.AppendLine(string.Concat(new string[] { "CaravanBaseMovementTime".Translate(), ": ", ((float)this.TicksPerMove / 2500f).ToString("0.##"), " ", "CaravanHoursPerTile".Translate() })); stringBuilder.AppendLine("CurrentTileMovementTime".Translate() + ": " + Caravan_PathFollower.CostToDisplay(this, base.Tile, this.pather.nextTile, -1f).ToStringTicksToPeriod(true, false, true)); stringBuilder.Append("StealthFactor".Translate() + ": " + CaravanIncidentUtility.CalculateCaravanStealthFactor(this.PawnsListForReading.Count).ToString("F1")); return(stringBuilder.ToString()); }
public override GizmoResult GizmoOnGUI(Vector2 topLeft, float maxWidth) { if (!this.caravan.Spawned) { return(new GizmoResult(GizmoState.Clear)); } Rect rect = new Rect(topLeft.x, topLeft.y, this.GetWidth(maxWidth), 75f); Widgets.DrawWindowBackground(rect); GUI.BeginGroup(rect); Rect rect2 = rect.AtZero(); int? ticksToArrive = (!this.caravan.pather.Moving) ? null : new int?(CaravanArrivalTimeEstimator.EstimatedTicksToArrive(this.caravan, true)); StringBuilder stringBuilder = new StringBuilder(); float tilesPerDay = TilesPerDayCalculator.ApproxTilesPerDay(this.caravan, stringBuilder); CaravanUIUtility.DrawCaravanInfo(new CaravanUIUtility.CaravanInfo(this.caravan.MassUsage, this.caravan.MassCapacity, this.caravan.MassCapacityExplanation, tilesPerDay, stringBuilder.ToString(), this.caravan.DaysWorthOfFood, this.caravan.forage.ForagedFoodPerDay, this.caravan.forage.ForagedFoodPerDayExplanation, this.caravan.Visibility, this.caravan.VisibilityExplanation, -1f, -1f, null), null, this.caravan.Tile, ticksToArrive, -9999f, rect2, true, null, true); GUI.EndGroup(); GenUI.AbsorbClicksInRect(rect); return(new GizmoResult(GizmoState.Clear)); }