Beispiel #1
0
        private static void DrawRangedStatRows(List <TSPWQuality> pairList, Rect startRect, int from, int to)
        {
            List <List <StatDrawInfo> > listHolder      = new List <List <StatDrawInfo> >();
            List <List <StatDrawInfo> > transposedLists = new List <List <StatDrawInfo> >();

            // listHolder[0]  listHolder[1]
            // | stuff1 |     | stuff2 |
            // | Damage |     | Damage |
            // | AP     |     | AP     |

            /*                       stuff1   stuff2
             * transposedLists[0]    Damage   Damage
             * transposedLists[1]    AP       AP
             */

            for (int i = from; i < to && i < pairList.Count; i++)
            {
                TSPWQuality         pair     = pairList[i];
                List <StatDrawInfo> infoList = new List <StatDrawInfo>();

                infoList.AddRange(pair.thing.SpecialDisplayStats(StatRequest.For(pair.thing, pair.stuff, pair.Quality))
                                  .Where(r => _rangedWeaponStats.Any(s => s.label.CapitalizeFirst() == r.LabelCap))
                                  .Select(r => (StatDrawInfo)r)
                                  .ToList());
                listHolder.Add(infoList);
            }

            // Transpose lists
            for (int i = 0; i < _rangedWeaponStats.Count; i++)
            {
                List <StatDrawInfo> newList = new List <StatDrawInfo>();
                foreach (List <StatDrawInfo> list in listHolder)
                {
                    newList.Add(
                        list.Find(s => s.LabelCap == _rangedWeaponStats[i].label.CapitalizeFirst())
                        ?? new StatDrawInfo()
                    {
                        ValueString = "-", Tip = string.Empty,
                    });
                }

                if (newList.Count > 1)
                {
                    List <StatDrawInfo> orderedList = newList.OrderByDescending(t => t.Value).ToList();
                    foreach (StatDrawInfo statDrawInfo in orderedList)
                    {
                        if (statDrawInfo.Value == orderedList[0].Value)
                        {
                            statDrawInfo.Color = Color.green;
                        }
                    }
                }

                transposedLists.Add(newList);
            }

            DrawStatRows(_rangedWeaponStats, null, startRect, from, to, out _, transposedLists, true);
        }
Beispiel #2
0
        protected override bool LongSearchMatch(ThingDef thing)
        {
            if (!base.LongSearchMatch(thing))
            {
                return(false);
            }
            if (!fromCategory.NullOrEmpty())
            {
                if (thing.thingCategories.NullOrEmpty() || !thing.thingCategories.Exists(cat => fromCategory.Contains(cat)))
                {
                    return(false);
                }
            }
            if (!fromRessource.NullOrEmpty())
            {
                if (!fromRessource.Exists(ress => ress.stuffProps.CanMake(thing)))
                {
                    return(false);
                }
            }
            if (!neededStats.NullOrEmpty())
            {
                if (thing.statBases.NullOrEmpty())
                {
                    return(false);
                }
                QualityCategory quality;
                List <ThingDef> stuffs;
                for (int i = 0; i < neededStats.Count; i++)
                {
                    if (!thing.statBases.StatListContains(neededStats[i].def))
                    {
                        return(false);
                    }
                    quality = thing.HasComp(typeof(CompQuality)) ? QualityCategory.Legendary : QualityCategory.Normal;
                    if (thing.MadeFromStuff)
                    {
                        stuffs = fromRessource.NullOrEmpty() ?
                                 DefDatabase <ThingDef> .AllDefsListForReading.FindAll(def => def.IsStuff && def.stuffProps.CanMake(thing)) :
                                 fromRessource.FindAll(def => def.stuffProps.CanMake(thing));

                        for (int j = 0; j < stuffs.Count; j++)
                        {
                            if (neededStats[i].def.Worker.GetValue(StatRequest.For(thing, stuffs[i], quality)) < neededStats[i].minValue)
                            {
                                return(false);
                            }
                        }
                    }
                    else if (neededStats[i].def.Worker.GetValue(StatRequest.For(thing, null, quality)) < neededStats[i].minValue)
                    {
                        return(false);
                    }
                }
            }
            return(true);
        }
Beispiel #3
0
        public static float GetBestValue(ThingDef td)
        {
            float val = StatDefOf.MarketValue.Worker.GetValue(StatRequest.For(td, null, QualityCategory.Legendary), true);

            if (td.stackLimit == 1 || td.BaseMarketValue >= forceSingleThreshold)
            {
                return(val);
            }
            return(ShardMaker.stackSize * val);
        }
Beispiel #4
0
        //ctor to populate lists.
        public MainTabWindow_Numbers()
        {
            optionsMaker = new OptionsMaker(this);

            MethodInfo statsToDraw = typeof(StatsReportUtility).GetMethod("StatsToDraw",
                                                                          BindingFlags.NonPublic | BindingFlags.Static |
                                                                          BindingFlags.InvokeMethod, null,
                                                                          new[] { typeof(Thing) }, null);

            Pawn tmpPawn = PawnGenerator.GeneratePawn(PawnKindDefOf.AncientSoldier, Faction.OfPlayerSilentFail);

            if (statsToDraw != null)
            {
                pawnHumanlikeStatDef =
                    ((IEnumerable <StatDrawEntry>)statsToDraw.Invoke(null, new[] { tmpPawn }))
                    .Concat(tmpPawn.def.SpecialDisplayStats(StatRequest.For(tmpPawn)))
                    .Where(s => s.stat != null && s.ShouldDisplay && s.stat.Worker != null)
                    .Select(s => s.stat)
                    .OrderBy(stat => stat.LabelCap.RawText);

                tmpPawn = PawnGenerator.GeneratePawn(PawnKindDefOf.Thrumbo);

                pawnAnimalNeedDef = tmpPawn.needs.AllNeeds.Where(x => x.def.showOnNeedList).Select(x => x.def);

                pawnAnimalStatDef =
                    ((IEnumerable <StatDrawEntry>)statsToDraw.Invoke(null, new[] { tmpPawn }))
                    .Where(s => s.stat != null && s.ShouldDisplay && s.stat.Worker != null)
                    .Select(s => s.stat)
                    .OrderBy(stat => stat.LabelCap.RawText);

                Corpse corpse = (Corpse)ThingMaker.MakeThing(tmpPawn.RaceProps.corpseDef);
                corpse.InnerPawn = tmpPawn;

                corpseStatDef = ((IEnumerable <StatDrawEntry>)statsToDraw.Invoke(null, new[] { corpse }))
                                .Concat(tmpPawn.def.SpecialDisplayStats(StatRequest.For(tmpPawn)))
                                .Where(s => s.stat != null && s.ShouldDisplay && s.stat.Worker != null)
                                .Select(s => s.stat)
                                .OrderBy(stat => stat.LabelCap.RawText);
            }
            else
            {
                Log.Error("ReflectionTypeLoadException in Numbers: statsToDraw was null. Please contact mod author.");
            }

            pawnHumanlikeNeedDef = DefDatabase <NeedDef> .AllDefsListForReading;

            PawnTableDef defaultTable = WorldComponent_Numbers.PrimaryFilter.First().Key;

            if (Find.World.GetComponent <WorldComponent_Numbers>().sessionTable.TryGetValue(defaultTable, out List <PawnColumnDef> list))
            {
                pawnTableDef.columns = list;
            }

            UpdateFilter();
        }
        public double GetAnimalCost(Thing thing)
        {
            if (statWorker == null)
            {
                StatDef marketValueStatDef = StatDefOf.MarketValue;
                statWorker = marketValueStatDef.Worker;
            }
            float value = statWorker.GetValue(StatRequest.For(thing));

            return(value);
        }
            public static void DefsLoaded()
            {
                var smallCorpses = ThingCategoryDefOf.Corpses.ThisAndChildCategoryDefs.SelectMany(x => x.childThingDefs).Where(
                    x =>
                    x.ingestible?.sourceDef != null &&
                    StatDefOf.MeatAmount.Worker.ShouldShowFor(StatRequest.For(x.ingestible.sourceDef, null)) &&
                    x.ingestible.sourceDef.GetStatValueAbstract(StatDefOf.MeatAmount) > 0 &&
                    x.ingestible.sourceDef.GetStatValueAbstract(StatDefOf.MeatAmount) <= 75);

                // second parameter is "exceptedFilters" but it's actually the filters to disallow apparently??
                ConvenientButcherRecipes.COAA_ButcherSmallCreatureFlesh.fixedIngredientFilter.SetDisallowAll(smallCorpses, new[] { SpecialFilter.AllowRotten });
            }
        public override bool CanBeAppliedToThing(ThingWithComps thing)
        {
            // ShouldShowFor doesn't show Max HP, so force it in
            if (affectedStat == StatDefOf.MaxHitPoints)
            {
                return(thing.def.useHitPoints);
            }

            StatRequest req = StatRequest.For(thing);

            return(affectedStat.Worker.ShouldShowFor(req));
        }
Beispiel #8
0
        public override IEnumerable <StatDrawEntry> SpecialDisplayStats()
        {
            var props = Props;

            if (props != null)
            {
                if (props.damageDef != null)
                {
                    var damageTypeStr = props.damageDef.LabelCap;
                    yield return(new StatDrawEntry(CompSlotLoadableDefOf.SlotLoadable, StringOf.OverrideDamageType, damageTypeStr,
                                                   string.Format(StringOf.OverrideDamageTypeExplanation, damageTypeStr), 99));

                    // TODO: armorPenStr should somehow be calculated via equivalent logic in ThingDef.SpecialDisplayStats.
                    var armorPenStr = props.armorPenetration.ToStringPercent();
                    yield return(new StatDrawEntry(CompSlotLoadableDefOf.SlotLoadable, StringOf.OverrideArmorPenetration, armorPenStr,
                                                   string.Format("ArmorPenetrationExplanation".Translate(), armorPenStr), 98));
                }
                var statModifiers = props.statModifiers;
                if (statModifiers != null)
                {
                    var statReq = StatRequest.For(parent);
                    foreach (var mod in statModifiers)
                    {
                        var stat = mod.stat;
                        yield return(new StatDrawEntry(CompSlotLoadableDefOf.SlotLoadable, stat,
                                                       stat.Worker.GetValue(statReq), statReq, ToStringNumberSense.Offset));
                    }
                }
                var defHealChance = props.defensiveHealChance;
                if (defHealChance != null)
                {
                    var chanceStr     = defHealChance.chance.ToStringPercent();
                    var woundLimitStr = defHealChance.woundLimit == int.MaxValue ? StringOf.all : defHealChance.woundLimit.ToString();
                    yield return(new StatDrawEntry(CompSlotLoadableDefOf.SlotLoadable, StringOf.DefensiveHeal,
                                                   string.Format(StringOf.DefensiveHealShort, chanceStr, woundLimitStr, defHealChance.amountRange),
                                                   string.Format(StringOf.DefensiveHealExplanation, chanceStr, woundLimitStr, defHealChance.amountRange),
                                                   90));
                }
                var vampHealChance = props.vampiricHealChance;
                if (vampHealChance != null)
                {
                    var chanceStr     = vampHealChance.chance.ToStringPercent();
                    var woundLimitStr = vampHealChance.woundLimit == int.MaxValue ? StringOf.all : vampHealChance.woundLimit.ToString();
                    var armorPenStr   = vampHealChance.armorPenetration.ToStringPercent();
                    yield return(new StatDrawEntry(CompSlotLoadableDefOf.SlotLoadable, StringOf.VampiricHeal,
                                                   string.Format(StringOf.VampiricHealShort, chanceStr, woundLimitStr, vampHealChance.amountRange, vampHealChance.damageDef, armorPenStr),
                                                   string.Format(StringOf.VampiricHealExplanation, chanceStr, woundLimitStr, vampHealChance.amountRange, vampHealChance.damageDef, armorPenStr),
                                                   89));
                }
            }
        }
Beispiel #9
0
        private List <StatDef> GetHumanLikeStatDefs()
        {
            Pawn tmpPawn = PawnGenerator.GeneratePawn(PawnKindDefOf.AncientSoldier, Faction.OfPlayerSilentFail);

            var source = ((IEnumerable <StatDrawEntry>)StatsToDraw?.Invoke(null, new[] { tmpPawn })) ?? Enumerable.Empty <StatDrawEntry>();

            var pawnHumanlikeStatDef = source
                                       .Concat(tmpPawn.def.SpecialDisplayStats(StatRequest.For(tmpPawn)))
                                       .Where(s => s.stat != null && s.ShouldDisplay && s.stat.Worker != null)
                                       .Select(s => s.stat);

            tmpPawn.Destroy(DestroyMode.KillFinalize);

            return(pawnHumanlikeStatDef.OrderBy(stat => stat.LabelCap.Resolve()).ToList());
        }
Beispiel #10
0
            static StatThingInfo CreateInstance(StatDef statDef)
            {
                float?min = null, max = null;
                var   foundFraction  = false;
                var   thingDefValues = new Dictionary <ThingDef, float>();

                foreach (var thingDef in DefDatabase <ThingDef> .AllDefsListForReading)
                {
                    if (!statDef.Worker.ShouldShowFor(StatRequest.For(thingDef, null)))
                    {
                        continue;
                    }

                    // https://github.com/CombatExtendedRWMod/CombatExtended/blob/7768f94edae4ffffdce16cb3bb7b10db0e541a79/Source/CombatExtended/CombatExtended/StatWorkers/StatWorker_MeleeDamageAverage.cs#L31
                    if (CeToolCeType != null && thingDef.tools != null && thingDef.tools.Any(x => x.GetType() != CeToolCeType))
                    {
                        continue;
                    }
                    var value = thingDef.GetStatValueAbstract(statDef);
                    if (Mathf.Approximately(value, statDef.hideAtValue))
                    {
                        continue;
                    }

                    if (!foundFraction && !Mathf.Approximately(value % 1, 0))
                    {
                        foundFraction = true;
                    }
                    min = Math.Min(min ?? value, value);
                    max = Math.Max(max ?? value, value);
                    thingDefValues.Add(thingDef, value);
                }

                if (min == null || float.IsNaN((float)min) || min.Equals(max))
                {
                    return(null);
                }
                //Debug.WriteLine($"{statDef} \"{statDef.label}\" {min} {max} {statDef.toStringStyle} \"{string.Join(", ", thingDefValues.Select(x => x.ToString()).ToArray())}\"");

                if (statDef.toStringStyle == default && !explicitlyIntegers.Contains(statDef) && foundFraction)
                {
                    statDef.toStringStyle = ToStringStyle.FloatTwo;
                }

                var result = new StatThingInfo(statDef, thingDefValues, (float)min, (float)max);

                return(result);
            }
        public static void Postfix(BuildingProperties __instance, ref IEnumerable <StatDrawEntry> __result, ThingDef parentDef, StatRequest req)
        {
            var turretGunDef = __instance.turretGunDef;

            if (turretGunDef != null)
            {
                var statRequestGun = StatRequest.For(turretGunDef, null);

                var newStats1 = DefDatabase <StatDef> .AllDefs
                                .Where(x => x.category == StatCategoryDefOf.Weapon &&
                                       x.Worker.ShouldShowFor(statRequestGun) &&
                                       !x.Worker.IsDisabledFor(req.Thing) &&
                                       !(x.Worker is StatWorker_MeleeStats))
                                .Select(x => new StatDrawEntry(StatCategoryDefOf.Weapon, x, turretGunDef.GetStatValueAbstract(x), statRequestGun, ToStringNumberSense.Undefined))
                                .Where(x => x.ShouldDisplay)
                                .Concat(turretGunDef.SpecialDisplayStats(statRequestGun));

                __result = __result.Concat(newStats1);
            }
        }
        static public void PostAffixCleanup(this CompLootAffixableThing comp, bool fixLabel = true)
        {
            ThingWithComps thing = comp.parent;

            comp.ClearAffixCaches();

            if (fixLabel)
            {
                comp.affixRules.Clear();
                comp.fullStuffLabel = null;
                string name = thing.LabelNoCount;
                name = comp.TransformLabel(name);
            }

            thing.def.SpecialDisplayStats(StatRequest.For(thing));

            foreach (LootAffixDef affix in comp.affixes)
            {
                affix.PostApplyAffix(thing);
            }
        }
Beispiel #13
0
        public virtual float GetStatOffset(StatDef stat)
        {
            var statModifiers = Props?.statModifiers;

            if (statModifiers != null)
            {
                var statOffset = statModifiers.GetStatOffsetFromList(stat);
                //Log.Message("adding in stat " + stat + " offset: " + statOffset);
                if (!stat.parts.NullOrEmpty())
                {
                    var statReq = StatRequest.For(parent);
                    for (var i = 0; i < stat.parts.Count; i++)
                    {
                        //Log.Message("adding in parts " + stat.parts[i]);
                        stat.parts[i].TransformValue(statReq, ref statOffset);
                    }
                    //Log.Message("added in parts of a stat for result " + statOffset);
                }
                return(statOffset);
            }
            return(0f);
        }
Beispiel #14
0
        public static void Postfix(ThingDef __instance, ref IEnumerable <StatDrawEntry> __result, StatRequest req)
        {
            var turretGunDef = __instance.building?.turretGunDef ?? null;

            if (turretGunDef != null)
            {
                var statRequestGun = StatRequest.For(turretGunDef, null);

                var cache = __result;

                var newStats1 = DefDatabase <StatDef> .AllDefs
                                .Where(x => x.category == StatCategoryDefOf.Weapon &&
                                       x.Worker.ShouldShowFor(statRequestGun) &&
                                       !x.Worker.IsDisabledFor(req.Thing) &&
                                       !(x.Worker is StatWorker_MeleeStats))
                                .Where(x => !cache.Any(y => y.stat == x))
                                .Select(x => new StatDrawEntry(StatCategoryDefOf.Weapon, x, turretGunDef.GetStatValueAbstract(x), statRequestGun, ToStringNumberSense.Undefined))
                                .Where(x => x.ShouldDisplay);

                __result = __result.Concat(newStats1);
            }
        }
Beispiel #15
0
        public override IEnumerable <StatDrawEntry> SpecialDisplayStatsForThing(ThingWithComps parentThing, string preLabel)
        {
            // Add additional Equipped Stat Offsets modifiers
            var statDrawEntry = new StatDrawEntry(
                category:    StatCategoryDefOf.EquippedStatOffsets,
                label:       affectedStat.LabelCap,
                valueString: ModifierChangeString,  // much more flexible than value
                reportText:  affectedStat.description,
                displayPriorityWithinCategory: 10
                );

            StatRequest req = StatRequest.For(parentThing);

            // Extra properties, since we're overriding the typical stat value display
            statDrawEntry.stat           = affectedStat;
            statDrawEntry.hasOptionalReq = true;
            statDrawEntry.optionalReq    = req;

            // Calculate an example value
            StatWorker worker       = affectedStat.Worker;
            float      exampleValue =
                parentThing.ParentHolder != null && parentThing.ParentHolder is Pawn pawn?
                worker.GetValueUnfinalized(StatRequest.For(pawn)) :
                    affectedStat.defaultBaseValue
            ;

            // Use the Thing-tied StatRequest to hit our StatPart
            worker.FinalizeValue(req, ref exampleValue, true);

            // And finally, another private we need to dodge around to install both kinds of StatDrawEntry fields.

            // [Reflection] statDrawEntry.value = exampleValue;
            FieldInfo valueField = AccessTools.Field(typeof(StatDrawEntry), "value");

            valueField.SetValue(statDrawEntry, exampleValue);

            yield return(statDrawEntry);
        }
Beispiel #16
0
        public static float DetermineSlottableStatAugment(Thing slottable, StatDef stat)
        {
            float            retval    = 0.0f;
            CompSlottedBonus slotBonus = slottable.TryGetComp <CompSlottedBonus>();

            if (slotBonus != null)
            {
                if (slotBonus.Props != null)
                {
                    if (slotBonus.Props.statModifiers != null && slotBonus.Props.statModifiers.Count > 0)
                    {
                        foreach (StatModifier thisStat in slotBonus.Props.statModifiers)
                        {
                            //Log.Message("Check for modding "+stat+"  against "+thisStat.stat);
                            if (thisStat.stat == stat)
                            {
                                //Log.Message("adding in stat "+thisStat.stat+":"+thisStat.value+" to result "+retval);
                                retval += thisStat.value;

                                // apply stats parts from Slottable
                                if (stat.parts != null && stat.parts.Count > 0)
                                {
                                    StatRequest req = StatRequest.For(slottable);
                                    for (int i = 0; i < stat.parts.Count; i++)
                                    {
                                        //Log.Message("adding in parts "+stat.parts[i]);
                                        stat.parts[i].TransformValue(req, ref retval);
                                    }
                                    //Log.Message("added in parts of a stat for result "+retval);
                                }
                            }
                        }
                    }
                }
            }

            return(retval);
        }
Beispiel #17
0
        /// Changed into a transpiler.
        /// <summary>
        /// Replaces the plant harvest toil of a cutebold to allow them to harvest over 100%.
        /// </summary>
        /// <param name="__result">The previous output from the original toil generator.</param>
        /// <param name="__instance">The plant job.</param>
        /// <returns>A headache. (The new toils)</returns>
        private static IEnumerable <Toil> CuteboldMakeNewToilsPlantWorkPostfix(IEnumerable <Toil> __result, JobDriver_PlantWork __instance)
        {
            //Log.Message("CuteboldMakeNewToilsPlantWorkPostfix");

            foreach (Toil toil in __result)
            {
                if (toil.tickAction != null && __instance.pawn?.def.defName == Cutebold_Assemblies.RaceName)
                {
                    //Log.Message("  Edit Toil");

                    // Shamelessly taken from the base code and modified to allow cutebolds to harvest just that little bit more with their small, delicate hands.
                    // Two Traverses are used to access protected methods that are overwritten by classes that overwrite the defaults.
                    toil.tickAction = delegate()
                    {
                        Pawn  actor     = toil.actor;
                        Map   map       = actor.Map;
                        float xpPerTick = (float)Traverse.Create(__instance).Field("xpPerTick").GetValue();

                        if (actor.skills != null)
                        {
                            actor.skills.Learn(SkillDefOf.Plants, xpPerTick);
                        }

                        float workSpeed = actor.GetStatValue(StatDefOf.PlantWorkSpeed, true);
                        Plant plant     = (Plant)__instance.job.targetA.Thing;

                        workSpeed *= UnityEngine.Mathf.Lerp(3.3f, 1f, plant.Growth);
                        var   workDoneVariable = Traverse.Create(__instance).Field("workDone");
                        float workDone         = (float)workDoneVariable.GetValue() + workSpeed;
                        workDoneVariable.SetValue(workDone);

                        if ((workDone) >= plant.def.plant.harvestWork)
                        {
                            if (plant.def.plant.harvestedThingDef != null)
                            {
                                StatDef stat = (plant.def.plant.harvestedThingDef.IsDrug ? StatDefOf.DrugHarvestYield : StatDefOf.PlantHarvestYield);
// 1.1                          StatDef stat = StatDefOf.PlantHarvestYield;
                                float yieldMultiplier = (1f + CuteboldCalculateExtraPercent(stat, StatRequest.For(actor)));
                                if (actor.RaceProps.Humanlike && plant.def.plant.harvestFailable && !plant.Blighted && Rand.Value > yieldMultiplier)
                                {
                                    MoteMaker.ThrowText((__instance.pawn.DrawPos + plant.DrawPos) / 2f, map, "TextMote_HarvestFailed".Translate(), 3.65f);
                                }
                                else
                                {
                                    int currentYield = GenMath.RoundRandom(plant.YieldNow() * yieldMultiplier);

                                    //Log.Message("  Pawn Additional Harvest Percent=" + calculateExtraPercent(StatDefOf.PlantHarvestYield, StatRequest.For(actor)));
                                    //Log.Message("  Plant Yield Before=" + plant.YieldNow() + " Plant Yield After=" + currentYield);

                                    if (currentYield > 0)
                                    {
                                        Thing product = ThingMaker.MakeThing(plant.def.plant.harvestedThingDef, null);

                                        product.stackCount = currentYield;

                                        if (actor.Faction != Faction.OfPlayer)
                                        {
                                            product.SetForbidden(true);
                                        }

                                        Find.QuestManager.Notify_PlantHarvested(actor, product);
                                        GenPlace.TryPlaceThing(product, actor.Position, map, ThingPlaceMode.Near);
                                        actor.records.Increment(RecordDefOf.PlantsHarvested);
                                    }
                                }
                            }
                            plant.def.plant.soundHarvestFinish.PlayOneShot(actor);
                            plant.PlantCollected(__instance.pawn);
// 1.1                      plant.PlantCollected();
                            workDoneVariable.SetValue(0f);
                            __instance.ReadyForNextToil();
                            return;
                        }
                    };
                }
                yield return(toil);
            }
        }
Beispiel #18
0
 public static IEnumerable <StatDrawEntry> Postfix(IEnumerable <StatDrawEntry> original, Thing thing)
 {
     foreach (StatDrawEntry entry in original)
     {
         Pawn    pawn    = thing as Pawn;
         StatDef statDef = entry.stat;
         if (pawn != null && pawn.InBed() && (statDef == StatDefOf.ComfyTemperatureMin || statDef == StatDefOf.ComfyTemperatureMax))
         {
             if (!statDef.Worker.IsDisabledFor(thing))
             {
                 //sneak transform:
                 float   statValue    = statDef.Worker.GetValueUnfinalized(StatRequest.For(thing), true);
                 bool    subtract     = statDef == StatDefOf.ComfyTemperatureMin;
                 StatDef modifier     = subtract ? BedInsulationCold.Bed_Insulation_Cold : BedInsulationHeat.Bed_Insulation_Heat;
                 float   bedStatValue = pawn.CurrentBed().GetStatValue(modifier, true);
                 float   bedOffset    = subtract ? bedStatValue * -1 : bedStatValue;
                 statValue += bedOffset;
                 //
                 if (statDef.showOnDefaultValue || statValue != statDef.defaultBaseValue)
                 {
                     yield return(new StatDrawEntry(statDef.category, statDef, statValue, StatRequest.For(thing), ToStringNumberSense.Undefined, null, false));
                 }
             }
             else
             {
                 yield return(new StatDrawEntry(statDef.category, statDef));
             }
         }
         else
         {
             yield return(entry);
         }
     }
 }
Beispiel #19
0
        private static void DrawStatRows(List <StatDef> stats, List <TSPWQuality> pairs, Rect startRect, int from, int to,
                                         out float rollingY, List <List <StatDrawInfo> > listHolder = null,
                                         bool specialStats = false)
        {
            float startX = startRect.x;

            for (int i = 0; i < stats.Count; i++)
            {
                List <StatDrawInfo> statInfoList = new List <StatDrawInfo>();
                if (!specialStats)
                {
                    statInfoList = new List <StatDrawInfo>();

                    // Retrieve stat value and create a view model, StatDrawInfo, for drawing.
                    for (int j = from; j < to && j < pairs.Count; j++)
                    {
                        TSPWQuality  pair        = pairs[j];
                        StatDrawInfo drawInfo    = new StatDrawInfo();
                        Thing        tempThing   = pair.MakeThingWithoutID();
                        StatRequest  statRequest = StatRequest.For(tempThing);
                        if ((stats[i].Worker.ShouldShowFor(statRequest) && !stats[i].Worker.IsDisabledFor(tempThing)) || stats[i] == StatDefOf.MaxHitPoints || stats[i] == StatDefOf.MeleeWeapon_CooldownMultiplier)
                        {
                            drawInfo.StatRequest = statRequest;
                            drawInfo.Value       = GetCachedValue(_statCache, () => stats[i].Worker.GetValue(drawInfo.StatRequest), pair, stats[i]);
                            drawInfo.Tip         = GetCachedValue(_statTipCache, () => stats[i].Worker.GetExplanationFull(drawInfo.StatRequest, stats[i].toStringNumberSense, drawInfo.Value), pair, stats[i]);
                        }
                        else
                        {
                            drawInfo.Value = -1;
                            drawInfo.Tip   = string.Empty;
                        }

                        statInfoList.Add(drawInfo);
                    }

                    if (statInfoList.Count > 1)
                    {
                        // Highlight highest stat value.
                        List <StatDrawInfo> orderedList = statInfoList.OrderByDescending(t => t.Value).ToList();
                        foreach (StatDrawInfo statDrawInfo in orderedList)
                        {
                            if (statDrawInfo.Value == orderedList[0].Value)
                            {
                                statDrawInfo.Color = Color.green;
                            }
                        }
                    }
                }
                else
                {
                    statInfoList = listHolder[i];
                }

#pragma warning disable SA1118 // Parameter should not span multiple lines

                // Draw stat for each stuff choice.
                Text.Anchor = TextAnchor.MiddleCenter;
                foreach (StatDrawInfo info in statInfoList)
                {
                    GUI.color = info.Color;
                    Widgets.Label(
                        startRect,
                        specialStats
                        ? info.ValueString
                        : info.Value == -1
                            ? "-"
                            : stats[i].Worker.ValueToString(info.Value, true, stats[i].toStringNumberSense));
                    Widgets.DrawHighlightIfMouseover(startRect);
                    Text.Anchor = TextAnchor.MiddleLeft;
                    TooltipHandler.TipRegion(startRect, info.Tip);
                    Text.Anchor = TextAnchor.MiddleCenter;
                    startRect   = startRect.ReplaceX(startRect.xMax);
                }
#pragma warning restore SA1118 // Parameter should not span multiple lines

                startRect = new Rect(startX, startRect.yMax, startRect.width, startRect.height);
            }

            rollingY    = startRect.y;
            Text.Anchor = TextAnchor.UpperLeft;
            GUI.color   = Color.white;
        }
Beispiel #20
0
        public static void DoSkillsAnalysis(this Pawn p)
        {
            var stringBuilder = new StringBuilder();

            stringBuilder.AppendLine("Beginning skills analysis.");
            foreach (var skill in p.skills.skills)
            {
                stringBuilder.AppendLine(skill.def + ": " + skill.levelInt + " Disabled: " + skill.TotallyDisabled);
            }
            stringBuilder.AppendLine("Beginning food poison test.");

            /*
             * foreach (var stat in DefDatabase<StatDef>.AllDefs)
             * {
             *  try
             *  {
             *      stringBuilder.AppendLine(stat.defName + ": " + p.GetStatValue(stat));
             *  }
             *  catch
             *  {
             *      stringBuilder.AppendLine(stat.defName + ": ERROR");
             *  }
             * }
             */
            stringBuilder.AppendLine(StatDefOf.FoodPoisonChance.Worker.GetExplanation(StatRequest.For(p), ToStringNumberSense.Absolute));
            Log.Message(stringBuilder.ToString());
        }
Beispiel #21
0
        private void DrawForagedFoodPerDay(Rect rect, TransferableOneWay trad)
        {
            if (!trad.HasAnyThing)
            {
                return;
            }
            if (!(trad.AnyThing is Pawn p))
            {
                return;
            }
            float foragedNutritionPerDay = ForagedFoodPerDayCalculator.GetBaseForagedNutritionPerDay(p, out bool flag);

            if (flag)
            {
                return;
            }
            Widgets.DrawHighlightIfMouseover(rect);
            GUI.color = ((foragedNutritionPerDay == 0f) ? Color.gray : Color.green);
            Widgets.Label(rect, "+" + foragedNutritionPerDay.ToString("0.##"));
            GUI.color = Color.white;
            if (Mouse.IsOver(rect))
            {
                TooltipHandler.TipRegion(rect, () => "NutritionForagedPerDayTip".Translate(StatDefOf.ForagedNutritionPerDay.Worker.GetExplanationFull(StatRequest.For(p), StatDefOf.ForagedNutritionPerDay.toStringNumberSense, foragedNutritionPerDay)), trad.GetHashCode() ^ 1958671422);
            }
        }
 public static float PaperclipAmount(this ThingDef tDef, ThingDef stuff = null)
 {
     return(StatDefOf.Mass.Worker.GetValue(StatRequest.For(tDef, stuff)) * 1000);
 }
Beispiel #23
0
 public static float GetEnergyAmount(ThingDef def, ThingDef stuffDef)
 {
     return(ConvertEnergyAmount(StatDefOf.MarketValue.Worker.GetValue(StatRequest.For(def, stuffDef))));
 }
Beispiel #24
0
        public override IEnumerable <StatDrawEntry> SpecialDisplayStats()
        {
            foreach (StatDrawEntry s in this.< SpecialDisplayStats > __BaseCallProxy0())
            {
                yield return(s);
            }
            if (this.GetRotStage() == RotStage.Fresh)
            {
                StatDef meatAmount = StatDefOf.MeatAmount;
                yield return(new StatDrawEntry(meatAmount.category, meatAmount, this.InnerPawn.GetStatValue(meatAmount, true), StatRequest.For(this.InnerPawn), ToStringNumberSense.Undefined));

                StatDef leatherAmount = StatDefOf.LeatherAmount;
                yield return(new StatDrawEntry(leatherAmount.category, leatherAmount, this.InnerPawn.GetStatValue(leatherAmount, true), StatRequest.For(this.InnerPawn), ToStringNumberSense.Undefined));
            }
            yield break;
        }
Beispiel #25
0
        private static RecipeDef CreateMiningRecipe(ThingDefCountClass defCount, EffecterDef effecter)
        {
            RecipeDef r = new RecipeDef();

            r.defName   = "Recipe_AutoMachineTool_Mine_" + defCount.thingDef.defName;
            r.label     = "PRF.AutoMachineTool.AutoMiner.MineOre".Translate(defCount.thingDef.label);
            r.jobString = "PRF.AutoMachineTool.AutoMiner.MineOre".Translate(defCount.thingDef.label);

            r.workAmount     = Mathf.Max(10000f, StatDefOf.MarketValue.Worker.GetValue(StatRequest.For(defCount.thingDef, null)) * defCount.count * 1000);
            r.workSpeedStat  = StatDefOf.WorkToMake;
            r.efficiencyStat = StatDefOf.WorkToMake;

            r.workSkill            = SkillDefOf.Mining;
            r.workSkillLearnFactor = 0;

            r.products = new List <ThingDefCountClass>().Append(defCount);
            r.defaultIngredientFilter = new ThingFilter();

            r.effectWorking = effecter;

            // ChunkStone が Recipe の WorkAmount 経由で価値を設定されてしまうため、BaseMarketValue に0を設定して、計算されないようにする。
            // <see cref="StatWorker_MarketValue.CalculatedBaseMarketValue(BuildableDef, ThingDef)"/>
            if (!defCount.thingDef.statBases.StatListContains(StatDefOf.MarketValue) && defCount.count == 1)
            {
                defCount.thingDef.BaseMarketValue = 0;
            }

            return(r);
        }
Beispiel #26
0
        static void SpecialDisplayStats_PostFix(Corpse __instance, ref IEnumerable <StatDrawEntry> __result)
        {
            // Create a modifyable list
            List <StatDrawEntry> NewList = new List <StatDrawEntry>();

            // copy vanilla entries into the new list
            foreach (StatDrawEntry entry in __result)
            {
                // it's possible to discard entries here if needed
                NewList.Add(entry);
            }

            // custom code to modify list contents
            StatDef BoneAmount = DefDatabase <StatDef> .GetNamed("BoneAmount", true);

            float pawnBoneCount = __instance.InnerPawn.GetStatValue(BoneAmount, true) * BoneModSettings.boneFactor;

            NewList.Add(new StatDrawEntry(BoneAmount.category, BoneAmount, pawnBoneCount, StatRequest.For(__instance.InnerPawn), ToStringNumberSense.Undefined));

            // convert list to IEnumerable to match the caller's expectations
            IEnumerable <StatDrawEntry> output = NewList;

            // make caller use the list
            __result = output;
        }
Beispiel #27
0
        private static RecipeDef CreateMiningRecipe(ThingDefCountClass defCount)
        {
            RecipeDef r = new RecipeDef();

            r.defName   = "Recipe_NR_AutoMachineTool_Mine_" + defCount.thingDef.defName;
            r.label     = "NR_AutoMachineTool.AutoMiner.MineOre".Translate(defCount.thingDef.label);
            r.jobString = "NR_AutoMachineTool.AutoMiner.MineOre".Translate(defCount.thingDef.label);

            r.workAmount     = Mathf.Max(10000f, StatDefOf.MarketValue.Worker.GetValue(StatRequest.For(defCount.thingDef, null)) * defCount.count * 1000);
            r.workSpeedStat  = StatDefOf.WorkToMake;
            r.efficiencyStat = StatDefOf.WorkToMake;

            r.workSkill            = SkillDefOf.Mining;
            r.workSkillLearnFactor = 0;

            r.products = new List <ThingDefCountClass>().Append(defCount);
            r.defaultIngredientFilter = new ThingFilter();

            r.effectWorking = EffecterDefOf.Drill;

            return(r);
        }
Beispiel #28
0
        public static bool FUUUCK(Rect rect, Thing thing)
        {
            if (!Active)
            {
                return(true);
            }

            Profiler prof = null;

            if (StatsReportUtility.cachedDrawEntries.NullOrEmpty <StatDrawEntry>())
            {
                prof = ProfileController.Start("SpecialDisplayStats");
                StatsReportUtility.cachedDrawEntries.AddRange(thing.def.SpecialDisplayStats(StatRequest.For(thing)));
                prof.Stop();

                prof = ProfileController.Start("StatsToDraw");
                StatsReportUtility.cachedDrawEntries.AddRange(StatsReportUtility.StatsToDraw(thing).Where(s => s.ShouldDisplay));
                prof.Stop();

                prof = ProfileController.Start("RemoveAll");
                StatsReportUtility.cachedDrawEntries.RemoveAll((StatDrawEntry de) => de.stat != null && !de.stat.showNonAbstract);
                prof.Stop();

                prof = ProfileController.Start("FinalizeCachedDrawEntries");
                StatsReportUtility.FinalizeCachedDrawEntries(StatsReportUtility.cachedDrawEntries);
                prof.Stop();
            }
            prof = ProfileController.Start("DrawStatsWorker");
            StatsReportUtility.DrawStatsWorker(rect, thing, null);
            prof.Stop();

            return(false);
        }
        private void DrawStatsWorker(Rect rect)
        {
            Rect rect2 = new Rect(rect);

            rect2.width *= 0.5f;
            Rect rect3 = new Rect(rect);

            rect3.x     = rect2.xMax;
            rect3.width = rect.xMax - rect3.x;
            Text.Font   = GameFont.Small;
            Rect viewRect = new Rect(0f, 0f, rect2.width - 16f, listHeight);

            Widgets.BeginScrollView(rect2, ref scrollPosition, viewRect, true);
            float  num = 0f;
            string b   = null;

            cachedDrawEntries = this.StatsToDraw(this.thing).ToList();
            this.FinalizeCachedDrawEntries();
            mousedOverEntry = null;
            foreach (StatDrawEntry stat in cachedDrawEntries)
            {
                if (stat.category.LabelCap != b)
                {
                    Widgets.ListSeparator(ref num, viewRect.width, stat.category.LabelCap);
                    b = stat.category.LabelCap;
                }
                num += stat.Draw(8f, num, viewRect.width - 8f, selectedEntry == stat, delegate
                {
                    selectedEntry = stat;
                    SoundDefOf.Tick_High.PlayOneShotOnCamera(null);
                }, delegate
                {
                    mousedOverEntry = stat;
                }, scrollPosition, rect2);
            }
            listHeight = num + 100f;
            Widgets.EndScrollView();
            Rect rect4 = rect3.ContractedBy(10f);

            GUI.BeginGroup(rect4);
            StatDrawEntry statDrawEntry;

            if ((statDrawEntry = selectedEntry) is null)
            {
                statDrawEntry = mousedOverEntry ?? cachedDrawEntries.FirstOrDefault <StatDrawEntry>();
            }
            StatDrawEntry statDrawEntry2 = statDrawEntry;

            if (statDrawEntry2 != null)
            {
                StatRequest optionalReq;
                if (statDrawEntry2.hasOptionalReq)
                {
                    optionalReq = statDrawEntry2.optionalReq;
                }
                else if (this.thing != null)
                {
                    optionalReq = StatRequest.For(this.thing);
                }
                else
                {
                    optionalReq = StatRequest.ForEmpty();
                }
                string explanation = statDrawEntry2.GetExplanationText(optionalReq);
                Rect   rect5       = rect4.AtZero();
                Widgets.Label(rect5, explanation);
            }
            GUI.EndGroup();
        }
Beispiel #30
0
        /// Convered into a transpiler.
        /// <summary>
        /// Adds extra materials to mined rock when the yield is over the default max.
        /// </summary>
        /// <param name="__instance">What was mined</param>
        /// <param name="___yieldPct">The max yield percentage</param>
        /// <param name="map">The map we are on</param>
        /// <param name="yieldChance">The chance to yield something (Ignored)</param>
        /// <param name="moteOnWaste">If we should do a mote on waste (Ignored)</param>
        /// <param name="pawn">The pawn mining</param>
        private static void CuteboldTrySpawnYieldMiningPostfix(Mineable __instance, float ___yieldPct, Map map, float yieldChance, bool moteOnWaste, Pawn pawn)
        {
            //Log.Message("CuteboldTrySapwnYieldMiningPostfix");

            if (pawn?.def.defName != Cutebold_Assemblies.RaceName || __instance == null || __instance.def.building.mineableThing == null || __instance.def.building.mineableDropChance < 1f || !__instance.def.building.mineableYieldWasteable)
            {
                return;
            }
            //if (pawn == null || pawn.def.defName != Cutebold_Assemblies.RaceName || __instance == null || __instance.def.building.mineableThing == null || __instance.def.building.mineableDropChance < 1f || !__instance.def.building.mineableYieldWasteable) return;

            //Log.Message("  Effective Mineable Yield="+ __instance.def.building.EffectiveMineableYield.ToString());
            //Log.Message("  Yield Percent=" + ___yieldPct.ToString());
            //Log.Message("  Mineable Thing=" + __instance.def.building.mineableThing.ToString());

            float extraPercent = CuteboldCalculateExtraPercent(StatDefOf.MiningYield, StatRequest.For(pawn));

            //Log.Message("  Pawn Additional Mining Percent=" + extraPercent);

            // Based on the RimWorld base code to allow for mining yield over 100% cause cutebolds are just that good at mining.
            if (___yieldPct >= 1f && extraPercent > 0f)
            {
                Thing minedMaterial = ThingMaker.MakeThing(__instance.def.building.mineableThing);
                minedMaterial.stackCount = GenMath.RoundRandom(__instance.def.building.EffectiveMineableYield * extraPercent);
// 1.1          minedMaterial.stackCount = GenMath.RoundRandom(__instance.def.building.mineableYield * extraPercent);
                GenPlace.TryPlaceThing(minedMaterial, __instance.Position, map, ThingPlaceMode.Near, ForbidIfNecessary);
            }

            void ForbidIfNecessary(Thing minedMaterial, int count)
            {
                if ((pawn == null || !pawn.IsColonist) && minedMaterial != null && minedMaterial.def.EverHaulable && !minedMaterial.def.designateHaulable)
                {
                    minedMaterial.SetForbidden(value: true, warnOnFail: false);
                }
            }
        }