public override IEnumerable <StatDrawEntry> SpecialDisplayStats(StatRequest req) { foreach (StatDrawEntry s in base.SpecialDisplayStats(req)) { yield return(s); } if (DeepStorageCategory == null) { DeepStorageCategory = DefDatabase <StatCategoryDef> .GetNamed("LWM_DS_Stats"); if (DeepStorageCategory == null) { Log.Warning("LWM.DeepStorage: Stat Category FAILED to load."); yield break; } } yield return(new StatDrawEntry(DeepStorageCategory, "LWM_DS_maxNumStacks".Translate(), size > 1? "LWM_DS_TotalAndPerCell".Translate(maxNumberStacks * size, maxNumberStacks) :maxNumberStacks.ToString(), 10 /*display priority*/, "LWM_DS_maxNumStacksDesc".Translate())); if (maxTotalMass > 0f) { yield return(new StatDrawEntry(DeepStorageCategory, "LWM_DS_maxTotalMass".Translate(), size > 1? "LWM_DS_TotalAndPerCell".Translate(kg(maxTotalMass * size), kg(maxTotalMass)) :kg(maxTotalMass), 9, "LWM_DS_maxTotalMassDesc".Translate())); } if (maxMassOfStoredItem > 0f) { yield return(new StatDrawEntry(DeepStorageCategory, "LWM_DS_maxMassOfStoredItem".Translate(), kg(maxMassOfStoredItem), 8, "LWM_DS_maxMassOfStoredItemDesc".Translate())); } if (AllowedCategoriesString != "") { yield return(new StatDrawEntry(DeepStorageCategory, "LWM_DS_allowedCategories".Translate(), AllowedCategoriesString, 7, "LWM_DS_allowedCategoriesDesc".Translate())); } if (AllowedDefsString != "") { yield return(new StatDrawEntry(DeepStorageCategory, "LWM_DS_allowedDefs".Translate(), AllowedDefsString, 6, "LWM_DS_allowedDefsDesc".Translate())); } if (DisallowedString != "") { yield return(new StatDrawEntry(DeepStorageCategory, "LWM_DS_disallowedStuff".Translate(), DisallowedString, 5, "LWM_DS_disallowedStuffDesc".Translate())); } // if (parent?.building?.fixedStorageSettings?.filter yield break; }
private static bool ShowForPawn(StatDef statDef) { StatCategoryDef category = statDef.category; return(category == StatCategoryDefOf.PawnCombat || category == StatCategoryDefOf.PawnMisc || category == StatCategoryDefOf.PawnSocial || category == StatCategoryDefOf.PawnWork); }
public StatDrawEntry(StatCategoryDef category, string label, string valueString, int displayPriorityWithinCategory = 0) { this.category = category; this.stat = null; this.labelInt = label; this.value = 0f; this.valueStringInt = valueString; this.displayOrderWithinCategory = displayPriorityWithinCategory; this.numberSense = ToStringNumberSense.Absolute; }
public static void Thing_PostfixSpecialDisplayStats(Thing __instance, ref IEnumerable <StatDrawEntry> __result) { if (Traverse.Create(__instance.def).Field("verbs").GetValue() is List <VerbProperties> verbs) { VerbProperties verb = verbs.First(x => x.isPrimary); if (verb.LaunchesProjectile && verb.defaultProjectile is ThingDef dP && dP.projectile is ProjectileProperties p) { StatCategoryDef c = (__instance.def.category != ThingCategory.Pawn) ? StatCategoryDefOf.Weapon : StatCategoryDefOf.PawnCombat; string vS = GetAdjustedStoppingPower(p.StoppingPower, __instance).ToString("F2"); string oRT = "StoppingPowerExplanation".Translate(); __result = __result.Add(new StatDrawEntry(c, "StoppingPower".Translate(), vS, overrideReportText: oRT)); } } }
public StatDrawEntry CreateStacklimitStatEntry(ThingDef thingDef, int displayPriority) { StatCategoryDef stockingCat = StockingStatCategoryDefOf.Stocking; int overstackLimit = (int)((float)thingDef.stackLimit * OverstackLimitPerOverlay); int overlays = InRackMode ? OverlayLimit : 1; float allowedMassPerThing = MaxStockWeight / overlays; int massLimit = (int)(allowedMassPerThing / StockingUtility.cachedThingDefMasses[thingDef]); return(new StatDrawEntry(stockingCat, "StackLimitStat.Label".Translate(thingDef.label) , stackLimits[thingDef] + "/" + maxStackLimits[thingDef].ToString() , displayPriority, "MaxStackLimitStat.Text" .Translate(thingDef.label, thingDef.stackLimit, OverstackLimitPerOverlay, overstackLimit , allowedMassPerThing, massLimit, maxStackLimits[thingDef]))); }
// FIXME: Icons on the affix hyperlinks public override IEnumerable <StatDrawEntry> SpecialDisplayStats() { StatCategoryDef category = parent.def.IsApparel ? StatCategoryDefOf.Apparel : parent.def.IsWeapon ? StatCategoryDefOf.Weapon : StatCategoryDefOf.BasicsImportant ; string reportText = "RimLoot_LootAffixDescription".Translate() + "\n\n"; var affixDict = AllAffixDefsByAffixes; foreach (string affixKey in AffixStrings) { LootAffixDef affix = affixDict[affixKey]; reportText += affix.FullStatsReport(parent, affixKey) + "\n"; } if (Prefs.DevMode) { reportText += "[DEV] Affix Rules:\n " + string.Join("\n ", affixRules) + "\n\n"; reportText += "[DEV] Total Points: " + affixes.Select(lad => lad.GetRealAffixCost(parent)).Sum() + "\n " + string.Join("\n ", affixes.Select(lad => AllAffixesByAffixDefs[lad] + ": " + lad.GetRealAffixCost(parent))) + "\n\n" ; } yield return(new StatDrawEntry( category: category, label: "RimLoot_LootAffixModifiers".Translate(), valueString: GenText.ToCommaList( AllAffixDefsByAffixes.Select(kv => kv.Value.LabelWithStyle(parent, kv.Key)), false ), reportText: reportText, hyperlinks: affixes.SelectMany(lad => lad.GetHyperlinks(parent)), displayPriorityWithinCategory: 1 )); // Add any additional entries from the defs or modifiers foreach (string affixKey in AffixStrings) { LootAffixDef affix = affixDict[affixKey]; foreach (var statDrawEntry in affix.SpecialDisplayStatsForThing(parent, affixKey)) { yield return(statDrawEntry); } } }
public StatDrawEntry(StatCategoryDef category, StatDef stat, float value, StatRequest optionalReq, ToStringNumberSense numberSense = ToStringNumberSense.Undefined) { this.category = category; this.stat = stat; this.labelInt = null; this.value = value; this.valueStringInt = null; this.displayOrderWithinCategory = 0; this.optionalReq = optionalReq; this.hasOptionalReq = true; if (numberSense == ToStringNumberSense.Undefined) { this.numberSense = stat.toStringNumberSense; } else { this.numberSense = numberSense; } }
public override IEnumerable <string> ConfigErrors(LootAffixDef parentDef) { foreach (string configError in base.ConfigErrors(parentDef)) { yield return(configError); } StatCategoryDef category = affectedStat.category; List <StatCategoryDef> acceptableCategories = new List <StatCategoryDef>() { StatCategoryDefOf.Basics, StatCategoryDefOf.BasicsImportant, StatCategoryDefOf.BasicsNonPawn, StatCategoryDefOf.BasicsPawn, StatCategoryDefOf.BasicsPawnImportant, StatCategoryDefOf.PawnCombat, StatCategoryDefOf.PawnMisc, StatCategoryDefOf.PawnSocial, StatCategoryDefOf.PawnWork, }; if (!acceptableCategories.Contains(category)) { yield return("The affectedStat isn't in the typical stat categories: " + category); } }
static AnimalGeneticsAssemblyLoader() { var h = new Harmony("AnimalGenetics"); h.PatchAll(); DefDatabase <StatDef> .Add(AnimalGenetics.Damage); DefDatabase <StatDef> .Add(AnimalGenetics.Health); DefDatabase <StatDef> .Add(AnimalGenetics.GatherYield); var affectedStats = Constants.affectedStatsToInsert; foreach (var stat in affectedStats) { try { stat.parts?.Insert(0, new StatPart(stat)); } catch { Log.Error(stat + " is broken"); } } var category = new StatCategoryDef { defName = "AnimalGenetics_Category", label = "Genetics", displayAllByDefault = true, displayOrder = 200 }; DefDatabase <StatCategoryDef> .Add(category); foreach (var stat in Constants.affectedStats) { DefDatabase <StatDef> .Add(new StatDefWrapper { defName = "AnimalGenetics_" + stat.defName, label = Constants.GetLabel(stat), Underlying = stat, category = category, workerClass = typeof(StatWorker), toStringStyle = ToStringStyle.PercentZero }); } StatDefOf.MarketValue.parts.Add(new MarketValueCalculator()); gatherableTypes = new List <Type>() { typeof(CompShearable), typeof(CompMilkable) }; // Compatibility patches try { if (LoadedModManager.RunningModsListForReading.Any(x => x.PackageId == "sarg.alphaanimals" || x.Name == "Alpha Animals")) { Log.Message("Animal Genetics : Alpha Animals is loaded - Patching"); h.Patch(AccessTools.Method(AccessTools.TypeByName("AlphaBehavioursAndEvents.CompAnimalProduct"), "get_ResourceAmount"), postfix: new HarmonyMethod(typeof(CompatibilityPatches), nameof(CompatibilityPatches.AlphaAnimals_get_ResourceAmount_Patch))); gatherableTypes.Add(AccessTools.TypeByName("AlphaBehavioursAndEvents.CompAnimalProduct")); } if (LoadedModManager.RunningModsListForReading.Any(x => x.PackageId == "CETeam.CombatExtended" || x.Name == "Combat Extended")) { //gatherableTypes.Append(AccessTools.TypeByName("CombatExtended.CompMilkableRenameable")); //they all use shearable gatherableTypes.Add(AccessTools.TypeByName("CombatExtended.CompShearableRenameable")); } if (LoadedModManager.RunningModsListForReading.Any(x => x.PackageId == "rim.job.world")) { Log.Message("Patched RJW"); h.Patch(AccessTools.Method(AccessTools.TypeByName("rjw.Hediff_BasePregnancy"), "GenerateBabies"), prefix: new HarmonyMethod(typeof(CompatibilityPatches), nameof(CompatibilityPatches.RJW_GenerateBabies_Prefix)), postfix: new HarmonyMethod(typeof(CompatibilityPatches), nameof(CompatibilityPatches.RJW_GenerateBabies_Postfix))); } } catch { } if (ColonyManager.ModRunning && Settings.Integration.ColonyManagerIntegration) { ColonyManager.Patch(h); } _DefaultAnimalsPawnTableDefColumns = new List <PawnColumnDef>(PawnTableDefOf.Animals.columns); _DefaultWildlifePawnTableDefColumns = new List <PawnColumnDef>(PawnTableDefOf.Wildlife.columns); var placeholderPosition = MainTabWindow_AnimalGenetics.PawnTableDefs.Genetics.columns.FindIndex(def => def.defName == "AnimalGenetics_Placeholder"); MainTabWindow_AnimalGenetics.PawnTableDefs.Genetics.columns.RemoveAt(placeholderPosition); MainTabWindow_AnimalGenetics.PawnTableDefs.Genetics.columns.InsertRange(placeholderPosition, PawnTableColumnsDefOf.Genetics.columns); PatchUI(); }
public static IEnumerable <StatDrawEntry> SpecialDisplayStats(HediffDef hediff, StatRequest req) { category = DefDatabase <StatCategoryDef> .GetNamed("Basics"); yield return(HediffCategoryStat(hediff)); if (hediff.isBad) { yield return(new StatDrawEntry( category: category, label: "Stat_Hediff_Tendable_Name".Translate(), reportText: "Stat_Hediff_Tendable_Desc".Translate(), valueString: hediff.tendable.ToStringYesNo(), displayPriorityWithinCategory: 4975 )); yield return(new StatDrawEntry( category: category, label: "Stat_Hediff_Immunizable_Name".Translate(), reportText: "Stat_Hediff_Immunizable_Desc".Translate(), valueString: hediff.PossibleToDevelopImmunityNaturally().ToStringYesNo(), displayPriorityWithinCategory: 4970 )); bool canBeLethal = hediff.lethalSeverity > 0 || (hediff.stages != null && hediff.stages.Any(s => s.lifeThreatening)); yield return(new StatDrawEntry( category: category, label: "Stat_Hediff_Lethal_Name".Translate(), reportText: "Stat_Hediff_Lethal_Desc".Translate(), valueString: canBeLethal.ToStringYesNo(), displayPriorityWithinCategory: 4965 )); } if (hediff.addedPartProps != null) { StatCategoryDef implantCategory = DefDatabase <StatCategoryDef> .GetNamed("Implant"); var props = hediff.addedPartProps; if (hediff.spawnThingOnRemoved != null) { yield return(new StatDrawEntry( category: implantCategory, label: "Stat_Hediff_RelatedPart_Name".Translate(), reportText: "Stat_Hediff_RelatedPart_Desc".Translate(), valueString: hediff.spawnThingOnRemoved.LabelCap, hyperlinks: new[] { new Dialog_InfoCard.Hyperlink(hediff.spawnThingOnRemoved) }, displayPriorityWithinCategory: 5000 )); } yield return(new StatDrawEntry( category: implantCategory, label: "PartEfficiency".Translate(), reportText: "Stat_Thing_BodyPartEfficiency_Desc".Translate(), valueString: props.partEfficiency.ToStringPercent(), displayPriorityWithinCategory: 4950 )); yield return(new StatDrawEntry( category: implantCategory, label: "Stat_Hediff_BetterThanNatural_Name".Translate(), reportText: "Stat_Hediff_BetterThanNatural_Desc".Translate(), valueString: props.betterThanNatural.ToStringYesNo(), displayPriorityWithinCategory: 4920 )); yield return(new StatDrawEntry( category: implantCategory, label: "Stat_Hediff_Solid_Name".Translate(), reportText: "Stat_Hediff_Solid_Desc".Translate(), valueString: props.solid.ToStringYesNo(), displayPriorityWithinCategory: 4900 )); } if (hediff.priceImpact || hediff.priceOffset != 0) { float priceOffset = hediff.priceOffset; if (priceOffset == 0 && hediff.spawnThingOnRemoved != null) { priceOffset = hediff.spawnThingOnRemoved.BaseMarketValue; } if (priceOffset >= 1.0 || priceOffset <= -1.0) { yield return(new StatDrawEntry( category: category, label: "Stat_Hediff_PriceOffset_Name".Translate(), reportText: "Stat_Hediff_PriceOffset_Desc".Translate(), valueString: priceOffset.ToStringMoneyOffset(), displayPriorityWithinCategory: 5500 )); } } }
public static IEnumerable <StatDrawEntry> SpecialDisplayStats(BodyPartDef bodyPart, StatRequest req) { category = DefDatabase <StatCategoryDef> .GetNamed("Basics"); yield return(new StatDrawEntry( category: category, label: "HitPointsBasic".Translate(), reportText: "Stat_HitPoints_Desc".Translate(), valueString: bodyPart.hitPoints.ToString(), displayPriorityWithinCategory: StatDisplayOrder.HitPointsBasic )); if (bodyPart.spawnThingOnRemoved != null) { yield return(new StatDrawEntry( category: category, label: "Stat_BodyPart_RemovedPart_Name".Translate(), reportText: "Stat_BodyPart_RemovedPart_Desc".Translate(), valueString: bodyPart.spawnThingOnRemoved.LabelCap, hyperlinks: new[] { new Dialog_InfoCard.Hyperlink(bodyPart.spawnThingOnRemoved) }, displayPriorityWithinCategory: 5000 )); } string permanentInjuryChanceFactorString = bodyPart.permanentInjuryChanceFactor > 10000 ? "Infinite".Translate().ToString() : bodyPart.permanentInjuryChanceFactor.ToStringPercent() ; yield return(new StatDrawEntry( category: category, label: "Stat_BodyPart_PermanentInjuryChanceFactor_Name".Translate(), reportText: "Stat_BodyPart_PermanentInjuryChanceFactor_Desc".Translate(), valueString: permanentInjuryChanceFactorString, displayPriorityWithinCategory: 4890 )); yield return(new StatDrawEntry( category: category, label: "Stat_BodyPart_BleedRate_Name".Translate(), reportText: "Stat_BodyPart_BleedRate_Desc".Translate(), valueString: bodyPart.bleedRate.ToStringPercent(), displayPriorityWithinCategory: 4880 )); yield return(new StatDrawEntry( category: category, label: "Stat_BodyPart_FrostbiteVulnerability_Name".Translate(), reportText: "Stat_BodyPart_FrostbiteVulnerability_Desc".Translate(), valueString: bodyPart.frostbiteVulnerability.ToStringPercent(), hyperlinks: new[] { new Dialog_InfoCard.Hyperlink(DefDatabase <HediffDef> .GetNamed("Frostbite")) }, displayPriorityWithinCategory: 4870 )); yield return(new StatDrawEntry( category: category, label: "Stat_BodyPart_Vital_Name".Translate(), reportText: "Stat_BodyPart_Vital_Desc".Translate(), valueString: bodyPart.tags.Any(bptd => bptd.vital).ToStringYesNo(), displayPriorityWithinCategory: 4795 )); yield return(new StatDrawEntry( category: category, label: "Stat_BodyPart_Alive_Name".Translate(), reportText: "Stat_BodyPart_Alive_Desc".Translate(), valueString: bodyPart.alive.ToStringYesNo(), displayPriorityWithinCategory: 4790 )); yield return(new StatDrawEntry( category: category, label: "Stat_BodyPart_SkinCovered_Name".Translate(), reportText: "Stat_BodyPart_SkinCovered_Desc".Translate(), valueString: bodyPart.IsSkinCoveredInDefinition_Debug.ToStringYesNo(), // they really don't want you to use this property... displayPriorityWithinCategory: 4780 )); yield return(new StatDrawEntry( category: category, label: "Stat_BodyPart_Solid_Name".Translate(), reportText: "Stat_BodyPart_Solid_Desc".Translate(), valueString: bodyPart.IsSolidInDefinition_Debug.ToStringYesNo(), // they really don't want you to use this property... displayPriorityWithinCategory: 4770 )); yield return(new StatDrawEntry( category: category, label: "Stat_BodyPart_Invulnerable_Name".Translate(), reportText: "Stat_BodyPart_Invulnerable_Desc".Translate(), valueString: (!bodyPart.destroyableByDamage).ToStringYesNo(), displayPriorityWithinCategory: 4765 )); yield return(new StatDrawEntry( category: category, label: "Stat_BodyPart_Delicate_Name".Translate(), reportText: "Stat_BodyPart_Delicate_Desc".Translate(), valueString: bodyPart.delicate.ToStringYesNo(), displayPriorityWithinCategory: 4760 )); yield return(new StatDrawEntry( category: category, label: "Stat_BodyPart_BeautyRelated_Name".Translate(), reportText: "Stat_BodyPart_BeautyRelated_Desc".Translate(), valueString: bodyPart.delicate.ToStringYesNo(), displayPriorityWithinCategory: 4750 )); yield return(new StatDrawEntry( category: category, label: "Stat_BodyPart_Amputatable_Name".Translate(), reportText: "Stat_BodyPart_Amputatable_Desc".Translate(), valueString: bodyPart.canSuggestAmputation.ToStringYesNo(), displayPriorityWithinCategory: 4690 )); string bodyPartProperties = string.Join("\n", bodyPart.tags.Select(bptd => { string tagLangKey = "Stat_BodyPart_BodyPartProperties_" + bptd.defName; string backupText = GenText.SplitCamelCase(bptd.defName); // See big comment on SurgeryCategoryStat return(tagLangKey.CanTranslate() ? tagLangKey.Translate() : backupText.Translate()); }) ); if (!bodyPartProperties.NullOrEmpty()) { yield return(new StatDrawEntry( category: category, label: "Stat_BodyPart_BodyPartProperties_Name".Translate(), reportText: "Stat_BodyPart_BodyPartProperties_Desc".Translate(), valueString: bodyPartProperties, displayPriorityWithinCategory: 4500 )); } List <Dialog_InfoCard.Hyperlink> bodyPartUsersHyperlinks = DefDatabase <PawnKindDef> .AllDefs. Where(pkd => pkd.race?.race != null). Select(pkd => pkd.race).Distinct(). Where(race => race.race.body.AllParts.Any(bpr => bpr.def == bodyPart)). Select(race => new Dialog_InfoCard.Hyperlink(race)). ToList() ; yield return(new StatDrawEntry( category: category, label: "Stat_BodyPart_BodyPartUsers_Name".Translate(), reportText: "Stat_BodyPart_BodyPartUsers_Desc".Translate(), valueString: "VariousLabel".Translate(), hyperlinks: bodyPartUsersHyperlinks, displayPriorityWithinCategory: 4200 )); }
// TODO: Document ThoughtDefs public static StatDrawEntry FindHediffRisks(HediffDef hediff, string labelKey, StatCategoryDef category, int displayOffset = 0) { var riskKeys = new List <string> { }; var riskReports = new List <string> { }; riskReports.Add(("Stat_Thing_Drug_" + labelKey + "_Desc").Translate()); var hyperlinks = new List <Dialog_InfoCard.Hyperlink> { new Dialog_InfoCard.Hyperlink(hediff) }; if (!hediff.everCurableByItem) { string incurable = "Incurable".Translate(); riskKeys.Add(incurable); riskReports.Add(incurable); } if (hediff.stages != null) { foreach (HediffStage stage in hediff.stages) { if (hediff.stages.Count > 1 && (stage.label.NullOrEmpty() || !stage.becomeVisible)) { continue; } string label = stage.label.NullOrEmpty() ? hediff.label : stage.label; label = label.CapitalizeFirst(); string report = ""; // keep it empty to check later List <StatDrawEntry> statDrawEntries = stage.SpecialDisplayStats().ToList(); foreach (StatDrawEntry statDrawEntry in statDrawEntries.OrderBy(sde => sde.DisplayPriorityWithinCategory)) { report += " " + statDrawEntry.LabelCap + ": " + statDrawEntry.ValueString + "\n"; } // Other stats not reported from stage.SpecialDisplayStats() if (stage.vomitMtbDays > 0) { report += " " + "Stat_MTBVomit".Translate() + ": " + ToStringDaysToPeriod(stage.vomitMtbDays) + "\n"; } if (stage.forgetMemoryThoughtMtbDays > 0) { report += " " + "Stat_MTBForget".Translate() + ": " + ToStringDaysToPeriod(stage.forgetMemoryThoughtMtbDays) + "\n"; } if (stage.mentalBreakMtbDays > 0) { report += " " + "Stat_MTBMentalBreak".Translate() + ": " + ToStringDaysToPeriod(stage.mentalBreakMtbDays) + "\n"; } if (stage.deathMtbDays > 0) { report += " " + "Stat_MTBDeath".Translate() + ": " + ToStringDaysToPeriod(stage.deathMtbDays) + "\n"; } if (!stage.hediffGivers.NullOrEmpty()) { foreach (HediffGiver hediffGiver in stage.hediffGivers) { report += " " + ReadHediffGiver(hediffGiver) + "\n"; } } if (report.NullOrEmpty()) { continue; } report = label + ":\n" + report.Trim('\n'); riskKeys.Add(label); riskReports.Add(report); } } // Report on thoughts tied to the hediff string thoughtsReport = ""; // keep it empty to check later foreach (ThoughtDef thought in DefDatabase <ThoughtDef> .AllDefs.Where(td => td.hediff == hediff)) { foreach (ThoughtStage stage in thought.stages) { if (thought.stages.Count > 1 && (stage.label.NullOrEmpty() || !stage.visible)) { continue; } string label = stage.label.NullOrEmpty() ? (string)thought.LabelCap : stage.LabelCap; var effects = new List <string> { }; if (stage.baseMoodEffect != 0) { effects.Add("Stat_Thought_MoodEffect".Translate(((int)stage.baseMoodEffect).ToStringWithSign())); } if (stage.baseOpinionOffset != 0) { effects.Add("Stat_Thought_OpinionOffset".Translate(((int)stage.baseOpinionOffset).ToStringWithSign())); } thoughtsReport += " " + label + ": " + GenText.ToCommaList(effects) + "\n"; } } if (!thoughtsReport.NullOrEmpty()) { riskKeys.Add("Thoughts".Translate()); thoughtsReport = "Thoughts".Translate() + ":\n" + thoughtsReport.Trim('\n'); riskReports.Add(thoughtsReport); } if (!hediff.hediffGivers.NullOrEmpty()) { string report = ""; foreach (HediffGiver hediffGiver in hediff.hediffGivers) { report += ReadHediffGiver(hediffGiver) + "\n"; riskKeys.Add(hediffGiver.hediff.LabelCap); } riskReports.Add(report.Trim('\n')); } if (hediff.lethalSeverity >= 0) { riskKeys.Add("Fatal".Translate()); riskReports.Add("Stat_FatalAt".Translate(hediff.lethalSeverity.ToStringPercent())); } return(new StatDrawEntry( category: category, label: ("Stat_Thing_Drug_" + labelKey + "_Name").Translate(), reportText: string.Join("\n\n", riskReports), valueString: riskKeys.Count == 0 ? (string)"None".Translate() : GenText.ToCommaList(riskKeys), hyperlinks: hyperlinks, displayPriorityWithinCategory: displayOffset + 50 )); }
public static void ProductionInfo(ref IEnumerable <StatDrawEntry> __result, RaceProperties __instance, ThingDef parentDef, StatRequest req) { if (!Settings.extra_display_stats) { return; } // Create a modifyable list List <StatDrawEntry> NewList = new List <StatDrawEntry>(); // copy vanilla entries into the new list // since original method returns enumerator instead of collection, to actually get values iterator should be iterated; also this method should not be used for enumerators that change condition when called - it may be bad a idea for work givers / drivers foreach (StatDrawEntry entry in __result) { NewList.Add(entry); } int startOrder = 2150; StatCategoryDef StatCategory = StatCategoryDefOf.PawnMisc; Pawn pawn = null; if (req.HasThing && req.Thing is Pawn) { pawn = (req.Thing as Pawn); } if (pawn == null) { return; } foreach (ThingComp comp in pawn.AllComps) { CompProperties c = comp.props; if (c is CompProperties_Shearable shearable) { NewList.Add(new StatDrawEntry(StatCategory, "WoolType".Translate(), shearable.woolDef.LabelCap, "Stat_Race_WoolType_Desc".Translate(), startOrder--, null, new Dialog_InfoCard.Hyperlink[1] { new Dialog_InfoCard.Hyperlink(shearable.woolDef) })); TaggedString woolStat = shearable.woolAmount + " / " + string.Format("{0:0.#}", shearable.shearIntervalDays) + "LetterDay".Translate(); if (shearable.shearIntervalDays != 1) { woolStat += " (" + string.Format("{0:0.#}", shearable.woolAmount / shearable.shearIntervalDays) + "/" + "LetterDay".Translate() + ")"; } NewList.Add(new StatDrawEntry(StatCategory, "WoolAmount".Translate(), woolStat, "Stat_Race_WoolAmount_Desc".Translate(), startOrder--)); } else if (c is CompProperties_Milkable milkable) { NewList.Add(new StatDrawEntry(StatCategory, "MilkType".Translate(), milkable.milkDef.LabelCap, "Stat_Race_MilkType_Desc".Translate(), startOrder--, null, new Dialog_InfoCard.Hyperlink[1] { new Dialog_InfoCard.Hyperlink(milkable.milkDef) })); String milkStat = milkable.milkAmount + " / " + string.Format("{0:0.#}", milkable.milkIntervalDays) + "LetterDay".Translate(); if (milkable.milkIntervalDays != 1) { milkStat += " (" + string.Format("{0:0.#}", milkable.milkAmount / milkable.milkIntervalDays) + "/" + "LetterDay".Translate() + ")"; } NewList.Add(new StatDrawEntry(StatCategory, "MilkAmount".Translate(), milkStat, "Stat_Race_MilkAmount_Desc".Translate(), startOrder--)); NewList.Add(new StatDrawEntry(StatCategory, "MilkFemale".Translate(), milkable.milkFemaleOnly ? "Yes".Translate() : "No".Translate(), "MilkFemaleExplanation".Translate(), startOrder--)); } // catch all for custom comps based on CompHasGatherableBodyResource abstract else if (comp is CompHasGatherableBodyResource resource) { ThingDef ResourceDef = (ThingDef)AccessTools.Method(comp.GetType(), "get_ResourceDef").Invoke(resource, null); Log.Warning("AL: resource " + ResourceDef); if (ResourceDef == null) { Log.Warning("Animals Logic: " + parentDef.defName + " has a custom comp for body resources but no resource def."); continue; } NewList.Add(new StatDrawEntry(StatCategory, "AL_ResourceType".Translate(), ResourceDef.LabelCap, "AL_ResourceType_Desc".Translate(), startOrder--, null, new Dialog_InfoCard.Hyperlink[1] { new Dialog_InfoCard.Hyperlink(ResourceDef) })); int ResourceAmount = (int)AccessTools.Method(comp.GetType(), "get_ResourceAmount").Invoke(resource, null); int GatherResourcesIntervalDays = (int)AccessTools.Method(comp.GetType(), "get_GatherResourcesIntervalDays").Invoke(resource, null); String resourceStat = ResourceAmount + " / " + string.Format("{0:0.#}", GatherResourcesIntervalDays) + "LetterDay".Translate(); if (GatherResourcesIntervalDays != 1) { resourceStat += " (" + string.Format("{0:0.#}", ResourceAmount / GatherResourcesIntervalDays) + "/" + "LetterDay".Translate() + ")"; } NewList.Add(new StatDrawEntry(StatCategory, "AL_ResourceAmount".Translate(), resourceStat, "AL_ResourceAmount_Desc".Translate(), startOrder--)); } if (c is CompProperties_EggLayer layer) { List <Dialog_InfoCard.Hyperlink> hyperlinks = new List <Dialog_InfoCard.Hyperlink> { new Dialog_InfoCard.Hyperlink(layer.eggFertilizedDef) }; if (layer.eggUnfertilizedDef != null && layer.eggUnfertilizedDef != layer.eggFertilizedDef) { hyperlinks.Add(new Dialog_InfoCard.Hyperlink(layer.eggUnfertilizedDef)); } NewList.Add(new StatDrawEntry(StatCategory, "EggType".Translate(), layer.eggFertilizedDef.LabelCap, "Stat_Race_EggType_Desc".Translate(), startOrder--, null, hyperlinks)); TaggedString eggsStat = (layer.eggCountRange.min == layer.eggCountRange.max ? layer.eggCountRange.max.ToString() : layer.eggCountRange.ToString()) + " / " + string.Format("{0:0.#}", layer.eggLayIntervalDays) + "LetterDay".Translate(); if (layer.eggLayIntervalDays != 1 || layer.eggCountRange.min != layer.eggCountRange.max) { eggsStat += " (" + string.Format("{0:0.#}", layer.eggCountRange.Average / layer.eggLayIntervalDays) + "/" + "LetterDay".Translate() + ")"; } NewList.Add(new StatDrawEntry(StatCategory, "EggAmount".Translate(), eggsStat, "Stat_Race_EggAmount_Desc".Translate(), startOrder--)); NewList.Add(new StatDrawEntry(StatCategory, "EggFemale".Translate(), layer.eggLayFemaleOnly ? "Yes".Translate() : "No".Translate(), "EggFemaleExplanation".Translate(), startOrder--)); NewList.Add(new StatDrawEntry(StatCategory, "EggNeedFertilization".Translate(), layer.eggProgressUnfertilizedMax < 1 ? "Yes".Translate() : "No".Translate(), "EggNeedFertilizationExplanation".Translate(), startOrder--)); CompProperties_Hatcher hatcher = layer.eggFertilizedDef.GetCompProperties <CompProperties_Hatcher>(); if (hatcher != null) { NewList.Add(new StatDrawEntry(StatCategory, "EggIncubation".Translate(), hatcher.hatcherDaystoHatch + "LetterDay".Translate(), "EggIncubationExplanation".Translate(), startOrder--)); } } } // TODO: break it down into explanation of each stage if (!__instance.lifeStageAges.NullOrEmpty()) { LifeStageAge matureAge = __instance.lifeStageAges.FirstOrFallback( p => p.def.reproductive || p.def.milkable || p.def.shearable, __instance.lifeStageAges.Last() ); if (matureAge != null) { float age = matureAge.minAge; // contains number of years as float int years = (int)age; age %= 1.0f; // now contains number of years that is less than 1 int days = (int)(age * 60); age = (age * 60) % 1.0f; // now contains number of days that is less than 1 int hours = (int)age * 24; String matureAgeString = ""; // unused now String matureAgeStringShort = ""; if (years > 1) { matureAgeString += "PeriodYears".Translate(years); matureAgeStringShort += years + "LetterYear".Translate(); } if (years == 1) { matureAgeString += "Period1Year".Translate(); matureAgeStringShort += 1 + "LetterYear".Translate(); } if (days > 1) { if (years > 0) { matureAgeString += " "; matureAgeStringShort += " "; } matureAgeString += "PeriodDays".Translate(days); matureAgeStringShort += days + "LetterDay".Translate(); } if (days == 1) { if (years > 0) { matureAgeString += " "; matureAgeStringShort += " "; } matureAgeString += "Period1Day".Translate(); matureAgeStringShort += 1 + "LetterDay".Translate(); } if (hours > 1) { if (years + hours > 0) { matureAgeString += " "; matureAgeStringShort += " "; } matureAgeString += "PeriodHours".Translate(hours); matureAgeStringShort += hours + "LetterHour".Translate(); } if (hours == 1) { if (years + hours > 0) { matureAgeString += " "; matureAgeStringShort += " "; } matureAgeString += "Period1Hour".Translate(); matureAgeStringShort += 1 + "LetterHour".Translate(); } NewList.Add(new StatDrawEntry(StatCategory, "TimeToMature".Translate(), matureAgeStringShort, "TimeToMatureExplanation".Translate(), startOrder--)); } LifeStageAge reproductiveAge = __instance.lifeStageAges.Find( p => p.def.reproductive ); if (__instance.hasGenders && reproductiveAge != null && !parentDef.HasComp(typeof(CompEggLayer))) { NewList.Add(new StatDrawEntry(StatCategory, "GestationPeriod".Translate(), String.Format("{0:0.#}", __instance.gestationPeriodDays) + "LetterDay".Translate(), "GestationPeriodExplanation".Translate(), startOrder--)); float litterAvg = 1f; String litterSize = "1"; if (__instance.litterSizeCurve != null && Math.Max(1, __instance.litterSizeCurve.First().x) != Math.Max(1, __instance.litterSizeCurve.Last().x)) { litterAvg = Rand.ByCurveAverage(__instance.litterSizeCurve); litterAvg = Math.Max(1, litterAvg); litterSize = Math.Max(1, __instance.litterSizeCurve.First().x) + "~" + Math.Max(1, __instance.litterSizeCurve.Last().x) + " (" + String.Format("{0:0.#}", litterAvg) + ")"; } NewList.Add(new StatDrawEntry(StatCategory, "LitterSize".Translate(), litterSize, "LitterSizeExplanation".Translate(), startOrder--)); } } // convert list to IEnumerable to match the caller's expectations IEnumerable <StatDrawEntry> output = NewList; // make caller use the list __result = output; }
public override IEnumerable <StatDrawEntry> SpecialDisplayStats() { if (this.apparel != null) { string coveredParts = this.apparel.GetCoveredOuterPartsString(BodyDefOf.Human); yield return(new StatDrawEntry(StatCategoryDefOf.Apparel, "Covers".Translate(), coveredParts, 100, string.Empty)); } if (this.IsMedicine && this.MedicineTendXpGainFactor != 1f) { yield return(new StatDrawEntry(StatCategoryDefOf.Basics, "MedicineXpGainFactor".Translate(), this.MedicineTendXpGainFactor.ToStringPercent(), 0, string.Empty)); } if (this.fillPercent > 0f && this.fillPercent < 1f && (this.category == ThingCategory.Item || this.category == ThingCategory.Building || this.category == ThingCategory.Plant)) { yield return(new StatDrawEntry(StatCategoryDefOf.Basics, "CoverEffectiveness".Translate(), this.BaseBlockChance().ToStringPercent(), 0, string.Empty) { overrideReportText = "CoverEffectivenessExplanation".Translate() }); } if (this.constructionSkillPrerequisite > 0) { StatCategoryDef basics = StatCategoryDefOf.Basics; string label = "ConstructionSkillRequired".Translate(); string valueString = this.constructionSkillPrerequisite.ToString(); string overrideReportText = "ConstructionSkillRequiredExplanation".Translate(); yield return(new StatDrawEntry(basics, label, valueString, 0, overrideReportText)); } if (!this.verbs.NullOrEmpty <VerbProperties>()) { VerbProperties verb = (from x in this.verbs where x.isPrimary select x).First <VerbProperties>(); StatCategoryDef verbStatCategory = (this.category != ThingCategory.Pawn) ? (verbStatCategory = StatCategoryDefOf.Weapon) : (verbStatCategory = StatCategoryDefOf.PawnCombat); float warmup = verb.warmupTime; if (warmup > 0f) { string warmupLabel = (this.category != ThingCategory.Pawn) ? "WarmupTime".Translate() : "MeleeWarmupTime".Translate(); yield return(new StatDrawEntry(verbStatCategory, warmupLabel, warmup.ToString("0.##") + " s", 40, string.Empty)); } if (verb.defaultProjectile != null) { float dam = (float)verb.defaultProjectile.projectile.damageAmountBase; yield return(new StatDrawEntry(verbStatCategory, "Damage".Translate(), dam.ToString(), 50, string.Empty)); } if (verb.LaunchesProjectile) { int burstShotCount = verb.burstShotCount; float burstShotFireRate = 60f / verb.ticksBetweenBurstShots.TicksToSeconds(); float range = verb.range; if (burstShotCount > 1) { yield return(new StatDrawEntry(verbStatCategory, "BurstShotCount".Translate(), burstShotCount.ToString(), 20, string.Empty)); yield return(new StatDrawEntry(verbStatCategory, "BurstShotFireRate".Translate(), burstShotFireRate.ToString("0.##") + " rpm", 19, string.Empty)); } yield return(new StatDrawEntry(verbStatCategory, "Range".Translate(), range.ToString("0.##"), 10, string.Empty)); } } if (this.plant != null) { foreach (StatDrawEntry s in this.plant.SpecialDisplayStats()) { yield return(s); } } if (this.ingestible != null) { foreach (StatDrawEntry s2 in this.ingestible.SpecialDisplayStats(this)) { yield return(s2); } } if (this.race != null) { foreach (StatDrawEntry s3 in this.race.SpecialDisplayStats(this)) { yield return(s3); } } if (this.isBodyPartOrImplant) { foreach (RecipeDef def in from x in DefDatabase <RecipeDef> .AllDefs where x.IsIngredient(this.$this) select x) { HediffDef diff = def.addsHediff; if (diff != null) { if (diff.addedPartProps != null) { yield return(new StatDrawEntry(StatCategoryDefOf.Basics, "BodyPartEfficiency".Translate(), diff.addedPartProps.partEfficiency.ToStringByStyle(ToStringStyle.PercentZero, ToStringNumberSense.Absolute), 0, string.Empty)); } foreach (StatDrawEntry s4 in diff.SpecialDisplayStats()) { yield return(s4); } HediffCompProperties_VerbGiver vg = diff.CompProps <HediffCompProperties_VerbGiver>(); if (vg != null) { if (!vg.verbs.NullOrEmpty <VerbProperties>()) { VerbProperties verb2 = vg.verbs[0]; if (!verb2.MeleeRange) { if (verb2.defaultProjectile != null) { int projDamage = verb2.defaultProjectile.projectile.damageAmountBase; yield return(new StatDrawEntry(StatCategoryDefOf.Basics, "Damage".Translate(), projDamage.ToString(), 0, string.Empty)); } } else { int meleeDamage = verb2.meleeDamageBaseAmount; yield return(new StatDrawEntry(StatCategoryDefOf.Weapon, "Damage".Translate(), meleeDamage.ToString(), 0, string.Empty)); } } else if (!vg.tools.NullOrEmpty <Tool>()) { Tool tool = vg.tools[0]; yield return(new StatDrawEntry(StatCategoryDefOf.Weapon, "Damage".Translate(), tool.power.ToString(), 0, string.Empty)); } } ThoughtDef thought = DefDatabase <ThoughtDef> .AllDefs.FirstOrDefault((ThoughtDef x) => x.hediff == diff); if (thought != null && thought.stages != null && thought.stages.Any <ThoughtStage>()) { yield return(new StatDrawEntry(StatCategoryDefOf.Basics, "MoodChange".Translate(), thought.stages.First <ThoughtStage>().baseMoodEffect.ToStringByStyle(ToStringStyle.Integer, ToStringNumberSense.Offset), 0, string.Empty)); } } } } for (int i = 0; i < this.comps.Count; i++) { foreach (StatDrawEntry s5 in this.comps[i].SpecialDisplayStats()) { yield return(s5); } } }
public static IEnumerable <StatDrawEntry> SpecialDisplayStats(RecipeDef surgery, StatRequest req) { category = DefDatabase <StatCategoryDef> .GetNamed("Surgery"); yield return(SurgeryCategoryStat(surgery)); StatDrawEntry workerModStat = WorkerModStat(surgery); if (workerModStat != null) { yield return(workerModStat); } yield return(new StatDrawEntry( category: category, label: "Stat_Recipe_Surgery_Anesthetize_Name".Translate(), reportText: "Stat_Recipe_Surgery_Anesthetize_Desc".Translate(), valueString: surgery.anesthetize.ToStringYesNo(), hyperlinks: new[] { new Dialog_InfoCard.Hyperlink(HediffDefOf.Anesthetic) }, displayPriorityWithinCategory: 4950 )); if (!surgery.hideBodyPartNames) { yield return(AffectedBodyPartsStat(surgery)); } if (!surgery.incompatibleWithHediffTags.NullOrEmpty()) { yield return(IncompatibleWithHediffTagsStat(surgery)); } if (surgery.addsHediff != null) { yield return(new StatDrawEntry( category: category, label: "Stat_Recipe_Surgery_AddsHediff_Name".Translate(), reportText: "Stat_Recipe_Surgery_AddsHediff_Desc".Translate(), valueString: surgery.addsHediff.LabelCap, hyperlinks: new[] { new Dialog_InfoCard.Hyperlink(surgery.addsHediff) }, displayPriorityWithinCategory: 4859 )); } if (surgery.removesHediff != null) { yield return(new StatDrawEntry( category: category, label: "Stat_Recipe_Surgery_RemovesHediff_Name".Translate(), reportText: "Stat_Recipe_Surgery_RemovesHediff_Desc".Translate(), valueString: surgery.removesHediff.LabelCap, hyperlinks: new[] { new Dialog_InfoCard.Hyperlink(surgery.removesHediff) }, displayPriorityWithinCategory: 4858 )); } if (surgery.changesHediffLevel != null) { yield return(new StatDrawEntry( category: category, label: "Stat_Recipe_Surgery_ChangesHediffLevel_Name".Translate(), reportText: "Stat_Recipe_Surgery_ChangesHediffLevel_Desc".Translate(), valueString: surgery.changesHediffLevel.LabelCap, hyperlinks: new[] { new Dialog_InfoCard.Hyperlink(surgery.changesHediffLevel) }, displayPriorityWithinCategory: 4857 )); } }