public static float ApproxDaysUntilRotLeftAfterTradeableTransfer(List <Thing> allCurrentThings, List <Tradeable> tradeables, int tile, IgnorePawnsInventoryMode ignoreInventory) { DaysUntilRotCalculator.tmpThingCountsFromTradeables.Clear(); TransferableUtility.SimulateTradeableTransfer(allCurrentThings, tradeables, DaysUntilRotCalculator.tmpThingCountsFromTradeables); DaysUntilRotCalculator.tmpThingCounts.Clear(); for (int i = DaysUntilRotCalculator.tmpThingCountsFromTradeables.Count - 1; i >= 0; i--) { if (DaysUntilRotCalculator.tmpThingCountsFromTradeables[i].Count > 0) { Pawn pawn = DaysUntilRotCalculator.tmpThingCountsFromTradeables[i].Thing as Pawn; if (pawn != null) { if (!InventoryCalculatorsUtility.ShouldIgnoreInventoryOf(pawn, ignoreInventory)) { ThingOwner <Thing> innerContainer = pawn.inventory.innerContainer; for (int j = 0; j < innerContainer.Count; j++) { DaysUntilRotCalculator.tmpThingCounts.Add(new ThingCount(innerContainer[j], innerContainer[j].stackCount)); } } } else { DaysUntilRotCalculator.tmpThingCounts.Add(DaysUntilRotCalculator.tmpThingCountsFromTradeables[i]); } } } DaysUntilRotCalculator.tmpThingCountsFromTradeables.Clear(); float result = DaysUntilRotCalculator.ApproxDaysUntilRot(DaysUntilRotCalculator.tmpThingCounts, tile, null, 0f, 3300); DaysUntilRotCalculator.tmpThingCounts.Clear(); return(result); }
public static float ApproxDaysUntilRotLeftAfterTransfer(List <TransferableOneWay> transferables, int assumingTile, IgnorePawnsInventoryMode ignoreInventory) { DaysUntilRotCalculator.tmpThings.Clear(); for (int i = 0; i < transferables.Count; i++) { TransferableOneWay transferableOneWay = transferables[i]; if (transferableOneWay.HasAnyThing) { if (transferableOneWay.AnyThing is Pawn) { for (int j = transferableOneWay.things.Count - 1; j >= transferableOneWay.CountToTransfer; j--) { Pawn pawn = (Pawn)transferableOneWay.things[j]; if (!InventoryCalculatorsUtility.ShouldIgnoreInventoryOf(pawn, ignoreInventory)) { ThingOwner <Thing> innerContainer = pawn.inventory.innerContainer; for (int k = 0; k < innerContainer.Count; k++) { DaysUntilRotCalculator.tmpThings.Add(innerContainer[k]); } } } } else if (transferableOneWay.MaxCount - transferableOneWay.CountToTransfer > 0) { DaysUntilRotCalculator.tmpThings.AddRange(transferableOneWay.things); } } } float result = DaysUntilRotCalculator.ApproxDaysUntilRot(DaysUntilRotCalculator.tmpThings, assumingTile); DaysUntilRotCalculator.tmpThings.Clear(); return(result); }
public static float ApproxDaysUntilRotLeftAfterTradeableTransfer(List <Thing> allCurrentThings, List <Tradeable> tradeables, int tile, IgnorePawnsInventoryMode ignoreInventory) { tmpThingCountsFromTradeables.Clear(); TransferableUtility.SimulateTradeableTransfer(allCurrentThings, tradeables, tmpThingCountsFromTradeables); tmpThingCounts.Clear(); for (int num = tmpThingCountsFromTradeables.Count - 1; num >= 0; num--) { if (tmpThingCountsFromTradeables[num].Count > 0) { Pawn pawn = tmpThingCountsFromTradeables[num].Thing as Pawn; if (pawn != null) { if (!InventoryCalculatorsUtility.ShouldIgnoreInventoryOf(pawn, ignoreInventory)) { ThingOwner <Thing> innerContainer = pawn.inventory.innerContainer; for (int i = 0; i < innerContainer.Count; i++) { tmpThingCounts.Add(new ThingCount(innerContainer[i], innerContainer[i].stackCount)); } } } else { tmpThingCounts.Add(tmpThingCountsFromTradeables[num]); } } } tmpThingCountsFromTradeables.Clear(); float result = ApproxDaysUntilRot(tmpThingCounts, tile); tmpThingCounts.Clear(); return(result); }
public static float ApproxDaysUntilRotLeftAfterTradeableTransfer(List <Thing> allCurrentThings, List <Tradeable> tradeables, int assumingTile, IgnorePawnsInventoryMode ignoreInventory) { TransferableUtility.SimulateTradeableTransfer(allCurrentThings, tradeables, DaysUntilRotCalculator.tmpThingStackParts); DaysUntilRotCalculator.tmpThings.Clear(); for (int num = DaysUntilRotCalculator.tmpThingStackParts.Count - 1; num >= 0; num--) { if (DaysUntilRotCalculator.tmpThingStackParts[num].Count > 0) { Pawn pawn = DaysUntilRotCalculator.tmpThingStackParts[num].Thing as Pawn; if (pawn != null) { if (!InventoryCalculatorsUtility.ShouldIgnoreInventoryOf(pawn, ignoreInventory)) { ThingOwner <Thing> innerContainer = pawn.inventory.innerContainer; for (int i = 0; i < innerContainer.Count; i++) { DaysUntilRotCalculator.tmpThings.Add(innerContainer[i]); } } } else { DaysUntilRotCalculator.tmpThings.Add(DaysUntilRotCalculator.tmpThingStackParts[num].Thing); } } } DaysUntilRotCalculator.tmpThingStackParts.Clear(); float result = DaysUntilRotCalculator.ApproxDaysUntilRot(DaysUntilRotCalculator.tmpThings, assumingTile); DaysUntilRotCalculator.tmpThings.Clear(); return(result); }
public static float ApproxDaysUntilRotLeftAfterTransfer(List <TransferableOneWay> transferables, int tile, IgnorePawnsInventoryMode ignoreInventory, WorldPath path = null, float nextTileCostLeft = 0f, int caravanTicksPerMove = 3300) { tmpThingCounts.Clear(); for (int i = 0; i < transferables.Count; i++) { TransferableOneWay transferableOneWay = transferables[i]; if (!transferableOneWay.HasAnyThing) { continue; } if (transferableOneWay.AnyThing is Pawn) { for (int num = transferableOneWay.things.Count - 1; num >= transferableOneWay.CountToTransfer; num--) { Pawn pawn = (Pawn)transferableOneWay.things[num]; if (!InventoryCalculatorsUtility.ShouldIgnoreInventoryOf(pawn, ignoreInventory)) { ThingOwner <Thing> innerContainer = pawn.inventory.innerContainer; for (int j = 0; j < innerContainer.Count; j++) { tmpThingCounts.Add(new ThingCount(innerContainer[j], innerContainer[j].stackCount)); } } } } else if (transferableOneWay.MaxCount - transferableOneWay.CountToTransfer > 0) { thingsInReverse.Clear(); thingsInReverse.AddRange(transferableOneWay.things); thingsInReverse.Reverse(); TransferableUtility.TransferNoSplit(thingsInReverse, transferableOneWay.MaxCount - transferableOneWay.CountToTransfer, delegate(Thing thing, int count) { tmpThingCounts.Add(new ThingCount(thing, count)); }, removeIfTakingEntireThing: false, errorIfNotEnoughThings: false); } } thingsInReverse.Clear(); float result = ApproxDaysUntilRot(tmpThingCounts, tile, path, nextTileCostLeft, caravanTicksPerMove); tmpThingCounts.Clear(); return(result); }
public static float ApproxDaysUntilRotLeftAfterTransfer(List <TransferableOneWay> transferables, int tile, IgnorePawnsInventoryMode ignoreInventory, WorldPath path = null, float nextTileCostLeft = 0f, int caravanTicksPerMove = 3300) { DaysUntilRotCalculator.tmpThingCounts.Clear(); for (int i = 0; i < transferables.Count; i++) { TransferableOneWay transferableOneWay = transferables[i]; if (transferableOneWay.HasAnyThing) { if (transferableOneWay.AnyThing is Pawn) { for (int j = transferableOneWay.things.Count - 1; j >= transferableOneWay.CountToTransfer; j--) { Pawn pawn = (Pawn)transferableOneWay.things[j]; if (!InventoryCalculatorsUtility.ShouldIgnoreInventoryOf(pawn, ignoreInventory)) { ThingOwner <Thing> innerContainer = pawn.inventory.innerContainer; for (int k = 0; k < innerContainer.Count; k++) { DaysUntilRotCalculator.tmpThingCounts.Add(new ThingCount(innerContainer[k], innerContainer[k].stackCount)); } } } } else if (transferableOneWay.MaxCount - transferableOneWay.CountToTransfer > 0) { DaysUntilRotCalculator.thingsInReverse.Clear(); DaysUntilRotCalculator.thingsInReverse.AddRange(transferableOneWay.things); DaysUntilRotCalculator.thingsInReverse.Reverse(); TransferableUtility.TransferNoSplit(DaysUntilRotCalculator.thingsInReverse, transferableOneWay.MaxCount - transferableOneWay.CountToTransfer, delegate(Thing thing, int count) { DaysUntilRotCalculator.tmpThingCounts.Add(new ThingCount(thing, count)); }, false, false); } } } DaysUntilRotCalculator.thingsInReverse.Clear(); float result = DaysUntilRotCalculator.ApproxDaysUntilRot(DaysUntilRotCalculator.tmpThingCounts, tile, path, nextTileCostLeft, caravanTicksPerMove); DaysUntilRotCalculator.tmpThingCounts.Clear(); return(result); }
private float GetMass(Thing thing) { if (thing == null) { return(0f); } float num = thing.GetStatValue(StatDefOf.Mass, true); if (thing is Pawn pawn) { if (InventoryCalculatorsUtility.ShouldIgnoreInventoryOf(pawn, ignorePawnInventoryMass)) { num -= MassUtility.InventoryMass(pawn); } } else if (ignoreSpawnedCorpseGearAndInventoryMass) { if (thing is Corpse corpse && corpse.Spawned) { num -= MassUtility.GearAndInventoryMass(corpse.InnerPawn); } } return(num); }
private static float ApproxDaysWorthOfFood(List <Pawn> pawns, List <ThingCount> extraFood, bool assumeCanEatLocalPlants, IgnorePawnsInventoryMode ignoreInventory) { if (!DaysWorthOfFoodCalculator.AnyNonLocalPlantsEatingPawn(pawns, assumeCanEatLocalPlants)) { return(1000f); } DaysWorthOfFoodCalculator.tmpFood.Clear(); if (extraFood != null) { for (int i = 0; i < extraFood.Count; i++) { if (extraFood[i].ThingDef.IsNutritionGivingIngestible && extraFood[i].Count > 0) { DaysWorthOfFoodCalculator.tmpFood.Add(extraFood[i]); } } } for (int j = 0; j < pawns.Count; j++) { if (!InventoryCalculatorsUtility.ShouldIgnoreInventoryOf(pawns[j], ignoreInventory)) { ThingOwner <Thing> innerContainer = pawns[j].inventory.innerContainer; for (int k = 0; k < innerContainer.Count; k++) { if (innerContainer[k].def.IsNutritionGivingIngestible) { DaysWorthOfFoodCalculator.tmpFood.Add(new ThingCount(innerContainer[k].def, innerContainer[k].stackCount)); } } } } if (!DaysWorthOfFoodCalculator.tmpFood.Any()) { return(0f); } DaysWorthOfFoodCalculator.tmpDaysWorthOfFoodPerPawn.Clear(); DaysWorthOfFoodCalculator.tmpAnyFoodLeftIngestibleByPawn.Clear(); for (int l = 0; l < pawns.Count; l++) { DaysWorthOfFoodCalculator.tmpDaysWorthOfFoodPerPawn.Add(0f); DaysWorthOfFoodCalculator.tmpAnyFoodLeftIngestibleByPawn.Add(true); } float num = 0f; while (true) { bool flag = false; for (int m = 0; m < pawns.Count; m++) { Pawn pawn = pawns[m]; if (DaysWorthOfFoodCalculator.tmpAnyFoodLeftIngestibleByPawn[m] && pawn.RaceProps.EatsFood && (!assumeCanEatLocalPlants || !VirtualPlantsUtility.CanEverEatVirtualPlants(pawn))) { while (true) { int num2 = DaysWorthOfFoodCalculator.BestEverEdibleFoodIndexFor(pawns[m], DaysWorthOfFoodCalculator.tmpFood); if (num2 < 0) { DaysWorthOfFoodCalculator.tmpAnyFoodLeftIngestibleByPawn[m] = false; break; } float num3 = Mathf.Min(DaysWorthOfFoodCalculator.tmpFood[num2].ThingDef.ingestible.nutrition, pawn.needs.food.NutritionBetweenHungryAndFed); float num4 = (float)(num3 / pawn.needs.food.NutritionBetweenHungryAndFed * (float)pawn.needs.food.TicksUntilHungryWhenFed / 60000.0); List <float> list; int index; (list = DaysWorthOfFoodCalculator.tmpDaysWorthOfFoodPerPawn)[index = m] = list[index] + num4; DaysWorthOfFoodCalculator.tmpFood[num2] = DaysWorthOfFoodCalculator.tmpFood[num2].WithCount(DaysWorthOfFoodCalculator.tmpFood[num2].Count - 1); flag = true; if (!(DaysWorthOfFoodCalculator.tmpDaysWorthOfFoodPerPawn[m] < num)) { break; } } num = Mathf.Max(num, DaysWorthOfFoodCalculator.tmpDaysWorthOfFoodPerPawn[m]); } } if (!flag) { break; } } float num5 = 1000f; for (int n = 0; n < pawns.Count; n++) { if (pawns[n].RaceProps.EatsFood && (!assumeCanEatLocalPlants || !VirtualPlantsUtility.CanEverEatVirtualPlants(pawns[n]))) { num5 = Mathf.Min(num5, DaysWorthOfFoodCalculator.tmpDaysWorthOfFoodPerPawn[n]); } } return(num5); }
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); }
private static float ApproxDaysWorthOfWater(List <Pawn> pawns, List <ThingCount> extraWater, IgnorePawnsInventoryMode ignoreInventory) { if (!DaysWorthOfWaterCalculator.AnyNonTerrainDrinkingPawn(pawns)) { return(1000f); } List <ThingCount> tmpWater = new List <ThingCount>(); tmpWater.Clear(); if (extraWater != null) { for (int i = 0; i < extraWater.Count; i++) { bool canGetWater = false; for (int j = 0; j < extraWater[i].ThingDef.comps.Count; j++) { var compprop = extraWater[i].ThingDef.comps[j] as CompProperties_WaterSource; if (compprop != null && compprop.sourceType == CompProperties_WaterSource.SourceType.Item && compprop.waterAmount > 0.0f) { canGetWater = true; break; } } if (canGetWater && extraWater[i].Count > 0) { tmpWater.Add(extraWater[i]); } } } for (int j = 0; j < pawns.Count; j++) { if (!InventoryCalculatorsUtility.ShouldIgnoreInventoryOf(pawns[j], ignoreInventory)) { ThingOwner <Thing> innerContainer = pawns[j].inventory.innerContainer; for (int k = 0; k < innerContainer.Count; k++) { if (innerContainer[k].CanGetWater()) { tmpWater.Add(new ThingCount(innerContainer[k].def, innerContainer[k].stackCount)); } } } } if (!tmpWater.Any <ThingCount>()) { return(0f); } List <float> tmpDaysWorthOfFoodPerPawn = new List <float>(); List <bool> tmpAnyFoodLeftIngestibleByPawn = new List <bool>(); tmpDaysWorthOfFoodPerPawn.Clear(); tmpAnyFoodLeftIngestibleByPawn.Clear(); for (int l = 0; l < pawns.Count; l++) { tmpDaysWorthOfFoodPerPawn.Add(0f); tmpAnyFoodLeftIngestibleByPawn.Add(true); } float num = 0f; bool flag; do { flag = false; for (int m = 0; m < pawns.Count; m++) { Pawn pawn = pawns[m]; if (tmpAnyFoodLeftIngestibleByPawn[m]) { do { int num2 = DaysWorthOfWaterCalculator.BestEverGetWaterIndexFor(pawns[m], tmpWater); if (num2 < 0) { tmpAnyFoodLeftIngestibleByPawn[m] = false; break; } CompProperties_WaterSource compprop = null; for (int x = 0; x < tmpWater[num2].ThingDef.comps.Count; x++) { compprop = tmpWater[num2].ThingDef.comps[x] as CompProperties_WaterSource; if (compprop != null && compprop.sourceType == CompProperties_WaterSource.SourceType.Item) { break; } } if (compprop == null) { tmpAnyFoodLeftIngestibleByPawn[m] = false; break; } Need_Water need_water = pawn.needs.water(); if (need_water == null) { tmpAnyFoodLeftIngestibleByPawn[m] = false; break; } float num3 = Mathf.Min(compprop.waterAmount, need_water.WaterAmountBetweenThirstyAndHealthy); float num4 = num3 / need_water.WaterAmountBetweenThirstyAndHealthy * (float)need_water.TicksUntilThirstyWhenHealthy / 60000f; tmpDaysWorthOfFoodPerPawn[m] = tmpDaysWorthOfFoodPerPawn[m] + num4; tmpWater[num2] = tmpWater[num2].WithCount(tmpWater[num2].Count - 1); flag = true; }while (tmpDaysWorthOfFoodPerPawn[m] < num); num = Mathf.Max(num, tmpDaysWorthOfFoodPerPawn[m]); } } }while (flag); float num6 = 1000f; for (int n = 0; n < pawns.Count; n++) { num6 = Mathf.Min(num6, tmpDaysWorthOfFoodPerPawn[n]); } return(num6); }
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); }
private void DrawMass(Rect rect, TransferableOneWay trad, float availableMass) { if (!trad.HasAnyThing) { return; } Thing anyThing = trad.AnyThing; Pawn pawn = anyThing as Pawn; if (pawn != null && !includePawnsMassInMassUsage && !MassUtility.CanEverCarryAnything(pawn)) { return; } Widgets.DrawHighlightIfMouseover(rect); if (pawn == null || includePawnsMassInMassUsage) { float mass = GetMass(anyThing); if (Mouse.IsOver(rect)) { if (pawn != null) { float gearMass = 0f; float invMass = 0f; gearMass = MassUtility.GearMass(pawn); if (!InventoryCalculatorsUtility.ShouldIgnoreInventoryOf(pawn, ignorePawnInventoryMass)) { invMass = MassUtility.InventoryMass(pawn); } TooltipHandler.TipRegion(rect, () => GetPawnMassTip(trad, 0f, mass - gearMass - invMass, gearMass, invMass), trad.GetHashCode() * 59); } else { TooltipHandler.TipRegion(rect, "ItemWeightTip".Translate()); } } if (mass > availableMass) { GUI.color = ColoredText.RedReadable; } else { GUI.color = TransferableOneWayWidget.ItemMassColor; } Widgets.Label(rect, mass.ToStringMass()); } else { float cap = MassUtility.Capacity(pawn, null); float gearMass = MassUtility.GearMass(pawn); float invMass = InventoryCalculatorsUtility.ShouldIgnoreInventoryOf(pawn, ignorePawnInventoryMass) ? 0f : MassUtility.InventoryMass(pawn); float num = cap - gearMass - invMass; if (num > 0f) { GUI.color = Color.green; } else if (num < 0f) { GUI.color = ColoredText.RedReadable; } else { GUI.color = Color.gray; } Widgets.Label(rect, num.ToStringMassOffset()); if (Mouse.IsOver(rect)) { TooltipHandler.TipRegion(rect, () => GetPawnMassTip(trad, cap, 0f, gearMass, invMass), trad.GetHashCode() * 59); } } GUI.color = Color.white; }
private static float ApproxDaysWorthOfWater( List <Pawn> pawns, List <ThingDefCount> extraWater, IgnorePawnsInventoryMode ignoreInventory) { if (!AnyNonTerrainDrinkingPawn(pawns)) { return(1000f); } var tmpWater = new List <ThingDefCount>(); tmpWater.Clear(); if (extraWater != null) { foreach (var thingDefCount in extraWater) { var canGetWater = false; foreach (var compProperties in thingDefCount.ThingDef.comps) { if (!(compProperties is CompProperties_WaterSource compprop) || compprop.sourceType != CompProperties_WaterSource.SourceType.Item || !(compprop.waterAmount > 0.0f)) { continue; } canGetWater = true; break; } if (canGetWater && thingDefCount.Count > 0) { tmpWater.Add(thingDefCount); } } } foreach (var pawn in pawns) { if (InventoryCalculatorsUtility.ShouldIgnoreInventoryOf(pawn, ignoreInventory)) { continue; } var innerContainer = pawn.inventory.innerContainer; foreach (var thing in innerContainer) { if (thing.CanGetWater()) { tmpWater.Add(new ThingDefCount(thing.def, thing.stackCount)); } } } if (!tmpWater.Any()) { return(0f); } var tmpDaysWorthOfFoodPerPawn = new List <float>(); var tmpAnyFoodLeftIngestibleByPawn = new List <bool>(); tmpDaysWorthOfFoodPerPawn.Clear(); tmpAnyFoodLeftIngestibleByPawn.Clear(); for (var l = 0; l < pawns.Count; l++) { tmpDaysWorthOfFoodPerPawn.Add(0f); tmpAnyFoodLeftIngestibleByPawn.Add(true); } var num = 0f; bool flag; do { flag = false; for (var m = 0; m < pawns.Count; m++) { var pawn = pawns[m]; if (!tmpAnyFoodLeftIngestibleByPawn[m]) { continue; } do { var num2 = BestEverGetWaterIndexFor(tmpWater); if (num2 < 0) { tmpAnyFoodLeftIngestibleByPawn[m] = false; break; } CompProperties_WaterSource compprop = null; foreach (var compProperties in tmpWater[num2].ThingDef.comps) { compprop = compProperties as CompProperties_WaterSource; if (compprop != null && compprop.sourceType == CompProperties_WaterSource.SourceType.Item) { break; } } if (compprop == null) { tmpAnyFoodLeftIngestibleByPawn[m] = false; break; } var need_water = pawn.needs.Water(); if (need_water == null) { tmpAnyFoodLeftIngestibleByPawn[m] = false; break; } var num3 = Mathf.Min(compprop.waterAmount, need_water.WaterAmountBetweenThirstyAndHealthy); var num4 = num3 / need_water.WaterAmountBetweenThirstyAndHealthy * need_water.TicksUntilThirstyWhenHealthy / 60000f; tmpDaysWorthOfFoodPerPawn[m] = tmpDaysWorthOfFoodPerPawn[m] + num4; tmpWater[num2] = tmpWater[num2].WithCount(tmpWater[num2].Count - 1); flag = true; }while (tmpDaysWorthOfFoodPerPawn[m] < num); num = Mathf.Max(num, tmpDaysWorthOfFoodPerPawn[m]); } }while (flag); var num6 = 1000f; for (var n = 0; n < pawns.Count; n++) { num6 = Mathf.Min(num6, tmpDaysWorthOfFoodPerPawn[n]); } return(num6); }