public static int LeftNonRestTicksAt(int tile, long ticksAbs)
        {
            if (CaravanNightRestUtility.WouldBeRestingAt(tile, ticksAbs))
            {
                return(0);
            }
            float num = GenDate.HourFloat(ticksAbs, Find.WorldGrid.LongLatOf(tile).x);

            return(Mathf.CeilToInt((22f - num) * 2500f));
        }
 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));
     }
     else
     {
         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, curTicksAbs))
         {
             if (Caravan_PathFollower.IsValidFinalPushDestination(to) && (path.Peek(0) == to || (nextTileCostLeft <= 0f && path.NodesLeftCount >= 2 && path.Peek(1) == to)))
             {
                 float costToMove = 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, curTicksAbs);
             num9 = num5;
         }
         else
         {
             num9 = CaravanNightRestUtility.LeftNonRestTicksAt(from, curTicksAbs);
         }
         while (true)
         {
             num7++;
             if (num7 >= 10000)
             {
                 Log.ErrorOnce("Could not calculate estimated ticks to arrive. Too many iterations.", 1837451324);
                 outTicksToArrive.Add(new Pair <int, int>(to, num));
                 return;
             }
             if (num6 <= 0)
             {
                 if (num2 == to)
                 {
                     outTicksToArrive.Add(new Pair <int, int>(to, num));
                     return;
                 }
                 bool firstInPath = num3 == 0;
                 int  num10       = num2;
                 num2 = path.Peek(num3);
                 num3++;
                 outTicksToArrive.Add(new Pair <int, int>(num10, num));
                 float costToMove2 = 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))
                 {
                     break;
                 }
                 num += num4;
                 num9 = num5;
             }
             else
             {
                 num  += num6;
                 num9 -= num6;
                 num6  = 0;
             }
         }
         num += num6;
         outTicksToArrive.Add(new Pair <int, int>(to, num));
     }
 }
示例#3
0
        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 int LeftNonRestTicksAt(int tile)
 {
     return(CaravanNightRestUtility.LeftNonRestTicksAt(tile, (long)GenTicks.TicksAbs));
 }
 public static bool RestingNowAt(int tile)
 {
     return(CaravanNightRestUtility.WouldBeRestingAt(tile, (long)GenTicks.TicksAbs));
 }