private void DrawRequirementRow(ThingDefCount thingCount, Rect listHolder, int listPos, bool canDrawToolTips)
        {
            float yPosition      = listPos * listElementRectHeight;
            Rect  highlightRect  = new Rect(0f, yPosition, listHolder.width, listElementRectHeight);
            bool  rowShouldBeRed = Find.CurrentMap.GetCountOnMapDifference(thingCount) > 0;

            // Do tool tips and background.
            if (listPos % 2 == 0 && rowShouldBeRed)
            {
                GUI.DrawTexture(highlightRect, redAltTexture);
            }
            else if (listPos % 2 == 0)
            {
                Widgets.DrawAltRect(highlightRect);
            }
            if (canDrawToolTips)
            {
                TooltipHandler.TipRegion(highlightRect, new TipSignal(GetReqRowTooltip(thingCount)));
            }
            // Draw thingdef icon
            Rect mainElementsRect = highlightRect.WidthContractedBy(listElementsMargin);
            Rect iconRect         = new Rect(mainElementsRect.x, yPosition, listElementRectHeight, listElementRectHeight);

            Widgets.ThingIcon(iconRect, thingCount.ThingDef);
            // Do text labels
            Rect labelsRect = new Rect(listElementRectHeight, yPosition, listHolder.width - listElementRectHeight, listElementRectHeight).WidthContractedBy(2 * listElementsMargin);

            if (rowShouldBeRed)
            {
                GUI.color = Color.red;
            }
            DoTextLabel(labelsRect, thingCount.ThingDef.LabelCap);
            DoNumberLabel(labelsRect, thingCount);
            GUI.color = Color.white;
        }
        private float GetFillFraction(ThingDefCount tc)
        {
            float needed    = tc.Count;
            float available = Find.CurrentMap.resourceCounter.GetCount(tc.ThingDef);

            return(Mathf.Clamp(available / needed, 0, 1));
        }
        private void DoRowTooltip(Rect tooltipRegion, ThingDefCount count, int difference)
        {
            int    present  = -difference + count.Count;
            string tipLabel = (modInstance.CountInStorage) ? "ReqRowTip_Storage".Translate(count.Count, present) : "ReqRowTip_All".Translate(count.Count, present);

            TooltipHandler.TipRegion(tooltipRegion, new TipSignal(tipLabel));
        }
        private void DrawToolTip()
        {
            List <ThingDefCount> trackedRequirements = Tracker.TotalCosts;
            float maxCountWidth = (trackedRequirements.Count > 0) ? Text.CalcSize(trackedRequirements[0].Count.ToString()).x : 0f;
            float workLeftWidth = Text.CalcSize(Tracker.WorkLeft.ToString()).x;
            float toolTipWidth  = Mathf.Max(maxCountWidth, workLeftWidth);

            toolTipWidth += (listElementsMargin * 2 + xOffsetFromContainer * 2) + listElementsHeight;
            float toolTipHeight = (trackedRequirements.Count + 1) * listElementsHeight;

            toolTipHeight += listElementsMargin * 2;
            Rect tooltipRect = new Rect(0f, 0f, toolTipWidth, toolTipHeight);

            PositionTipRect(ref tooltipRect);
            if (modInstance.ClampTipToScreen)
            {
                tooltipRect = tooltipRect.ClampRectInRect(new Rect(0, 0, UI.screenWidth, UI.screenHeight).ContractedBy(modInstance.TooltipClampMargin));
            }
            Rect innerTipRect = tooltipRect.ContractedBy(listElementsMargin).WidthContractedBy(xOffsetFromContainer);
            int  indexOffset  = 0;

            if (Find.Selector.NumSelected > 0)
            {
                DrawTrackingModeIndicator(innerTipRect, indexOffset);
                indexOffset = 1;
            }
            for (int i = 0; i < trackedRequirements.Count; i++)
            {
                ThingDefCount count = trackedRequirements[i];
                DrawRequirementRow(count, innerTipRect, i + indexOffset);
            }
            DrawWorkLeftRow(innerTipRect, trackedRequirements.Count + indexOffset);
        }
 public List <ThingDefCount> GetRequirementsTotals(TotalsSortModes modeToSortCountsBy = TotalsSortModes.Absolute, bool ascending = false)
 {
     if (!cachedTotalsAreUpdated)
     {
         List <ThingDefCount> protoRequirementsTotals = new List <ThingDefCount>();
         foreach (IConstructible tracked in trackedConstructibles)
         {
             foreach (ThingDefCount requirements in tracked.GetMaterialsNeededSafely())
             {
                 int thingCountWithSameThingDefIndex = protoRequirementsTotals.FindIndex(x => x.ThingDef == requirements.ThingDef);
                 if (thingCountWithSameThingDefIndex == -1)
                 {
                     protoRequirementsTotals.Add(requirements);
                 }
                 else
                 {
                     ThingDefCount tcWithSameThingDef = protoRequirementsTotals[thingCountWithSameThingDefIndex];
                     protoRequirementsTotals[thingCountWithSameThingDefIndex] = BlueprintReportUtility.AddThingCounts(tcWithSameThingDef, requirements);
                 }
             }
         }
         cachedRequirementsTotals = protoRequirementsTotals;
         cachedTotalsAreUpdated   = true;
     }
     SortTotalsIfNecessary(modeToSortCountsBy, ascending);
     return(cachedRequirementsTotals);
 }
        private string GetReqRowTooltip(ThingDefCount rowTC)
        {
            // First line
            string tipString = "ReqRowTipLine1".Translate(new object[] {
                rowTC.Count,
                rowTC.ThingDef.label
            });
            // Second line
            int amountPresent;
            int difference = Find.CurrentMap.GetCountOnMapDifference(rowTC, out amountPresent);

            if (difference < 0)
            {
                tipString += "ReqRowTipLine2Excess".Translate(new object[] {
                    -difference,
                    rowTC.ThingDef.label,
                    amountPresent
                });
            }
            else if (difference > 0)
            {
                tipString += "ReqRowTipLine2Lack".Translate(new object[] {
                    difference,
                    rowTC.ThingDef.label,
                    amountPresent
                });
            }
            return(tipString);
        }
 // Takes two ThingCounts and returns a new one with the counts added
 public static ThingDefCount AddThingCounts(ThingDefCount tc1, ThingDefCount tc2)
 {
     if (tc1.ThingDef != tc2.ThingDef)
     {
         Log.Warning("Added two ThingCounts of different ThingDefs. New ThingCount will have ThingDef of first ThingCount.");
     }
     return(new ThingDefCount(tc1.ThingDef, tc1.Count + tc2.Count));
 }
 // Get difference between count and the number present on map
 public static int GetCountOnMapDifference(this Map map, ThingDefCount count)
 {
     if (count.ThingDef.IsBlueprint)
     {
         return(0);
     }
     return(count.Count - map.GetCountAll(count.ThingDef));
 }
 public static int GetCountInStorageDifference(this Map map, ThingDefCount count)
 {
     if (count.ThingDef.IsBlueprint)
     {
         return(0);
     }
     return(count.Count - map.resourceCounter.GetCount(count.ThingDef));
 }
 public static ThingDefCount AddThingDefCounts(ThingDefCount lhs, ThingDefCount rhs)
 {
     if (lhs.ThingDef != rhs.ThingDef)
     {
         Log.Warning("Adding ThingDefCounts with different ThingDefs - New ThingDefCount will have ThingDef of first ThingDefCount");
     }
     return(new ThingDefCount(lhs.ThingDef, lhs.Count + rhs.Count));
 }
 // Same as above, but can pass amount present on map through out paramater.
 public static int GetCountOnMapDifference(this Map map, ThingDefCount count, out int numOnMap)
 {
     if (count.ThingDef.IsBlueprint)
     {
         numOnMap = count.Count;
         return(0);
     }
     numOnMap = map.GetCountAll(count.ThingDef);
     return(count.Count - numOnMap);
 }
Пример #12
0
        private void DoNumberLabel(Rect rowRect, ThingDefCount tc)
        {
            Rect textRect = new Rect(rowRect.x + rowRect.width - largestNumberWidth, rowRect.y, largestNumberWidth, rowRect.height);

            switch (currentSortMode)
            {
            case TotalsSortModes.Absolute:
                Widgets.Label(textRect, tc.Count.ToString());
                break;

            case TotalsSortModes.Difference:
                string strToDisplay = Find.CurrentMap.GetCountOnMapDifference(tc).ToStringWithSign();
                Widgets.Label(textRect, strToDisplay);
                break;
            }
        }
        public override Job JobOnThing(Pawn pawn, Thing t, bool forced = false)
        {
            if (t is ThingWithComps thing)
            {
                if (!pawn.Dead && !pawn.Downed && !pawn.IsBurning() && !thing.Destroyed && !thing.IsBurning() && pawn.CanReserveAndReach(thing, PathEndMode.InteractionCell, Danger.Deadly))
                {
                    CompUpgrade comp = null;
                    foreach (var c in thing.AllComps.OfType <CompUpgrade>())
                    {
                        if (c.beginUpgrade)
                        {
                            comp = c;
                            break;
                        }
                    }
                    if (comp == null)
                    {
                        return(null);
                    }

                    ThingDefCount needThingCount = comp.TryGetOneMissingMaterial();

                    if (!comp.PawnMeetsSkillRequirement(pawn))
                    {
                        JobFailReason.Is("ConstructionSkillTooLow");
                        return(null);
                    }
                    if (needThingCount.Count > 0)
                    {
                        Thing foundRes = GenClosest.ClosestThingReachable(pawn.Position, pawn.Map, ThingRequest.ForDef(needThingCount.ThingDef), PathEndMode.ClosestTouch, TraverseParms.For(pawn, Danger.Deadly), 9999f, (Thing r) => { return(r.def == needThingCount.ThingDef && !r.IsForbidden(pawn) && pawn.CanReserve(r)); });
                        if (foundRes == null)
                        {
                            JobFailReason.Is("Upgrade_missingMaterial");
                            return(null);
                        }
                    }
                    return(new Job(PESDefOf.PES_Job_InstallUpgrade, t));
                }
            }
            return(null);
        }
        private void DrawRequirementRow(ThingDefCount count, Rect toolTipRect, int posInList)
        {
            Rect rowRect  = new Rect(toolTipRect.x, toolTipRect.y + posInList * listElementsHeight, toolTipRect.width, listElementsHeight);
            Rect iconRect = new Rect(rowRect.x, rowRect.y, listElementsHeight, listElementsHeight).ContractedBy(1.5f);

            Widgets.ThingIcon(iconRect, count.ThingDef);
            Rect labelRect = new Rect(rowRect.x + listElementsHeight, rowRect.y, rowRect.width - listElementsHeight, rowRect.height);

            Text.Anchor = TextAnchor.MiddleLeft;
            int difference = (modInstance.CountInStorage) ? Find.CurrentMap.GetCountInStorageDifference(count) : Find.CurrentMap.GetCountOnMapDifference(count, modInstance.CountForbidden);

            if (difference > 0)
            {
                GUI.color = Color.red;
            }
            Widgets.Label(labelRect, count.Count.ToString());
            GUI.color   = Color.white;
            Text.Anchor = TextAnchor.UpperLeft;
            if (modInstance.ShowRowToolTips)
            {
                DoRowTooltip(rowRect, count, difference);
            }
        }
Пример #15
0
        private static bool Prefix(Pawn_InventoryTracker __instance, ref ThingCount __result)
        {
            if (__instance.innerContainer.Count == 0)
            {
                __result = default;
                return(false);
            }

            tmpDrugsToKeep.Clear();

            if (__instance.pawn.drugs?.CurrentPolicy != null)
            {
                var currentPolicy = __instance.pawn.drugs.CurrentPolicy;
                for (var i = 0; i < currentPolicy.Count; i++)
                {
                    if (currentPolicy[i].takeToInventory > 0)
                    {
                        tmpDrugsToKeep.Add(new ThingDefCount(currentPolicy[i].drug, currentPolicy[i].takeToInventory));
                    }
                }
            }

            Thing bestInstrument = null;

            if (!__instance.pawn.NonHumanlikeOrWildMan() && !__instance.pawn.WorkTagIsDisabled(WorkTags.Artistic))
            {
                var artSkill = __instance.pawn.skills.GetSkill(SkillDefOf.Artistic).levelInt;

                IEnumerable <Thing> heldInstruments = __instance.innerContainer
                                                      .Where(PerformanceManager.IsInstrument)
                                                      .Where(x => !x.TryGetComp <CompMusicalInstrument>().Props.isBuilding)
                                                      .OrderByDescending(x => x.TryGetComp <CompMusicalInstrument>().WeightedSuitability(artSkill));

                if (heldInstruments.Any())
                {
                    bestInstrument = heldInstruments.FirstOrDefault();
                }
            }

            if (tmpDrugsToKeep.Any() || bestInstrument != null)
            {
                foreach (var thing in __instance.innerContainer)
                {
                    if (thing.def.IsDrug)
                    {
                        var num = -1;

                        for (var k = 0; k < tmpDrugsToKeep.Count; k++)
                        {
                            if (thing.def != tmpDrugsToKeep[k].ThingDef)
                            {
                                continue;
                            }

                            num = k;
                            break;
                        }

                        if (num < 0)
                        {
                            __result = new ThingCount(thing,
                                                      thing.stackCount);
                            return(false);
                        }

                        if (thing.stackCount > tmpDrugsToKeep[num].Count)
                        {
                            __result = new ThingCount(thing,
                                                      thing.stackCount - tmpDrugsToKeep[num].Count);
                            return(false);
                        }

                        tmpDrugsToKeep[num] = new ThingDefCount(tmpDrugsToKeep[num].ThingDef,
                                                                tmpDrugsToKeep[num].Count - thing.stackCount);
                    }
                    else if (PerformanceManager.IsInstrument(thing))
                    {
                        if (bestInstrument == null)
                        {
                            __result = new ThingCount(thing,
                                                      thing.stackCount);
                            return(false);
                        }

                        if (bestInstrument.GetHashCode() == thing.GetHashCode())
                        {
                            continue;
                        }

                        __result = new ThingCount(thing,
                                                  thing.stackCount);
                        return(false);
                    }
                    else
                    {
                        __result = new ThingCount(thing,
                                                  thing.stackCount);
                        return(false);
                    }
                }

                __result = default;
                return(false);
            }

            __result = new ThingCount(__instance.innerContainer[0], __instance.innerContainer[0].stackCount);
            return(false);
        }
Пример #16
0
        protected override IEnumerable <Toil> MakeNewToils()
        {
            CompUpgrade comp = FindOneComp();

            if (comp == null)
            {
                EndJobWith(JobCondition.Incompletable);
                yield break;
            }
            AddFailCondition(() => comp == null || !comp.parent.Spawned || !comp.beginUpgrade);
            this.FailOnDestroyedNullOrForbidden(TargetIndex.A);

            Toil gotoBuilding = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell);
            Toil findMaterial = new Toil
            {
                initAction = delegate()
                {
                    ThingDefCount thingDefCount = comp.TryGetOneMissingMaterial();
                    job.count = thingDefCount.Count;
                    if (thingDefCount.Count > 0)
                    {
                        Thing foundRes = GenClosest.ClosestThingReachable(pawn.Position, pawn.Map, ThingRequest.ForDef(thingDefCount.ThingDef), PathEndMode.ClosestTouch, TraverseParms.For(pawn, Danger.Deadly), 9999f, (Thing r) => { return(r.def == thingDefCount.ThingDef && !r.IsForbidden(pawn) && pawn.CanReserve(r)); });
                        if (foundRes == null)
                        {
                            EndJobWith(JobCondition.Incompletable);
                        }
                        else
                        {
                            job.SetTarget(TargetIndex.B, foundRes);
                        }
                    }
                    else
                    {
                        JumpToToil(gotoBuilding);
                    }
                }
            };

            //Haul things to building
            yield return(findMaterial);

            yield return(Toils_Reserve.Reserve(TargetIndex.B, 1, job.count));

            yield return(Toils_Goto.GotoCell(TargetIndex.B, PathEndMode.Touch).FailOnDestroyedNullOrForbidden(TargetIndex.B));

            yield return(Toils_Haul.StartCarryThing(TargetIndex.B));

            yield return(Toils_Goto.GotoCell(TargetIndex.A, PathEndMode.InteractionCell));

            yield return(new Toil
            {
                initAction = delegate()
                {
                    var tracker = pawn.carryTracker;
                    if (tracker.CarriedThing != null)
                    {
                        tracker.innerContainer.TryTransferToContainer(tracker.CarriedThing, comp.GetDirectlyHeldThings(), tracker.CarriedThing.stackCount, true);
                        pawn.Map.reservationManager.ReleaseAllForTarget(TargetThingB);
                        job.SetTarget(TargetIndex.B, null);
                        JumpToToil(findMaterial);
                    }
                }
            });

            //Do upgrade
            yield return(gotoBuilding);

            yield return(new Toil
            {
                tickAction = delegate()
                {
                    Pawn actor = GetActor();
                    comp.Work(actor, actor.GetStatValue(StatDefOf.ConstructionSpeed));
                    if (comp.complete)
                    {
                        EndJobWith(JobCondition.Succeeded);
                    }
                },
                defaultCompleteMode = ToilCompleteMode.Never
            }.WithEffect(EffecterDefOf.ConstructMetal, TargetIndex.A).WithProgressBar(TargetIndex.A, () => comp.FinishPercentage));

            yield break;
        }
Пример #17
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);
        }
Пример #18
0
        public override void DrawPanelReadout(ref float curY, float width)
        {
            // we need the window's size to be able to do a scrollbar, but are not directly given that size.
            Rect outRect = ArchitectCategoryTab.InfoRect.AtZero();

            // our window actually starts from curY
            outRect.yMin = curY;

            // our contents height is given by final curY - which we conveniently saved
            Rect viewRect = new Rect(0f, 0f, width, _panelHeight);

            // if contents are larger than available canvas, leave some room for scrollbar
            if (viewRect.height > outRect.height)
            {
                outRect.width -= 16f;
                width         -= 16f;
            }

            // since we're going to work in new GUI group (through the scrollview), we'll need to keep track of
            // our own relative Y position.
            float oldY = curY;

            curY = 0f;

            // start scrollrect
            Widgets.BeginScrollView(outRect, ref _scrollPosition, viewRect);

            // list of objects to be build
            Text.Font = GameFont.Tiny;
            foreach (var buildables in Blueprint.GroupedBuildables)
            {
                // count
                float curX = 5f;
                Widgets.Label(new Rect(5f, curY, width * .2f, 100f), buildables.Value.Count + "x");
                curX += width * .2f;

                // stuff selector
                float height = 0f;
                if (buildables.Value.First().Stuff != null)
                {
                    string label = buildables.Value.First().Stuff.LabelAsStuff.CapitalizeFirst() + " " + buildables.Key.label;

                    Rect iconRect = new Rect(curX, curY, 12f, 12f);
                    curX += 16f;

                    height = Text.CalcHeight(label, width - curX) + _lineOffset;
                    Rect labelRect  = new Rect(curX, curY, width - curX, height);
                    Rect buttonRect = new Rect(curX - 16f, curY, width - curX + 16f, height + _lineOffset);

                    if (Mouse.IsOver(buttonRect))
                    {
                        GUI.DrawTexture(buttonRect, TexUI.HighlightTex);
                        GUI.color = GenUI.MouseoverColor;
                    }
                    GUI.DrawTexture(iconRect, Resources.Icon_Edit);
                    GUI.color = Color.white;
                    Widgets.Label(labelRect, label);
                    if (Widgets.ButtonInvisible(buttonRect))
                    {
                        Blueprint.DrawStuffMenu(buildables.Key);
                    }
                }
                else
                {
                    // label
                    float  labelWidth = width - curX;
                    string label      = buildables.Key.LabelCap;
                    height = Text.CalcHeight(label, labelWidth) + _lineOffset;
                    Widgets.Label(new Rect(curX, curY, labelWidth, height), label);
                }

                // next line
                curY += height + _lineOffset;
            }

            // complete cost list
            curY     += 12f;
            Text.Font = GameFont.Small;
            Widgets.Label(new Rect(0f, curY, width, 24f), "Fluffy.Blueprint.Cost".Translate());
            curY += 24f;

            Text.Font = GameFont.Tiny;
            List <ThingDefCount> costlist = Blueprint.CostListAdjusted;

            for (int i = 0; i < costlist.Count; i++)
            {
                ThingDefCount thingCount = costlist[i];
                Texture2D     image;
                if (thingCount.ThingDef == null)
                {
                    image = BaseContent.BadTex;
                }
                else
                {
                    image = thingCount.ThingDef.uiIcon;
                }
                GUI.DrawTexture(new Rect(0f, curY, 20f, 20f), image);
                if (thingCount.ThingDef != null && thingCount.ThingDef.resourceReadoutPriority != ResourceCountPriority.Uncounted && Find.CurrentMap.resourceCounter.GetCount(thingCount.ThingDef) < thingCount.Count)
                {
                    GUI.color = Color.red;
                }
                Widgets.Label(new Rect(26f, curY + 2f, 50f, 100f), thingCount.Count.ToString());
                GUI.color = Color.white;
                string text;
                if (thingCount.ThingDef == null)
                {
                    text = "(" + "UnchosenStuff".Translate() + ")";
                }
                else
                {
                    text = thingCount.ThingDef.LabelCap;
                }
                float height = Text.CalcHeight(text, width - 60f) - 2f;
                Widgets.Label(new Rect(60f, curY + 2f, width - 60f, height), text);
                curY += height + _lineOffset;
            }

            Widgets.EndScrollView();

            _panelHeight = curY;

            // need to give some extra offset to properly align description.
            // also, add back in our internal offset
            curY += 28f + oldY;
        }
        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);
        }