From d974382de22626ac857c56a6e9a5b121bbcf14a2 Mon Sep 17 00:00:00 2001 From: "ProjectKoi-Kalo\\Kalo" Date: Fri, 22 Aug 2025 15:57:36 +0800 Subject: [PATCH 1/3] Chore: Untrack vector_cache files --- MCP/vector_cache/AbilityDef.txt | 621 --- .../AddHumanlikeOrders-FloatMenuMakerMap.txt | 519 --- MCP/vector_cache/BiosculpterPod-ThingDef.txt | 1502 ------ MCP/vector_cache/BiosculpterPod.txt | 74 - MCP/vector_cache/Building_Bed.txt | 1122 ----- ...bDefOf-JobDriver_CarryToBiosculpterPod.txt | 198 - .../ColonistBarColonistDrawer-DrawIcons.txt | 985 ---- ...lpterPod-CompProperties_BiosculpterPod.txt | 1485 ------ ...pterPod-WorkGiver_HaulToBiosculpterPod.txt | 91 - .../CompProperties_Refuelable.txt | 881 ---- MCP/vector_cache/CryptosleepCasket.txt | 267 -- MCP/vector_cache/HediffDef-Luciferium.txt | 118 - MCP/vector_cache/HediffDef-Malnutrition.txt | 750 --- MCP/vector_cache/Human-ThingDef.txt | 2691 ----------- .../HumanlikeAdult-LifeStageDef.txt | 134 - MCP/vector_cache/JobDef.txt | 115 - .../JobDefOf-JobDriver_TakeToBed-Rescue.txt | 827 ---- .../JobDriver_EnterCryptosleepCasket.txt | 70 - MCP/vector_cache/PawnKindDef-lifeStages.txt | 535 --- ...entoryTracker-get_FirstUnloadableThing.txt | 4149 ----------------- .../Projectile-TickInterval-Verse.txt | 655 --- MCP/vector_cache/PsychicRitualDef.txt | 871 ---- .../PsychicRitualDef_InvocationCircle.txt | 573 --- .../PsychicRitualToil_GatherForInvocation.txt | 103 - .../PsychicRitualToil_GatherOfferings.txt | 270 -- ...Source-StartCarryThing-Toil-Toils_Haul.txt | 1333 ------ MCP/vector_cache/StatDef.txt | 502 -- MCP/vector_cache/WorkGiver_Scanner.txt | 507 -- 28 files changed, 21948 deletions(-) delete mode 100644 MCP/vector_cache/AbilityDef.txt delete mode 100644 MCP/vector_cache/AddHumanlikeOrders-FloatMenuMakerMap.txt delete mode 100644 MCP/vector_cache/BiosculpterPod-ThingDef.txt delete mode 100644 MCP/vector_cache/BiosculpterPod.txt delete mode 100644 MCP/vector_cache/Building_Bed.txt delete mode 100644 MCP/vector_cache/CarryToBiosculpterPod-JobDefOf-JobDriver_CarryToBiosculpterPod.txt delete mode 100644 MCP/vector_cache/ColonistBarColonistDrawer-DrawIcons.txt delete mode 100644 MCP/vector_cache/CompBiosculpterPod-CompProperties_BiosculpterPod.txt delete mode 100644 MCP/vector_cache/CompBiosculpterPod-WorkGiver_HaulToBiosculpterPod.txt delete mode 100644 MCP/vector_cache/CompProperties_Refuelable.txt delete mode 100644 MCP/vector_cache/CryptosleepCasket.txt delete mode 100644 MCP/vector_cache/HediffDef-Luciferium.txt delete mode 100644 MCP/vector_cache/HediffDef-Malnutrition.txt delete mode 100644 MCP/vector_cache/Human-ThingDef.txt delete mode 100644 MCP/vector_cache/HumanlikeAdult-LifeStageDef.txt delete mode 100644 MCP/vector_cache/JobDef.txt delete mode 100644 MCP/vector_cache/JobDefOf-JobDriver_TakeToBed-Rescue.txt delete mode 100644 MCP/vector_cache/JobDriver_EnterCryptosleepCasket.txt delete mode 100644 MCP/vector_cache/PawnKindDef-lifeStages.txt delete mode 100644 MCP/vector_cache/Pawn_InventoryTracker-get_FirstUnloadableThing.txt delete mode 100644 MCP/vector_cache/Projectile-TickInterval-Verse.txt delete mode 100644 MCP/vector_cache/PsychicRitualDef.txt delete mode 100644 MCP/vector_cache/PsychicRitualDef_InvocationCircle.txt delete mode 100644 MCP/vector_cache/PsychicRitualToil_GatherForInvocation.txt delete mode 100644 MCP/vector_cache/PsychicRitualToil_GatherOfferings.txt delete mode 100644 MCP/vector_cache/Source-StartCarryThing-Toil-Toils_Haul.txt delete mode 100644 MCP/vector_cache/StatDef.txt delete mode 100644 MCP/vector_cache/WorkGiver_Scanner.txt diff --git a/MCP/vector_cache/AbilityDef.txt b/MCP/vector_cache/AbilityDef.txt deleted file mode 100644 index 08b7ce71..00000000 --- a/MCP/vector_cache/AbilityDef.txt +++ /dev/null @@ -1,621 +0,0 @@ -根据向量相似度分析,与 'AbilityDef' 最相关的代码定义如下: - ---- -**文件路径 (精确匹配):** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\AbilityDef.txt` - -```csharp -public class AbilityDef : Def -{ - public Type abilityClass = typeof(Ability); - - public Type gizmoClass = typeof(Command_Ability); - - public List comps = new List(); - - public AbilityCategoryDef category; - - public int displayOrder; - - public List statBases; - - public VerbProperties verbProperties; - - public KeyBindingDef hotKey; - - public JobDef jobDef; - - public ThingDef warmupMote; - - public EffecterDef warmupEffecter; - - public FleckDef emittedFleck; - - public int emissionInterval; - - public string warmupMoteSocialSymbol; - - public SoundDef warmupStartSound; - - public SoundDef warmupSound; - - public SoundDef warmupPreEndSound; - - public float warmupPreEndSoundSeconds; - - public Vector3 moteDrawOffset; - - public float moteOffsetAmountTowardsTarget; - - public bool canUseAoeToGetTargets = true; - - public bool useAverageTargetPositionForWarmupEffecter; - - public bool targetRequired = true; - - public bool targetWorldCell; - - public bool showGizmoOnWorldView; - - public bool aiCanUse; - - public bool ai_SearchAOEForTargets; - - public bool ai_IsOffensive = true; - - public bool ai_IsIncendiary = true; - - public bool groupAbility; - - public int level; - - public IntRange cooldownTicksRange; - - public bool cooldownPerCharge; - - public bool hasExternallyHandledCooldown; - - public int charges = -1; - - public AbilityGroupDef groupDef; - - public bool overrideGroupCooldown; - - public List requiredMemes; - - public bool sendLetterOnCooldownComplete; - - public bool sendMessageOnCooldownComplete; - - public bool displayGizmoWhileUndrafted; - - public bool disableGizmoWhileUndrafted = true; - - public bool writeCombatLog; - - public bool stunTargetWhileCasting; - - public bool showPsycastEffects = true; - - public bool showCastingProgressBar; - - public float detectionChanceOverride = -1f; - - public float uiOrder; - - public bool waitForJobEnd; - - public bool showWhenDrafted = true; - - public bool showOnCharacterCard = true; - - public bool hostile = true; - - public bool casterMustBeCapableOfViolence = true; - - [MustTranslate] - public string confirmationDialogText; - - [NoTranslate] - public string iconPath; - - public Texture2D uiIcon = BaseContent.BadTex; - - private string cachedTooltip; - - private Pawn cachedTooltipPawn; - - private List cachedTargets; - - private int requiredPsyfocusBandCached = -1; - - private bool? anyCompOverridesPsyfocusCost; - - private FloatRange psyfocusCostRange = new FloatRange(-1f, -1f); - - private string psyfocusCostPercent; - - private string psyfocusCostPercentMax; - - private Texture2D warmupMoteSocialSymbolCached; - - public float EntropyGain => statBases.GetStatValueFromList(StatDefOf.Ability_EntropyGain, 0f); - - public float PsyfocusCost => statBases.GetStatValueFromList(StatDefOf.Ability_PsyfocusCost, 0f); - - public float EffectRadius => statBases.GetStatValueFromList(StatDefOf.Ability_EffectRadius, 0f); - - public bool HasAreaOfEffect => EffectRadius > float.Epsilon; - - public float DetectionChance - { - get - { - if (!(detectionChanceOverride >= 0f)) - { - return this.GetStatValueAbstract(StatDefOf.Ability_DetectChancePerEntropy); - } - return detectionChanceOverride; - } - } - - public bool IsPsycast => typeof(Psycast).IsAssignableFrom(abilityClass); - - public string PsyfocusCostPercent - { - get - { - if (psyfocusCostPercent.NullOrEmpty()) - { - psyfocusCostPercent = PsyfocusCost.ToStringPercent(); - } - return psyfocusCostPercent; - } - } - - public string PsyfocusCostPercentMax - { - get - { - if (psyfocusCostPercentMax.NullOrEmpty()) - { - psyfocusCostPercentMax = PsyfocusCostRange.max.ToStringPercent(); - } - return psyfocusCostPercentMax; - } - } - - public int RequiredPsyfocusBand - { - get - { - if (requiredPsyfocusBandCached == -1) - { - requiredPsyfocusBandCached = Pawn_PsychicEntropyTracker.MaxAbilityLevelPerPsyfocusBand.Count - 1; - for (int i = 0; i < Pawn_PsychicEntropyTracker.MaxAbilityLevelPerPsyfocusBand.Count; i++) - { - int num = Pawn_PsychicEntropyTracker.MaxAbilityLevelPerPsyfocusBand[i]; - if (level <= num) - { - requiredPsyfocusBandCached = i; - break; - } - } - } - return requiredPsyfocusBandCached; - } - } - - public bool AnyCompOverridesPsyfocusCost - { - get - { - if (!anyCompOverridesPsyfocusCost.HasValue) - { - anyCompOverridesPsyfocusCost = false; - if (comps != null) - { - foreach (AbilityCompProperties comp in comps) - { - if (comp.OverridesPsyfocusCost) - { - anyCompOverridesPsyfocusCost = true; - break; - } - } - } - } - return anyCompOverridesPsyfocusCost.Value; - } - } - - public FloatRange PsyfocusCostRange - { - get - { - if (psyfocusCostRange.min < 0f) - { - if (!AnyCompOverridesPsyfocusCost) - { - psyfocusCostRange = new FloatRange(PsyfocusCost, PsyfocusCost); - } - else - { - foreach (AbilityCompProperties comp in comps) - { - if (comp.OverridesPsyfocusCost) - { - psyfocusCostRange = comp.PsyfocusCostRange; - break; - } - } - } - } - return psyfocusCostRange; - } - } - - public Texture2D WarmupMoteSocialSymbol - { - get - { - if (!warmupMoteSocialSymbol.NullOrEmpty() && warmupMoteSocialSymbolCached == null) - { - warmupMoteSocialSymbolCached = ContentFinder.Get(warmupMoteSocialSymbol); - } - return warmupMoteSocialSymbolCached; - } - } - - public IEnumerable StatSummary(Pawn forPawn = null) - { - string text = null; - foreach (AbilityCompProperties comp in comps) - { - if (comp.OverridesPsyfocusCost) - { - text = comp.PsyfocusCostExplanation; - break; - } - } - if (text == null) - { - if (PsyfocusCost > float.Epsilon) - { - yield return "AbilityPsyfocusCost".Translate() + ": " + PsyfocusCost.ToStringPercent(); - } - } - else - { - yield return text; - } - if (EntropyGain > float.Epsilon) - { - yield return string.Concat("AbilityEntropyGain".Translate() + ": ", EntropyGain.ToString()); - } - if (verbProperties.warmupTime > float.Epsilon) - { - yield return string.Concat("AbilityCastingTime".Translate() + ": ", verbProperties.warmupTime.ToString()) + "LetterSecond".Translate(); - } - if (cooldownTicksRange.min == cooldownTicksRange.max && cooldownTicksRange.min > 0) - { - yield return "StatsReport_Cooldown".Translate() + ": " + cooldownTicksRange.min.ToStringTicksToPeriod(allowSeconds: true, shortForm: false, canUseDecimals: true, allowYears: false); - } - float num = EffectDuration(forPawn); - if (num > float.Epsilon) - { - int num2 = num.SecondsToTicks(); - yield return "AbilityDuration".Translate() + ": " + ((num2 >= 2500) ? num2.ToStringTicksToPeriod() : (num.ToString() + "LetterSecond".Translate())); - } - if (HasAreaOfEffect) - { - yield return string.Concat("AbilityEffectRadius".Translate() + ": ", Mathf.Ceil(EffectRadius).ToString()); - } - if (comps == null) - { - yield break; - } - for (int i = 0; i < comps.Count; i++) - { - foreach (string item in comps[i].ExtraStatSummary()) - { - yield return item; - } - } - } - - public float EffectDuration(Pawn forPawn = null) - { - return this.GetStatValueAbstract(StatDefOf.Ability_Duration, forPawn); - } - - public override void PostLoad() - { - if (!string.IsNullOrEmpty(iconPath)) - { - LongEventHandler.ExecuteWhenFinished(delegate - { - uiIcon = ContentFinder.Get(iconPath); - }); - } - } - - public string GetTooltip(Pawn pawn = null) - { - if (cachedTooltip == null || cachedTooltipPawn != pawn) - { - cachedTooltip = LabelCap.Colorize(ColoredText.TipSectionTitleColor) + ((level > 0) ? string.Concat("\n" + "Level".Translate().CapitalizeFirst() + " ", level.ToString()) : "") + "\n\n" + description; - cachedTooltipPawn = pawn; - string text = StatSummary(pawn).ToLineList(); - if (!text.NullOrEmpty()) - { - cachedTooltip = cachedTooltip + "\n\n" + text; - } - } - if (pawn != null && ModsConfig.RoyaltyActive && IsPsycast && level > 0) - { - Faction first = Faction.GetMinTitleForImplantAllFactions(HediffDefOf.PsychicAmplifier).First; - if (first != null) - { - RoyalTitleDef minTitleForImplant = first.GetMinTitleForImplant(HediffDefOf.PsychicAmplifier, level); - RoyalTitleDef currentTitle = pawn.royalty.GetCurrentTitle(first); - if (minTitleForImplant != null && (currentTitle == null || currentTitle.seniority < minTitleForImplant.seniority) && DetectionChance > 0f) - { - return cachedTooltip + "\n\n" + ((string)"PsycastIsIllegal".Translate(pawn.Named("PAWN"), minTitleForImplant.GetLabelCapFor(pawn).Named("TITLE"))).Colorize(ColoredText.WarningColor); - } - } - } - return cachedTooltip; - } - - public override IEnumerable SpecialDisplayStats(StatRequest req) - { - if (cachedTargets == null) - { - cachedTargets = new List(); - if (verbProperties.targetParams.canTargetPawns && verbProperties.targetParams.canTargetSelf) - { - cachedTargets.Add("TargetSelf".Translate()); - } - if (verbProperties.targetParams.canTargetLocations) - { - cachedTargets.Add("TargetGround".Translate()); - } - if (verbProperties.targetParams.canTargetPawns && verbProperties.targetParams.canTargetHumans) - { - cachedTargets.Add("TargetHuman".Translate()); - } - if (verbProperties.targetParams.canTargetPawns && verbProperties.targetParams.canTargetAnimals) - { - cachedTargets.Add("TargetAnimal".Translate()); - } - } - int num = comps.OfType().Sum((CompProperties_AbilityEffect e) => e.goodwillImpact); - if (num != 0) - { - yield return new StatDrawEntry(StatCategoryDefOf.Ability, StatDefOf.Ability_GoodwillImpact, num, req); - } - if (IsPsycast && level != 0) - { - yield return new StatDrawEntry(StatCategoryDefOf.Ability, StatDefOf.Ability_RequiredPsylink, level, req); - } - yield return new StatDrawEntry(StatCategoryDefOf.Ability, StatDefOf.Ability_CastingTime, verbProperties.warmupTime, req); - if (verbProperties.range > 0f) - { - yield return new StatDrawEntry(StatCategoryDefOf.Ability, StatDefOf.Ability_Range, verbProperties.range, req); - } - yield return new StatDrawEntry(StatCategoryDefOf.Ability, "Target".Translate(), cachedTargets.ToCommaList().CapitalizeFirst(), "AbilityTargetDesc".Translate(), 1001); - yield return new StatDrawEntry(StatCategoryDefOf.Ability, "AbilityRequiresLOS".Translate(), verbProperties.requireLineOfSight ? "Yes".Translate() : "No".Translate(), "", 1000); - } - - public override IEnumerable ConfigErrors() - { - foreach (string item in base.ConfigErrors()) - { - yield return item; - } - if (abilityClass == null) - { - yield return "abilityClass is null"; - } - if (verbProperties == null) - { - yield return "verbProperties are null"; - } - if (label.NullOrEmpty()) - { - yield return "no label"; - } - if (statBases != null) - { - foreach (StatModifier statBase in statBases) - { - if (statBases.Count((StatModifier st) => st.stat == statBase.stat) > 1) - { - yield return "defines the stat base " + statBase.stat?.ToString() + " more than once."; - } - } - } - for (int i = 0; i < comps.Count; i++) - { - foreach (string item2 in comps[i].ConfigErrors(this)) - { - yield return item2; - } - } - } -} -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\Royalty\Defs\AbilityDefs\Abilities.xml` -**相似度:** 0.5815 - -```xml - - Skip - -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\AbilityStatModifiers.txt` -**相似度:** 0.5807 - -```csharp -public class AbilityStatModifiers -{ - public AbilityDef ability; - - public List modifiers; -} -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\AbilityDefOf.txt` -**相似度:** 0.5779 - -```csharp -public static class AbilityDefOf -{ - [MayRequireRoyalty] - public static AbilityDef Speech; - - [MayRequireBiotech] - public static AbilityDef ReimplantXenogerm; - - [MayRequireBiotech] - public static AbilityDef ResurrectionMech; - - [MayRequireAnomaly] - public static AbilityDef EntitySkip; - - [MayRequireAnomaly] - public static AbilityDef UnnaturalCorpseSkip; - - [MayRequireAnomaly] - public static AbilityDef ConsumeLeap_Devourer; - - [MayRequireOdyssey] - public static AbilityDef SludgeSpew; - - [MayRequireOdyssey] - public static AbilityDef EggSpew; - - static AbilityDefOf() - { - DefOfHelper.EnsureInitializedInCtor(typeof(AbilityDefOf)); - } -} -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\CompAbilityEffect_GiveMentalState.txt` -**相似度:** 0.5541 - -```csharp -public class CompAbilityEffect_GiveMentalState : CompAbilityEffect -{ - public new CompProperties_AbilityGiveMentalState Props => (CompProperties_AbilityGiveMentalState)props; - - public override void Apply(LocalTargetInfo target, LocalTargetInfo dest) - { - base.Apply(target, dest); - Pawn pawn = (Props.applyToSelf ? parent.pawn : (target.Thing as Pawn)); - if (pawn != null && !pawn.InMentalState) - { - TryGiveMentalState(pawn.RaceProps.IsMechanoid ? (Props.stateDefForMechs ?? Props.stateDef) : Props.stateDef, pawn, parent.def, Props.durationMultiplier, parent.pawn, Props.forced); - RestUtility.WakeUp(pawn); - if (Props.casterEffect != null) - { - Effecter effecter = Props.casterEffect.SpawnAttached(parent.pawn, parent.pawn.MapHeld); - effecter.Trigger(parent.pawn, null); - effecter.Cleanup(); - } - if (Props.targetEffect != null) - { - Effecter effecter2 = Props.targetEffect.SpawnAttached(parent.pawn, parent.pawn.MapHeld); - effecter2.Trigger(pawn, null); - effecter2.Cleanup(); - } - } - } - - public override bool Valid(LocalTargetInfo target, bool throwMessages = false) - { - if (!base.Valid(target, throwMessages)) - { - return false; - } - Pawn pawn = target.Pawn; - if (pawn != null) - { - if (!AbilityUtility.ValidateNoMentalState(pawn, throwMessages, parent)) - { - return false; - } - if (Props.excludeNPCFactions && pawn.Faction != null && !pawn.Faction.IsPlayer) - { - if (throwMessages) - { - Messages.Message("CannotUseAbility".Translate(parent.def.label) + ": " + "TargetBelongsToNPCFaction".Translate(), pawn, MessageTypeDefOf.RejectInput, historical: false); - } - return false; - } - } - return true; - } - - public static void TryGiveMentalState(MentalStateDef def, Pawn p, AbilityDef ability, StatDef multiplierStat, Pawn caster, bool forced = false) - { - if (p.mindState.mentalStateHandler.TryStartMentalState(def, null, forced, forceWake: true, causedByMood: false, caster, transitionSilently: false, causedByDamage: false, ability.IsPsycast)) - { - float num = ability.GetStatValueAbstract(StatDefOf.Ability_Duration, caster); - if (multiplierStat != null) - { - num *= p.GetStatValue(multiplierStat); - } - if (num > 0f) - { - p.mindState.mentalStateHandler.CurState.forceRecoverAfterTicks = num.SecondsToTicks(); - } - p.mindState.mentalStateHandler.CurState.sourceFaction = caster.Faction; - } - } -} -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\CompProperties_ResurrectMech.txt` -**相似度:** 0.5473 - -```csharp -public class CompProperties_ResurrectMech : CompProperties_AbilityEffect -{ - public int maxCorpseAgeTicks = int.MaxValue; - - public List costs = new List(); - - public EffecterDef appliedEffecterDef; - - public EffecterDef centerEffecterDef; - - public CompProperties_ResurrectMech() - { - compClass = typeof(CompAbilityEffect_ResurrectMech); - } - - public override IEnumerable ConfigErrors(AbilityDef parentDef) - { - foreach (string item in base.ConfigErrors(parentDef)) - { - yield return item; - } - if (costs.NullOrEmpty()) - { - yield return "costs list is null"; - yield break; - } - foreach (MechChargeCosts cost in costs) - { - if (cost.weightClass == null) - { - yield return $"costs list contains null weight class with cost {cost.cost}"; - } - } - } -} -``` \ No newline at end of file diff --git a/MCP/vector_cache/AddHumanlikeOrders-FloatMenuMakerMap.txt b/MCP/vector_cache/AddHumanlikeOrders-FloatMenuMakerMap.txt deleted file mode 100644 index 96addb59..00000000 --- a/MCP/vector_cache/AddHumanlikeOrders-FloatMenuMakerMap.txt +++ /dev/null @@ -1,519 +0,0 @@ -根据向量相似度分析,与 'AddHumanlikeOrders, FloatMenuMakerMap' 最相关的代码定义如下: - ---- -**文件路径 (精确匹配):** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\FloatMenuMakerMap.txt` - -```csharp -public static class FloatMenuMakerMap -{ - private static List providers; - - public static FloatMenuOptionProvider currentProvider; - - public static Pawn makingFor; - - public static void Init() - { - providers = new List(); - foreach (Type item in typeof(FloatMenuOptionProvider).AllSubclassesNonAbstract()) - { - providers.Add((FloatMenuOptionProvider)Activator.CreateInstance(item)); - } - } - - public static List GetOptions(List selectedPawns, Vector3 clickPos, out FloatMenuContext context) - { - List list = new List(); - context = null; - if (!clickPos.InBounds(Find.CurrentMap)) - { - return list; - } - context = new FloatMenuContext(selectedPawns, clickPos, Find.CurrentMap); - if (!context.allSelectedPawns.Any()) - { - return list; - } - if (!context.ClickedCell.IsValid || !context.ClickedCell.InBounds(Find.CurrentMap)) - { - return list; - } - if (!context.IsMultiselect) - { - AcceptanceReport acceptanceReport = ShouldGenerateFloatMenuForPawn(context.FirstSelectedPawn); - if (!acceptanceReport.Accepted) - { - if (!acceptanceReport.Reason.NullOrEmpty()) - { - Messages.Message(acceptanceReport.Reason, context.FirstSelectedPawn, MessageTypeDefOf.RejectInput, historical: false); - } - return list; - } - } - else - { - context.allSelectedPawns.RemoveAll((Pawn selectedPawn) => !ShouldGenerateFloatMenuForPawn(selectedPawn)); - if (!context.allSelectedPawns.Any()) - { - return list; - } - } - if (!context.IsMultiselect) - { - makingFor = context.FirstSelectedPawn; - } - GetProviderOptions(context, list); - makingFor = null; - return list; - } - - private static void GetProviderOptions(FloatMenuContext context, List options) - { - foreach (FloatMenuOptionProvider provider in providers) - { - try - { - currentProvider = provider; - if (!context.ValidSelectedPawns.Any() || !provider.Applies(context)) - { - continue; - } - options.AddRange(provider.GetOptions(context)); - foreach (Thing clickedThing in context.ClickedThings) - { - if (!provider.TargetThingValid(clickedThing, context)) - { - continue; - } - Thing thing = clickedThing; - if (thing.TryGetComp(out CompSelectProxy comp) && comp.thingToSelect != null) - { - thing = comp.thingToSelect; - } - foreach (FloatMenuOption item in provider.GetOptionsFor(thing, context)) - { - FloatMenuOption floatMenuOption = item; - if (floatMenuOption.iconThing == null) - { - floatMenuOption.iconThing = thing; - } - item.targetsDespawned = !thing.Spawned; - options.Add(item); - } - } - foreach (Pawn clickedPawn in context.ClickedPawns) - { - if (!provider.TargetPawnValid(clickedPawn, context)) - { - continue; - } - foreach (FloatMenuOption item2 in provider.GetOptionsFor(clickedPawn, context)) - { - FloatMenuOption floatMenuOption = item2; - if (floatMenuOption.iconThing == null) - { - floatMenuOption.iconThing = clickedPawn; - } - item2.targetsDespawned = !clickedPawn.Spawned; - options.Add(item2); - } - } - } - catch (Exception arg) - { - Log.Error($"Error in FloatMenuWorker {provider.GetType().Name}: {arg}"); - } - } - currentProvider = null; - } - - public static AcceptanceReport ShouldGenerateFloatMenuForPawn(Pawn pawn) - { - if (pawn.Map != Find.CurrentMap) - { - return false; - } - if (pawn.Downed) - { - return "IsIncapped".Translate(pawn.LabelCap, pawn); - } - if (ModsConfig.BiotechActive && pawn.Deathresting) - { - return "IsDeathresting".Translate(pawn.Named("PAWN")); - } - Lord lord = pawn.GetLord(); - if (lord != null) - { - AcceptanceReport result = lord.AllowsFloatMenu(pawn); - if (!result.Accepted) - { - return result; - } - } - return true; - } - - public static FloatMenuOption GetAutoTakeOption(List options) - { - bool flag = true; - FloatMenuOption floatMenuOption = null; - foreach (FloatMenuOption option in options) - { - if (option.Disabled || !option.autoTakeable) - { - flag = false; - break; - } - if (floatMenuOption == null || option.autoTakeablePriority > floatMenuOption.autoTakeablePriority) - { - floatMenuOption = option; - } - } - if (!flag || floatMenuOption == null) - { - return null; - } - return floatMenuOption; - } -} -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\FloatMenuContext.txt` -**相似度:** 0.5788 - -```csharp -public class FloatMenuContext -{ - public List allSelectedPawns; - - public Vector3 clickPosition; - - public Map map; - - private IntVec3 cachedClickedCell; - - private List cachedClickedThings; - - private List cachedClickedPawns; - - private Room cachedClickedRoom; - - private Zone cachedClickedZone; - - public IntVec3 ClickedCell => cachedClickedCell; - - public Room ClickedRoom => cachedClickedRoom; - - public Zone ClickedZone => cachedClickedZone; - - public List ClickedThings => cachedClickedThings; - - public List ClickedPawns => cachedClickedPawns; - - public bool IsMultiselect => allSelectedPawns.Count > 1; - - public Pawn FirstSelectedPawn - { - get - { - foreach (Pawn allSelectedPawn in allSelectedPawns) - { - if (FloatMenuMakerMap.currentProvider == null || FloatMenuMakerMap.currentProvider.SelectedPawnValid(allSelectedPawn, this)) - { - return allSelectedPawn; - } - } - return null; - } - } - - public IEnumerable ValidSelectedPawns - { - get - { - foreach (Pawn allSelectedPawn in allSelectedPawns) - { - if (FloatMenuMakerMap.currentProvider == null || FloatMenuMakerMap.currentProvider.SelectedPawnValid(allSelectedPawn, this)) - { - yield return allSelectedPawn; - } - } - } - } - - public FloatMenuContext(List selectedPawns, Vector3 clickPosition, Map map) - { - allSelectedPawns = selectedPawns; - this.clickPosition = clickPosition; - this.map = map; - cachedClickedCell = IntVec3.FromVector3(clickPosition); - cachedClickedRoom = cachedClickedCell.GetRoom(map); - cachedClickedZone = cachedClickedCell.GetZone(map); - cachedClickedThings = GenUI.ThingsUnderMouse(clickPosition, 0.8f, TargetingParameters.ForThing()); - cachedClickedPawns = GenUI.ThingsUnderMouse(clickPosition, 0.8f, TargetingParameters.ForPawns()).OfType().ToList(); - selectedPawns.RemoveAll((Pawn pawn) => !pawn.CanTakeOrder); - } -} -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\Verse\FloatMenuMap.txt` -**相似度:** 0.5739 - -```csharp -public class FloatMenuMap : FloatMenu -{ - private Vector3 clickPos; - - private static Dictionary> cachedChoices = new Dictionary>(); - - private List lastOptionsForRevalidation; - - private int nextOptionToRevalidate; - - public const int RevalidateEveryFrame = 4; - - public FloatMenuMap(List options, string title, Vector3 clickPos) - : base(options, title) - { - this.clickPos = clickPos; - } - - public override void DoWindowContents(Rect inRect) - { - if (!Find.Selector.AnyPawnSelected) - { - Find.WindowStack.TryRemove(this); - return; - } - bool flag = options.Count >= 3; - if (Time.frameCount % 4 == 0 || lastOptionsForRevalidation == null) - { - lastOptionsForRevalidation = FloatMenuMakerMap.GetOptions(Find.Selector.SelectedPawns, clickPos, out var _); - cachedChoices.Clear(); - cachedChoices.Add(clickPos, lastOptionsForRevalidation); - if (!flag) - { - for (int i = 0; i < options.Count; i++) - { - RevalidateOption(options[i]); - } - } - } - else if (flag) - { - if (nextOptionToRevalidate >= options.Count) - { - nextOptionToRevalidate = 0; - } - int num = Mathf.CeilToInt((float)options.Count / 3f); - int num2 = nextOptionToRevalidate; - int num3 = 0; - while (num2 < options.Count && num3 < num) - { - RevalidateOption(options[num2]); - nextOptionToRevalidate++; - num2++; - num3++; - } - } - base.DoWindowContents(inRect); - void RevalidateOption(FloatMenuOption option) - { - if (!option.Disabled && !StillValid(option, lastOptionsForRevalidation)) - { - option.Disabled = true; - } - } - } - - private static bool StillValid(FloatMenuOption opt, List curOpts) - { - if (opt.revalidateClickTarget == null) - { - for (int i = 0; i < curOpts.Count; i++) - { - if (OptionsMatch(opt, curOpts[i])) - { - return true; - } - } - } - else - { - if (!opt.targetsDespawned && !opt.revalidateClickTarget.Spawned) - { - return false; - } - Vector3 key = opt.revalidateClickTarget.PositionHeld.ToVector3Shifted(); - if (!cachedChoices.TryGetValue(key, out var value)) - { - FloatMenuContext context; - List list = FloatMenuMakerMap.GetOptions(Find.Selector.SelectedPawns, key, out context); - cachedChoices.Add(key, list); - value = list; - } - for (int j = 0; j < value.Count; j++) - { - if (OptionsMatch(opt, value[j])) - { - return !value[j].Disabled; - } - } - } - return false; - } - - public override void PreOptionChosen(FloatMenuOption opt) - { - base.PreOptionChosen(opt); - if (!opt.Disabled && !StillValid(opt, FloatMenuMakerMap.GetOptions(Find.Selector.SelectedPawns, clickPos, out var _))) - { - opt.Disabled = true; - } - } - - private static bool OptionsMatch(FloatMenuOption a, FloatMenuOption b) - { - if (a.Label == b.Label) - { - return true; - } - return false; - } -} -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\FloatMenuOptionProvider.txt` -**相似度:** 0.5483 - -```csharp -public abstract class FloatMenuOptionProvider -{ - protected abstract bool Drafted { get; } - - protected abstract bool Undrafted { get; } - - protected abstract bool Multiselect { get; } - - protected virtual bool RequiresManipulation => false; - - protected virtual bool MechanoidCanDo => false; - - protected virtual bool CanSelfTarget => false; - - public virtual bool CanTargetDespawned => false; - - protected virtual bool IgnoreFogged => true; - - public virtual bool SelectedPawnValid(Pawn pawn, FloatMenuContext context) - { - if (pawn.IsMutant && pawn.mutant.Def.whitelistedFloatMenuProviders != null && !pawn.mutant.Def.whitelistedFloatMenuProviders.Contains(FloatMenuMakerMap.currentProvider.GetType())) - { - return false; - } - if (!Drafted && pawn.Drafted) - { - return false; - } - if (!Undrafted && !pawn.Drafted) - { - return false; - } - if (!MechanoidCanDo && pawn.RaceProps.IsMechanoid) - { - return false; - } - if (RequiresManipulation && !pawn.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation)) - { - return false; - } - return true; - } - - public virtual bool TargetThingValid(Thing thing, FloatMenuContext context) - { - if (!CanTargetDespawned && !thing.Spawned) - { - return false; - } - if (thing is Pawn pawn && !TargetPawnValid(pawn, context)) - { - return false; - } - return true; - } - - public virtual bool TargetPawnValid(Pawn pawn, FloatMenuContext context) - { - if (!CanSelfTarget && pawn == context.FirstSelectedPawn) - { - return false; - } - return true; - } - - public virtual bool Applies(FloatMenuContext context) - { - if (!Multiselect && context.IsMultiselect) - { - return false; - } - if (IgnoreFogged && context.ClickedCell.Fogged(context.map)) - { - return false; - } - if (!AppliesInt(context)) - { - return false; - } - return true; - } - - protected virtual bool AppliesInt(FloatMenuContext context) - { - return true; - } - - public virtual IEnumerable GetOptions(FloatMenuContext context) - { - FloatMenuOption singleOption = GetSingleOption(context); - if (singleOption != null) - { - yield return singleOption; - } - } - - public virtual IEnumerable GetOptionsFor(Thing clickedThing, FloatMenuContext context) - { - FloatMenuOption singleOptionFor = GetSingleOptionFor(clickedThing, context); - if (singleOptionFor != null) - { - yield return singleOptionFor; - } - } - - public virtual IEnumerable GetOptionsFor(Pawn clickedPawn, FloatMenuContext context) - { - FloatMenuOption singleOptionFor = GetSingleOptionFor(clickedPawn, context); - if (singleOptionFor != null) - { - yield return singleOptionFor; - } - } - - protected virtual FloatMenuOption GetSingleOption(FloatMenuContext context) - { - return null; - } - - protected virtual FloatMenuOption GetSingleOptionFor(Thing clickedThing, FloatMenuContext context) - { - return null; - } - - protected virtual FloatMenuOption GetSingleOptionFor(Pawn clickedPawn, FloatMenuContext context) - { - return null; - } -} -``` \ No newline at end of file diff --git a/MCP/vector_cache/BiosculpterPod-ThingDef.txt b/MCP/vector_cache/BiosculpterPod-ThingDef.txt deleted file mode 100644 index a55a7d7b..00000000 --- a/MCP/vector_cache/BiosculpterPod-ThingDef.txt +++ /dev/null @@ -1,1502 +0,0 @@ -根据向量相似度分析,与 'BiosculpterPod, ThingDef' 最相关的代码定义如下: - ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\CompProperties_BiosculpterPod_BaseCycle.txt` -**相似度:** 0.7659 - -```csharp -public abstract class CompProperties_BiosculpterPod_BaseCycle : CompProperties -{ - [NoTranslate] - public string key; - - [MustTranslate] - public string label; - - [MustTranslate] - public string description; - - [NoTranslate] - public string iconPath; - - public float durationDays; - - public Color operatingColor = new Color(0.5f, 0.7f, 0.5f); - - public ThoughtDef gainThoughtOnCompletion; - - public List requiredResearch; - - public List extraRequiredIngredients; - - private Texture2D icon; - - public Texture2D Icon - { - get - { - if (icon == null) - { - icon = ContentFinder.Get(iconPath); - } - return icon; - } - } - - public string LabelCap => label.CapitalizeFirst(); -} -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\CompBiosculpterPod.txt` -**相似度:** 0.7294 - -```csharp -public class CompBiosculpterPod : ThingComp, ISuspendableThingHolder, IThingHolder, IThingHolderWithDrawnPawn, IStoreSettingsParent, INotifyHauledTo, ISearchableContents -{ - private const int NoPowerEjectCumulativeTicks = 60000; - - private const int BiotunedDuration = 4800000; - - private const float NutritionRequired = 5f; - - private const float CacheForSecs = 2f; - - private static readonly Texture2D InterruptCycleIcon = ContentFinder.Get("UI/Designators/Cancel"); - - private static readonly Material BackgroundMat = SolidColorMaterials.NewSolidColorMaterial(new Color(0.082f, 0.078f, 0.063f), ShaderDatabase.SolidColorBehind); - - private const float BackgroundRect_YOff = 0.07317074f; - - private const float Pawn_YOff = 0.03658537f; - - private string currentCycleKey; - - private float currentCycleTicksRemaining; - - private int currentCyclePowerCutTicks; - - private ThingOwner innerContainer; - - private Pawn biotunedTo; - - private int biotunedCountdownTicks; - - private StorageSettings allowedNutritionSettings; - - private float liquifiedNutrition; - - public bool autoLoadNutrition = true; - - public bool devFillPodLatch; - - private bool autoAgeReversal; - - private int tickEntered = -99999; - - public Job queuedEnterJob; - - public Pawn queuedPawn; - - private List chosenExtraItems = new List(); - - private List cycleEligiblePawnOptions = new List(); - - private Pawn pawnEnteringBiosculpter; - - private Dictionary> cachedExtraIngredients = new Dictionary>(); - - private Dictionary cachedAnyPawnEligible = new Dictionary(); - - private static Dictionary> cachedBiotunedPods = new Dictionary>(); - - private Pawn cacheReachIngredientsPawn; - - private CompBiosculpterPod_Cycle cacheReachIngredientsCycle; - - private float cacheReachIngredientsTime = float.MinValue; - - private bool cacheReachIngredientsResult; - - private Effecter progressBarEffecter; - - private Effecter operatingEffecter; - - private Effecter readyEffecter; - - private Texture2D cachedAutoAgeReverseIcon; - - private List cachedAvailableCycles; - - private Dictionary cycleLookup; - - private static string cachedAgeReversalCycleKey = null; - - private List tmpIngredientsStrings = new List(); - - private static readonly List tmpItems = new List(); - - private CompPowerTrader powerTraderComp; - - private CompPower powerComp; - - private static List cachedPodDefs; - - public CompProperties_BiosculpterPod Props => props as CompProperties_BiosculpterPod; - - public ThingOwner SearchableContents => innerContainer; - - public bool IsContentsSuspended => true; - - public float RequiredNutritionRemaining => Mathf.Max(5f - liquifiedNutrition, 0f); - - public bool NutritionLoaded => RequiredNutritionRemaining <= 0f; - - public bool AutoAgeReversal => autoAgeReversal; - - private Texture2D AutoAgeReversalIcon - { - get - { - if (cachedAutoAgeReverseIcon == null) - { - cachedAutoAgeReverseIcon = ContentFinder.Get("UI/Gizmos/BiosculpterAutoAgeReversal"); - } - return cachedAutoAgeReverseIcon; - } - } - - public BiosculpterPodState State - { - get - { - if (Occupant != null) - { - return BiosculpterPodState.Occupied; - } - if (NutritionLoaded) - { - return BiosculpterPodState.SelectingCycle; - } - return BiosculpterPodState.LoadingNutrition; - } - } - - public Pawn Occupant - { - get - { - if (pawnEnteringBiosculpter != null) - { - return pawnEnteringBiosculpter; - } - if (currentCycleKey == null) - { - return null; - } - if (innerContainer.Count != 1) - { - return null; - } - return innerContainer[0] as Pawn; - } - } - - public CompBiosculpterPod_Cycle CurrentCycle - { - get - { - if (currentCycleKey == null) - { - return null; - } - foreach (CompBiosculpterPod_Cycle availableCycle in AvailableCycles) - { - if (availableCycle.Props.key == currentCycleKey) - { - return availableCycle; - } - } - return null; - } - } - - public List AvailableCycles - { - get - { - if (cachedAvailableCycles == null) - { - SetupCycleCaches(); - } - return cachedAvailableCycles; - } - } - - public string AgeReversalCycleKey - { - get - { - if (cachedAgeReversalCycleKey == null) - { - SetupCycleCaches(); - } - return cachedAgeReversalCycleKey; - } - } - - private float CycleSpeedFactorNoPawn => CleanlinessSpeedFactor * BiotunedSpeedFactor; - - public float CycleSpeedFactor - { - get - { - if (Occupant == null) - { - return Mathf.Max(0.1f, CycleSpeedFactorNoPawn); - } - return GetCycleSpeedFactorForPawn(Occupant); - } - } - - private float CleanlinessSpeedFactor => parent.GetStatValue(StatDefOf.BiosculpterPodSpeedFactor); - - private float BiotunedSpeedFactor - { - get - { - if (biotunedTo == null) - { - return 1f; - } - return Props.biotunedCycleSpeedFactor; - } - } - - public bool PowerOn => parent.TryGetComp().PowerOn; - - public float HeldPawnDrawPos_Y => parent.DrawPos.y - 0.03658537f; - - public float HeldPawnBodyAngle => parent.Rotation.Opposite.AsAngle; - - public PawnPosture HeldPawnPosture => PawnPosture.LayingOnGroundFaceUp; - - public bool StorageTabVisible => true; - - public CompBiosculpterPod() - { - innerContainer = new ThingOwner(this); - } - - public override void Initialize(CompProperties props) - { - base.Initialize(props); - allowedNutritionSettings = new StorageSettings(this); - if (parent.def.building.defaultStorageSettings != null) - { - allowedNutritionSettings.CopyFrom(parent.def.building.defaultStorageSettings); - } - } - - public override void PostSpawnSetup(bool respawningAfterLoad) - { - if (ModLister.CheckIdeology("Biosculpter pod comp")) - { - base.PostSpawnSetup(respawningAfterLoad); - } - } - - public override void PostExposeData() - { - base.PostExposeData(); - Scribe_Deep.Look(ref innerContainer, "innerContainer", this); - Scribe_Values.Look(ref currentCycleKey, "currentCycleKey"); - Scribe_Values.Look(ref currentCycleTicksRemaining, "currentCycleTicksRemaining", 0f); - Scribe_Values.Look(ref currentCyclePowerCutTicks, "currentCyclePowerCutTicks", 0); - Scribe_References.Look(ref biotunedTo, "biotunedTo"); - Scribe_Values.Look(ref biotunedCountdownTicks, "biotunedCountdownTicks", 0); - Scribe_Deep.Look(ref allowedNutritionSettings, "allowedNutritionSettings"); - Scribe_Values.Look(ref liquifiedNutrition, "liquifiedNutrition", 0f); - Scribe_Values.Look(ref autoLoadNutrition, "autoLoadNutrition", defaultValue: false); - Scribe_Values.Look(ref devFillPodLatch, "devFillPodLatch", defaultValue: false); - Scribe_Values.Look(ref autoAgeReversal, "autoAgeReversal", defaultValue: false); - Scribe_Values.Look(ref tickEntered, "tickEntered", 0); - Scribe_References.Look(ref queuedEnterJob, "queuedEnterJob"); - Scribe_References.Look(ref queuedPawn, "queuedPawn"); - if (allowedNutritionSettings == null) - { - allowedNutritionSettings = new StorageSettings(this); - if (parent.def.building.defaultStorageSettings != null) - { - allowedNutritionSettings.CopyFrom(parent.def.building.defaultStorageSettings); - } - } - if (Scribe.mode == LoadSaveMode.PostLoadInit) - { - if (currentCycleKey == "healing") - { - currentCycleKey = "medic"; - } - if (biotunedTo != null) - { - SetBiotuned(biotunedTo); - } - LiquifyNutrition(); - } - } - - public CompBiosculpterPod_Cycle GetCycle(string key) - { - if (cycleLookup == null) - { - SetupCycleCaches(); - } - return cycleLookup[key]; - } - - public float GetCycleSpeedFactorForPawn(Pawn p) - { - return Mathf.Max(0.1f, CycleSpeedFactorNoPawn * p.GetStatValue(StatDefOf.BiosculpterOccupantSpeed)); - } - - private void SetupCycleCaches() - { - cachedAvailableCycles = new List(); - cachedAvailableCycles.AddRange(parent.AllComps.OfType()); - cycleLookup = new Dictionary(); - foreach (CompBiosculpterPod_Cycle cachedAvailableCycle in cachedAvailableCycles) - { - if (cachedAvailableCycle is CompBiosculpterPod_AgeReversalCycle compBiosculpterPod_AgeReversalCycle) - { - cachedAgeReversalCycleKey = compBiosculpterPod_AgeReversalCycle.Props.key; - } - cycleLookup[cachedAvailableCycle.Props.key] = cachedAvailableCycle; - } - } - - public void SetBiotuned(Pawn newBiotunedTo) - { - if (newBiotunedTo != biotunedTo) - { - autoAgeReversal = false; - } - if (biotunedTo != null && cachedBiotunedPods.ContainsKey(biotunedTo)) - { - cachedBiotunedPods[biotunedTo].Remove(this); - } - if (newBiotunedTo != null && !cachedBiotunedPods.ContainsKey(newBiotunedTo)) - { - cachedBiotunedPods[newBiotunedTo] = new List(); - } - if (newBiotunedTo != null && !cachedBiotunedPods[newBiotunedTo].Contains(this)) - { - cachedBiotunedPods[newBiotunedTo].Add(this); - } - if (newBiotunedTo != null && newBiotunedTo != biotunedTo) - { - biotunedCountdownTicks = 4800000; - } - biotunedTo = newBiotunedTo; - } - - public override void PostDestroy(DestroyMode mode, Map previousMap) - { - SetBiotuned(null); - if (mode == DestroyMode.Deconstruct || mode == DestroyMode.KillFinalize) - { - EjectContents(interrupted: true, playSounds: false, previousMap); - } - innerContainer.ClearAndDestroyContents(); - base.PostDestroy(mode, previousMap); - } - - public override void PostDeSpawn(Map map, DestroyMode mode = DestroyMode.Vanish) - { - if (mode != DestroyMode.WillReplace) - { - EjectContents(interrupted: true, playSounds: false, map); - currentCycleKey = null; - } - progressBarEffecter?.Cleanup(); - progressBarEffecter = null; - operatingEffecter?.Cleanup(); - operatingEffecter = null; - readyEffecter?.Cleanup(); - readyEffecter = null; - } - - public override void DrawGUIOverlay() - { - base.DrawGUIOverlay(); - if (!Find.ScreenshotModeHandler.Active && (biotunedTo != null || Occupant != null)) - { - GenMapUI.DrawThingLabel(parent, biotunedTo?.LabelShort ?? Occupant.LabelShort, GenMapUI.DefaultThingLabelColor); - } - } - - public override string CompInspectStringExtra() - { - StringBuilder stringBuilder = new StringBuilder(); - BiosculpterPodState state = State; - if (parent.Spawned) - { - CompBiosculpterPod_Cycle currentCycle = CurrentCycle; - if (currentCycle != null) - { - stringBuilder.AppendLineIfNotEmpty().Append("BiosculpterPodCycleLabel".Translate()).Append(": ") - .Append(currentCycle.Props.LabelCap); - if (biotunedTo == null) - { - stringBuilder.Append(" " + "BiosculpterPodCycleWillBiotune".Translate()); - } - } - else if (state == BiosculpterPodState.SelectingCycle) - { - if (PowerOn) - { - if (queuedEnterJob != null && !queuedEnterJob.biosculpterCycleKey.NullOrEmpty()) - { - stringBuilder.Append("BiosculpterPodCycleStandby".Translate(GetCycle(queuedEnterJob.biosculpterCycleKey).Props.label.Named("CYCLE"), queuedPawn.Named("PAWN"))); - } - else - { - stringBuilder.Append("BiosculpterPodCycleSelection".Translate().CapitalizeFirst()); - } - } - else - { - stringBuilder.Append("BiosculpterPodCycleSelectionNoPower".Translate().CapitalizeFirst()); - } - } - if (state == BiosculpterPodState.LoadingNutrition) - { - stringBuilder.Append("BiosculpterPodCycleLabelLoading".Translate().CapitalizeFirst()); - stringBuilder.AppendLineIfNotEmpty().Append("Nutrition".Translate()).Append(": ") - .Append(liquifiedNutrition.ToStringByStyle(ToStringStyle.FloatMaxOne)) - .Append(" / ") - .Append(5f); - } - if (state == BiosculpterPodState.Occupied) - { - float num = currentCycleTicksRemaining / CycleSpeedFactor; - stringBuilder.AppendLineIfNotEmpty().Append("Contains".Translate()).Append(": ") - .Append(Occupant.NameShortColored.Resolve()); - if (!PowerOn) - { - stringBuilder.AppendLine().Append("BiosculpterCycleNoPowerInterrupt".Translate((60000 - currentCyclePowerCutTicks).ToStringTicksToPeriod().Named("TIME")).Colorize(ColorLibrary.RedReadable)); - } - stringBuilder.AppendLine().Append("BiosculpterCycleTimeRemaining".Translate()).Append(": ") - .Append(((int)num).ToStringTicksToPeriod().Colorize(ColoredText.DateTimeColor)); - Ideo ideo = Occupant.Ideo; - if (ideo != null && ideo.HasPrecept(PreceptDefOf.Biosculpting_Accelerated)) - { - stringBuilder.Append(" (" + "BiosculpterCycleAccelerated".Translate() + ")"); - } - if (biotunedTo != null) - { - stringBuilder.AppendLine().Append("BiosculpterBiotunedSpeedFactor".Translate()).Append(": ") - .Append(BiotunedSpeedFactor.ToStringPercent()); - } - stringBuilder.AppendLine().Append("BiosculpterCleanlinessSpeedFactor".Translate()).Append(": ") - .Append(CleanlinessSpeedFactor.ToStringPercent()); - } - } - if (biotunedTo != null && state != BiosculpterPodState.Occupied) - { - stringBuilder.AppendLineIfNotEmpty().Append("BiosculpterBiotunedTo".Translate()).Append(": ") - .Append(biotunedTo.LabelShort) - .Append(" (") - .Append(biotunedCountdownTicks.ToStringTicksToPeriod()) - .Append(")"); - } - if (stringBuilder.Length <= 0) - { - return null; - } - return stringBuilder.ToString(); - } - - public override IEnumerable CompGetGizmosExtra() - { - BiosculpterPodState state = State; - string cycleIndependentCannotUseReason = CannotUseNowReason(); - foreach (CompBiosculpterPod_Cycle cycle in AvailableCycles) - { - string text = cycleIndependentCannotUseReason ?? CannotUseNowCycleReason(cycle); - Command_Action command_Action = new Command_Action(); - command_Action.defaultLabel = "BiosculpterPodCycleCommand".Translate(cycle.Props.label) + ((biotunedTo != null) ? (" (" + biotunedTo.LabelShort + ")") : ""); - command_Action.defaultDesc = CycleDescription(cycle); - command_Action.icon = cycle.Props.Icon; - command_Action.action = delegate - { - SelectPawnsForCycleOptions(cycle, out var options2); - if (biotunedTo != null && options2.Count > 0) - { - options2[0].action(); - if (!(cycle is CompBiosculpterPod_HealingCycle)) - { - Messages.Message("BiosculpterEnteringMessage".Translate(biotunedTo.Named("PAWN"), cycle.Props.label.Named("CYCLE")).CapitalizeFirst(), parent, MessageTypeDefOf.SilentInput, historical: false); - } - } - else - { - Find.WindowStack.Add(new FloatMenu(options2)); - } - }; - command_Action.activateSound = SoundDefOf.Tick_Tiny; - command_Action.Disabled = text != null; - List options; - if (text != null) - { - command_Action.Disable(text); - } - else if (!SelectPawnsForCycleOptions(cycle, out options, shortCircuit: true)) - { - command_Action.Disable((biotunedTo != null) ? "BiosculpterNoEligiblePawnsBiotuned".Translate(biotunedTo.Named("PAWN")) : "BiosculpterNoEligiblePawns".Translate()); - } - yield return command_Action; - } - if (state == BiosculpterPodState.Occupied) - { - Command_Action command_Action2 = new Command_Action(); - command_Action2.defaultLabel = "BiosculpterInteruptCycle".Translate(); - command_Action2.defaultDesc = "BiosculpterInteruptCycleDesc".Translate(); - command_Action2.icon = InterruptCycleIcon; - command_Action2.action = delegate - { - EjectContents(interrupted: true, playSounds: true); - }; - command_Action2.activateSound = SoundDefOf.Designate_Cancel; - yield return command_Action2; - } - Command_Toggle command_Toggle = new Command_Toggle(); - command_Toggle.defaultLabel = "BiosculpterAutoLoadNutritionLabel".Translate(); - command_Toggle.defaultDesc = "BiosculpterAutoLoadNutritionDescription".Translate(); - command_Toggle.icon = (autoLoadNutrition ? TexCommand.ForbidOff : TexCommand.ForbidOn); - command_Toggle.isActive = () => autoLoadNutrition; - command_Toggle.toggleAction = delegate - { - autoLoadNutrition = !autoLoadNutrition; - }; - yield return command_Toggle; - if ((biotunedTo?.Ideo?.HasPrecept(PreceptDefOf.AgeReversal_Demanded)).GetValueOrDefault()) - { - Command_Toggle command_Toggle2 = new Command_Toggle(); - command_Toggle2.defaultLabel = "BiosculpterAutoAgeReversalLabel".Translate(biotunedTo.Named("PAWN")); - TaggedString taggedString = ((biotunedTo.ageTracker.AgeReversalDemandedDeadlineTicks > 0) ? "BiosculpterAutoAgeReversalDescriptionFuture".Translate(biotunedTo.Named("PAWN"), ((int)biotunedTo.ageTracker.AgeReversalDemandedDeadlineTicks).ToStringTicksToPeriodVague().Named("TIME")) : "BiosculpterAutoAgeReversalDescriptionNow".Translate(biotunedTo.Named("PAWN"))); - command_Toggle2.defaultDesc = "BiosculpterAutoAgeReversalDescription".Translate(biotunedTo.Named("PAWN"), taggedString.Named("NEXTTREATMENT")); - command_Toggle2.icon = AutoAgeReversalIcon; - command_Toggle2.isActive = () => AutoAgeReversal; - command_Toggle2.toggleAction = delegate - { - autoAgeReversal = !autoAgeReversal; - }; - if (!CanAgeReverse(biotunedTo)) - { - command_Toggle2.Disable("UnderMinBiosculpterAgeReversalAge".Translate(biotunedTo.ageTracker.AdultMinAge.Named("ADULTAGE")).CapitalizeFirst()); - autoAgeReversal = false; - } - yield return command_Toggle2; - } - foreach (Gizmo item in StorageSettingsClipboard.CopyPasteGizmosFor(allowedNutritionSettings)) - { - yield return item; - } - Gizmo gizmo = Building.SelectContainedItemGizmo(parent, Occupant); - if (gizmo != null) - { - yield return gizmo; - } - if (DebugSettings.ShowDevGizmos) - { - yield return new Command_Action - { - defaultLabel = "DEV: complete cycle", - action = delegate - { - currentCycleTicksRemaining = 10f; - }, - Disabled = (State != BiosculpterPodState.Occupied) - }; - yield return new Command_Action - { - defaultLabel = "DEV: advance cycle +1 day", - action = delegate - { - currentCycleTicksRemaining -= 60000f; - }, - Disabled = (State != BiosculpterPodState.Occupied) - }; - yield return new Command_Action - { - defaultLabel = "DEV: complete biotune timer", - action = delegate - { - biotunedCountdownTicks = 10; - }, - Disabled = (biotunedCountdownTicks <= 0) - }; - yield return new Command_Action - { - defaultLabel = "DEV: fill nutrition and cycle ingredients", - action = delegate - { - liquifiedNutrition = 5f; - devFillPodLatch = true; - }, - Disabled = (State == BiosculpterPodState.Occupied || (devFillPodLatch && liquifiedNutrition == 5f)) - }; - } - } - - private string IngredientsDescription(CompBiosculpterPod_Cycle cycle) - { - tmpIngredientsStrings.Clear(); - if (!cycle.Props.extraRequiredIngredients.NullOrEmpty() && !devFillPodLatch) - { - for (int i = 0; i < cycle.Props.extraRequiredIngredients.Count; i++) - { - tmpIngredientsStrings.Add(cycle.Props.extraRequiredIngredients[i].Summary); - } - } - return tmpIngredientsStrings.ToCommaList(useAnd: true); - } - - private string CycleDescription(CompBiosculpterPod_Cycle cycle) - { - StringBuilder stringBuilder = new StringBuilder(); - stringBuilder.Append(cycle.Description(biotunedTo)); - float num = cycle.Props.durationDays / CycleSpeedFactor; - float num2 = num / PreceptDefOf.Biosculpting_Accelerated.biosculpterPodCycleSpeedFactor; - stringBuilder.AppendLine("\n\n" + "BiosculpterPodCycleDuration".Translate() + ": " + ((int)(num * 60000f)).ToStringTicksToDays()); - if (!Find.IdeoManager.classicMode) - { - stringBuilder.Append("BiosculpterPodCycleDurationTranshumanists".Translate() + ": " + ((int)(num2 * 60000f)).ToStringTicksToDays()); - } - return stringBuilder.ToString(); - } - - public bool PawnCanUseNow(Pawn pawn, CompBiosculpterPod_Cycle cycle) - { - return (CannotUseNowReason() ?? CannotUseNowPawnReason(pawn) ?? CannotUseNowCycleReason(cycle) ?? CannotUseNowPawnCycleReason(pawn, cycle)) == null; - } - - public override IEnumerable CompFloatMenuOptions(Pawn selPawn) - { - if (selPawn.IsQuestLodger()) - { - yield return new FloatMenuOption("CannotEnter".Translate() + ": " + "CryptosleepCasketGuestsNotAllowed".Translate().CapitalizeFirst(), null); - yield break; - } - string cycleIndependentfailureReason = CannotUseNowReason() ?? CannotUseNowPawnReason(selPawn); - foreach (CompBiosculpterPod_Cycle cycle in AvailableCycles) - { - string text = cycleIndependentfailureReason ?? CannotUseNowCycleReason(cycle) ?? CannotUseNowPawnCycleReason(selPawn, cycle); - if (text != null) - { - yield return new FloatMenuOption(CannotStartText(cycle, text), null); - continue; - } - string label = "EnterBiosculpterPod".Translate(cycle.Props.label, ((int)(cycle.Props.durationDays / GetCycleSpeedFactorForPawn(selPawn) * 60000f)).ToStringTicksToDays()); - yield return FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption(label, delegate - { - PrepareCycleJob(selPawn, selPawn, cycle, EnterBiosculpterJob()); - }), selPawn, parent); - } - } - - public static bool CanAgeReverse(Pawn biosculptee) - { - return biosculptee.ageTracker.Adult; - } - - public static List BiotunedPods(Pawn pawn) - { - return cachedBiotunedPods.TryGetValue(pawn); - } - - public static bool HasBiotunedAutoAgeReversePod(Pawn pawn) - { - List list = cachedBiotunedPods.TryGetValue(pawn); - if (list == null) - { - return false; - } - foreach (CompBiosculpterPod item in list) - { - if (item.AutoAgeReversal) - { - return true; - } - } - return false; - } - - public static string CannotStartText(CompBiosculpterPod_Cycle cycle, string translatedReason) - { - return "BiosculpterCannotStartCycle".Translate(cycle.Props.label) + ": " + translatedReason.CapitalizeFirst(); - } - - public string CannotUseNowCycleReason(CompBiosculpterPod_Cycle cycle) - { - List list = cycle.MissingResearchLabels(); - if (list.Any()) - { - return "MissingRequiredResearch".Translate() + " " + list.ToCommaList(); - } - return null; - } - - public string CannotUseNowPawnCycleReason(Pawn p, CompBiosculpterPod_Cycle cycle, bool checkIngredients = true) - { - return CannotUseNowPawnCycleReason(p, p, cycle, checkIngredients); - } - - private bool CanReachOrHasIngredients(Pawn hauler, Pawn biosculptee, CompBiosculpterPod_Cycle cycle, bool useCache = false) - { - if (!PawnCarryingExtraCycleIngredients(biosculptee, cycle) && (biosculptee == hauler || !PawnCarryingExtraCycleIngredients(hauler, cycle))) - { - return CanReachRequiredIngredients(hauler, cycle, useCache); - } - return true; - } - - public string CannotUseNowPawnCycleReason(Pawn hauler, Pawn biosculptee, CompBiosculpterPod_Cycle cycle, bool checkIngredients = true) - { - if (AgeReversalCycleKey != null && cycle.Props.key == AgeReversalCycleKey && !CanAgeReverse(biosculptee)) - { - return "UnderMinBiosculpterAgeReversalAge".Translate(biosculptee.ageTracker.AdultMinAge.Named("ADULTAGE")).CapitalizeFirst(); - } - if (checkIngredients && !CanReachOrHasIngredients(hauler, biosculptee, cycle, useCache: true)) - { - return "BiosculpterMissingIngredients".Translate(IngredientsDescription(cycle).Named("INGREDIENTS")).CapitalizeFirst(); - } - return null; - } - - public string CannotUseNowPawnReason(Pawn p) - { - if (biotunedTo != null && biotunedTo != p) - { - return "BiosculpterBiotunedToAnother".Translate().CapitalizeFirst(); - } - if (!p.CanReach(parent, PathEndMode.InteractionCell, Danger.Deadly)) - { - return "NoPath".Translate().CapitalizeFirst(); - } - return null; - } - - public string CannotUseNowReason() - { - if (!PowerOn) - { - return "NoPower".Translate().CapitalizeFirst(); - } - if (State == BiosculpterPodState.LoadingNutrition) - { - return "BiosculpterNutritionNotLoaded".Translate().CapitalizeFirst(); - } - if (State == BiosculpterPodState.Occupied) - { - return "BiosculpterOccupied".Translate().CapitalizeFirst(); - } - return null; - } - - private List RequiredIngredients(CompBiosculpterPod_Cycle cycle) - { - List extraRequiredIngredients = cycle.Props.extraRequiredIngredients; - if (extraRequiredIngredients == null || devFillPodLatch) - { - return null; - } - if (!cachedExtraIngredients.ContainsKey(cycle)) - { - cachedExtraIngredients[cycle] = extraRequiredIngredients.Select((ThingDefCountClass tc) => tc.ToIngredientCount()).ToList(); - } - return cachedExtraIngredients[cycle]; - } - - private bool CanReachRequiredIngredients(Pawn pawn, CompBiosculpterPod_Cycle cycle, bool useCache = false) - { - chosenExtraItems.Clear(); - if (cycle.Props.extraRequiredIngredients == null || devFillPodLatch) - { - return true; - } - float realtimeSinceStartup = Time.realtimeSinceStartup; - if (useCache && cacheReachIngredientsPawn == pawn && cacheReachIngredientsCycle == cycle && realtimeSinceStartup < cacheReachIngredientsTime + 2f) - { - return cacheReachIngredientsResult; - } - cacheReachIngredientsPawn = pawn; - cacheReachIngredientsCycle = cycle; - cacheReachIngredientsTime = realtimeSinceStartup; - cacheReachIngredientsResult = WorkGiver_DoBill.TryFindBestFixedIngredients(RequiredIngredients(cycle), pawn, parent, chosenExtraItems); - return cacheReachIngredientsResult; - } - - private bool SelectPawnCycleOption(Pawn pawn, CompBiosculpterPod_Cycle cycle, out FloatMenuOption option) - { - string text = CannotUseNowPawnReason(pawn) ?? CannotUseNowPawnCycleReason(pawn, cycle, checkIngredients: false); - string label = pawn.Label + ((text == null) ? "" : (": " + text)); - Action action = null; - if (text == null) - { - action = delegate - { - PrepareCycleJob(pawn, pawn, cycle, EnterBiosculpterJob()); - }; - } - option = new FloatMenuOption(label, action); - return text == null; - } - - private bool SelectPawnsForCycleOptions(CompBiosculpterPod_Cycle cycle, out List options, bool shortCircuit = false) - { - cycleEligiblePawnOptions.Clear(); - options = cycleEligiblePawnOptions; - if (!cachedAnyPawnEligible.ContainsKey(cycle)) - { - cachedAnyPawnEligible[cycle] = new CacheAnyPawnEligibleCycle - { - gameTime = float.MinValue - }; - } - int ticksGame = Find.TickManager.TicksGame; - if (shortCircuit && (float)ticksGame < cachedAnyPawnEligible[cycle].gameTime + 2f) - { - return cachedAnyPawnEligible[cycle].anyEligible; - } - cachedAnyPawnEligible[cycle].gameTime = ticksGame; - if (biotunedTo != null) - { - if (biotunedTo.Dead || !biotunedTo.Spawned || biotunedTo.Map != parent.Map) - { - cachedAnyPawnEligible[cycle].anyEligible = false; - return cachedAnyPawnEligible[cycle].anyEligible; - } - if (SelectPawnCycleOption(biotunedTo, cycle, out var option) && shortCircuit) - { - cachedAnyPawnEligible[cycle].anyEligible = true; - return cachedAnyPawnEligible[cycle].anyEligible; - } - cycleEligiblePawnOptions.Add(option); - } - else - { - foreach (Pawn item in parent.Map.mapPawns.FreeColonistsSpawned) - { - if (SelectPawnCycleOption(item, cycle, out var option2) && shortCircuit) - { - cachedAnyPawnEligible[cycle].anyEligible = true; - return cachedAnyPawnEligible[cycle].anyEligible; - } - cycleEligiblePawnOptions.Add(option2); - } - } - cachedAnyPawnEligible[cycle].anyEligible = cycleEligiblePawnOptions.Count > 0; - return cachedAnyPawnEligible[cycle].anyEligible; - } - - public Job EnterBiosculpterJob() - { - return JobMaker.MakeJob(JobDefOf.EnterBiosculpterPod, parent); - } - - public Job MakeCarryToBiosculpterJob(Pawn willBeCarried) - { - return JobMaker.MakeJob(JobDefOf.CarryToBiosculpterPod, willBeCarried, LocalTargetInfo.Invalid, parent); - } - - public void ConfigureJobForCycle(Job job, CompBiosculpterPod_Cycle cycle, List extraIngredients) - { - if (!extraIngredients.NullOrEmpty()) - { - job.targetQueueB = new List(extraIngredients.Count); - job.countQueue = new List(extraIngredients.Count); - foreach (ThingCount extraIngredient in extraIngredients) - { - job.targetQueueB.Add(extraIngredient.Thing); - job.countQueue.Add(extraIngredient.Count); - } - } - job.haulMode = HaulMode.ToCellNonStorage; - job.biosculpterCycleKey = cycle.Props.key; - } - - public void PrepareCycleJob(Pawn hauler, Pawn biosculptee, CompBiosculpterPod_Cycle cycle, Job job) - { - OrderToPod(cycle, biosculptee, delegate - { - chosenExtraItems.Clear(); - if (!CanReachOrHasIngredients(hauler, biosculptee, cycle)) - { - Messages.Message("BiosculpterMissingIngredients".Translate(IngredientsDescription(cycle).Named("INGREDIENTS")).CapitalizeFirst(), parent, MessageTypeDefOf.NegativeEvent, historical: false); - } - else - { - ConfigureJobForCycle(job, cycle, chosenExtraItems); - if (cycle.Props.extraRequiredIngredients != null && !devFillPodLatch) - { - if (job.def == JobDefOf.CarryToBiosculpterPod) - { - Messages.Message("BiosculpterCarryStartedMessage".Translate(hauler.Named("PAWN"), IngredientsDescription(cycle).Named("INGREDIENTS"), biosculptee.Named("DOWNED"), cycle.Props.label.Named("CYCLE")), parent, MessageTypeDefOf.SilentInput, historical: false); - } - else - { - Messages.Message("BiosculpterLoadingStartedMessage".Translate(hauler.Named("PAWN"), IngredientsDescription(cycle).Named("INGREDIENTS"), cycle.Props.label.Named("CYCLE")), parent, MessageTypeDefOf.SilentInput, historical: false); - } - } - if (hauler.jobs.TryTakeOrderedJob(job, JobTag.Misc)) - { - SetQueuedInformation(job, biosculptee); - } - } - }); - } - - public void ClearQueuedInformation() - { - SetQueuedInformation(null, null); - } - - public void SetQueuedInformation(Job job, Pawn biosculptee) - { - queuedEnterJob = job; - queuedPawn = biosculptee; - } - - public bool CanAcceptNutrition(Thing thing) - { - return allowedNutritionSettings.AllowedToAccept(thing); - } - - public bool CanAcceptOnceCycleChosen(Pawn pawn) - { - if (State != BiosculpterPodState.SelectingCycle || !PowerOn) - { - return false; - } - if (biotunedTo != null && biotunedTo != pawn) - { - return false; - } - return true; - } - - public bool PawnCarryingExtraCycleIngredients(Pawn pawn, string cycleKey, bool remove = false) - { - return PawnCarryingExtraCycleIngredients(pawn, GetCycle(cycleKey), remove); - } - - public bool PawnCarryingExtraCycleIngredients(Pawn pawn, CompBiosculpterPod_Cycle cycle, bool remove = false) - { - if (cycle.Props.extraRequiredIngredients.NullOrEmpty() || devFillPodLatch) - { - return true; - } - foreach (ThingDefCountClass extraRequiredIngredient in cycle.Props.extraRequiredIngredients) - { - if (pawn.inventory.Count(extraRequiredIngredient.thingDef) < extraRequiredIngredient.count) - { - return false; - } - } - if (remove) - { - foreach (ThingDefCountClass extraRequiredIngredient2 in cycle.Props.extraRequiredIngredients) - { - pawn.inventory.RemoveCount(extraRequiredIngredient2.thingDef, extraRequiredIngredient2.count); - } - } - return true; - } - - public bool TryAcceptPawn(Pawn pawn, string cycleKey) - { - return TryAcceptPawn(pawn, GetCycle(cycleKey)); - } - - public bool TryAcceptPawn(Pawn pawn, CompBiosculpterPod_Cycle cycle) - { - if (!CanAcceptOnceCycleChosen(pawn)) - { - return false; - } - if (!PawnCarryingExtraCycleIngredients(pawn, cycle, remove: true)) - { - return false; - } - currentCycleKey = cycle.Props.key; - innerContainer.ClearAndDestroyContents(); - pawnEnteringBiosculpter = pawn; - bool num = pawn.DeSpawnOrDeselect(); - if (pawn.holdingOwner != null) - { - pawn.holdingOwner.TryTransferToContainer(pawn, innerContainer); - } - else - { - innerContainer.TryAdd(pawn); - } - if (num) - { - Find.Selector.Select(pawn, playSound: false, forceDesignatorDeselect: false); - } - pawnEnteringBiosculpter = null; - currentCycleTicksRemaining = cycle.Props.durationDays * 60000f; - liquifiedNutrition = 0f; - devFillPodLatch = false; - ClearQueuedInformation(); - tickEntered = Find.TickManager.TicksGame; - return true; - } - - public void EjectContents(bool interrupted, bool playSounds, Map destMap = null) - { - if (destMap == null) - { - destMap = parent.Map; - } - Pawn occupant = Occupant; - currentCycleKey = null; - currentCycleTicksRemaining = 0f; - currentCyclePowerCutTicks = 0; - liquifiedNutrition = 0f; - devFillPodLatch = false; - innerContainer.TryDropAll(parent.InteractionCell, destMap, ThingPlaceMode.Near); - if (occupant != null) - { - FilthMaker.TryMakeFilth(parent.InteractionCell, destMap, ThingDefOf.Filth_PodSlime, new IntRange(3, 6).RandomInRange); - if (interrupted) - { - occupant.needs?.mood.thoughts.memories.TryGainMemory(ThoughtDefOf.SoakingWet); - occupant.health?.AddHediff(HediffDefOf.BiosculptingSickness); - } - } - if (playSounds) - { - Props.exitSound?.PlayOneShot(SoundInfo.InMap(new TargetInfo(parent.Position, parent.Map))); - } - } - - private void CycleCompleted() - { - Pawn occupant = Occupant; - CompBiosculpterPod_Cycle currentCycle = CurrentCycle; - SetBiotuned(occupant); - currentCycle.CycleCompleted(occupant); - EjectContents(interrupted: false, playSounds: true); - if (occupant != null) - { - Need_Food need_Food = occupant.needs?.food; - if (need_Food != null) - { - need_Food.CurLevelPercentage = 1f; - } - Need_Rest need_Rest = occupant.needs?.rest; - if (need_Rest != null) - { - need_Rest.CurLevelPercentage = 1f; - } - if (currentCycle.Props.gainThoughtOnCompletion != null) - { - occupant.needs?.mood?.thoughts.memories.TryGainMemory(ThoughtDefOf.AgeReversalReceived); - } - Find.HistoryEventsManager.RecordEvent(new HistoryEvent(HistoryEventDefOf.UsedBiosculpterPod, occupant.Named(HistoryEventArgsNames.Doer))); - } - if (tickEntered > 0) - { - occupant.drugs.Notify_LeftSuspension(Find.TickManager.TicksGame - tickEntered); - } - } - - private void LiquifyNutrition() - { - tmpItems.AddRange(innerContainer); - foreach (Thing tmpItem in tmpItems) - { - float num = tmpItem.GetStatValue(StatDefOf.Nutrition) * (float)tmpItem.stackCount; - if (!(num <= 0f) && !(tmpItem is Pawn)) - { - liquifiedNutrition = Mathf.Min(5f, liquifiedNutrition + num); - tmpItem.Destroy(); - } - } - tmpItems.Clear(); - } - - public override void CompTick() - { - if (!ModLister.CheckIdeology("Biosculpting")) - { - return; - } - base.CompTick(); - if (State != BiosculpterPodState.SelectingCycle || !PowerOn) - { - readyEffecter?.Cleanup(); - readyEffecter = null; - } - else if (Props.readyEffecter != null) - { - if (readyEffecter == null) - { - readyEffecter = Props.readyEffecter.Spawn(); - ColorizeEffecter(readyEffecter, Props.selectCycleColor); - readyEffecter.Trigger(parent, new TargetInfo(parent.InteractionCell, parent.Map)); - } - readyEffecter.EffectTick(parent, new TargetInfo(parent.InteractionCell, parent.Map)); - } - if (State != BiosculpterPodState.Occupied) - { - progressBarEffecter?.Cleanup(); - progressBarEffecter = null; - operatingEffecter?.Cleanup(); - operatingEffecter = null; - } - else - { - Pawn occupant = Occupant; - biotunedCountdownTicks = 4800000; - if (PowerOn) - { - int num = 1; - currentCycleTicksRemaining -= (float)num * CycleSpeedFactor; - if (currentCycleTicksRemaining <= 0f) - { - CycleCompleted(); - } - } - else - { - currentCyclePowerCutTicks++; - if (currentCyclePowerCutTicks >= 60000) - { - EjectContents(interrupted: true, playSounds: true); - Messages.Message("BiosculpterNoPowerEjectedMessage".Translate(occupant.Named("PAWN")), occupant, MessageTypeDefOf.NegativeEvent, historical: false); - } - } - if (currentCycleTicksRemaining > 0f) - { - if (progressBarEffecter == null) - { - progressBarEffecter = EffecterDefOf.ProgressBar.Spawn(); - } - progressBarEffecter.EffectTick(parent, TargetInfo.Invalid); - MoteProgressBar moteProgressBar = (progressBarEffecter.children[0] as SubEffecter_ProgressBar)?.mote; - if (moteProgressBar != null) - { - float num2 = CurrentCycle.Props.durationDays * 60000f; - moteProgressBar.progress = 1f - Mathf.Clamp01(currentCycleTicksRemaining / num2); - int num3 = (parent.RotatedSize.z - 1) / 2; - moteProgressBar.offsetZ = 0f - ((float)num3 + 0.5f); - } - if (Props.operatingEffecter != null) - { - if (!PowerOn) - { - operatingEffecter?.Cleanup(); - operatingEffecter = null; - } - else - { - if (operatingEffecter == null) - { - operatingEffecter = Props.operatingEffecter.Spawn(); - ColorizeEffecter(operatingEffecter, CurrentCycle.Props.operatingColor); - operatingEffecter.Trigger(parent, new TargetInfo(parent.InteractionCell, parent.Map)); - } - operatingEffecter.EffectTick(parent, new TargetInfo(parent.InteractionCell, parent.Map)); - } - } - } - } - if (PowerOn && biotunedCountdownTicks > 0) - { - biotunedCountdownTicks--; - } - if (biotunedCountdownTicks <= 0) - { - SetBiotuned(null); - } - SetPower(); - if (biotunedTo?.Ideo != null && !biotunedTo.Ideo.HasPrecept(PreceptDefOf.AgeReversal_Demanded)) - { - autoAgeReversal = false; - } - } - - private void SetPower() - { - if (powerTraderComp == null) - { - powerTraderComp = parent.TryGetComp(); - } - if (powerComp == null) - { - powerComp = parent.TryGetComp(); - } - if (State == BiosculpterPodState.Occupied) - { - powerTraderComp.PowerOutput = 0f - powerComp.Props.PowerConsumption; - } - else - { - powerTraderComp.PowerOutput = 0f - powerComp.Props.idlePowerDraw; - } - } - - private void ColorizeEffecter(Effecter effecter, Color color) - { - foreach (SubEffecter child in effecter.children) - { - if (child is SubEffecter_Sprayer subEffecter_Sprayer) - { - subEffecter_Sprayer.colorOverride = color * child.def.color; - } - } - } - - public override void PostDraw() - { - base.PostDraw(); - Rot4 rotation = parent.Rotation; - Vector3 s = new Vector3(parent.def.graphicData.drawSize.x * 0.8f, 1f, parent.def.graphicData.drawSize.y * 0.8f); - Vector3 drawPos = parent.DrawPos; - drawPos.y -= 0.07317074f; - Graphics.DrawMesh(MeshPool.plane10, Matrix4x4.TRS(drawPos, rotation.AsQuat, s), BackgroundMat, 0); - if (State == BiosculpterPodState.Occupied) - { - Pawn occupant = Occupant; - Vector3 drawLoc = parent.DrawPos + FloatingOffset(currentCycleTicksRemaining + (float)currentCyclePowerCutTicks); - Rot4 rotation2 = parent.Rotation; - if (rotation2 == Rot4.East || rotation2 == Rot4.West) - { - drawLoc.z += 0.2f; - } - occupant.Drawer.renderer.RenderPawnAt(drawLoc, null, neverAimWeapon: true); - } - } - - public static Vector3 FloatingOffset(float tickOffset) - { - float num = tickOffset % 500f / 500f; - float num2 = Mathf.Sin(MathF.PI * num); - float z = num2 * num2 * 0.04f; - return new Vector3(0f, 0f, z); - } - - public void GetChildHolders(List outChildren) - { - ThingOwnerUtility.AppendThingHoldersFromThings(outChildren, GetDirectlyHeldThings()); - } - - public ThingOwner GetDirectlyHeldThings() - { - return innerContainer; - } - - public StorageSettings GetStoreSettings() - { - return allowedNutritionSettings; - } - - public StorageSettings GetParentStoreSettings() - { - return parent.def.building.fixedStorageSettings; - } - - public void Notify_SettingsChanged() - { - } - - private static void OrderToPod(CompBiosculpterPod_Cycle cycle, Pawn pawn, Action giveJobAct) - { - if (cycle is CompBiosculpterPod_HealingCycle compBiosculpterPod_HealingCycle) - { - string healingDescriptionForPawn = compBiosculpterPod_HealingCycle.GetHealingDescriptionForPawn(pawn); - string text = (healingDescriptionForPawn.NullOrEmpty() ? "BiosculpterNoCoditionsToHeal".Translate(pawn.Named("PAWN"), compBiosculpterPod_HealingCycle.Props.label.Named("CYCLE")).Resolve() : ("OnCompletionOfCycle".Translate(compBiosculpterPod_HealingCycle.Props.label.Named("CYCLE")).Resolve() + ":\n\n" + healingDescriptionForPawn)); - Find.WindowStack.Add(Dialog_MessageBox.CreateConfirmation(text, giveJobAct, healingDescriptionForPawn.NullOrEmpty())); - } - else - { - giveJobAct(); - } - } - - public static Thing FindPodFor(Pawn pawn, Pawn traveller, bool biotuned) - { - if (cachedPodDefs.NullOrEmpty()) - { - cachedPodDefs = DefDatabase.AllDefs.Where((ThingDef def) => def.GetCompProperties() != null).ToList(); - } - foreach (ThingDef cachedPodDef in cachedPodDefs) - { - Thing thing = GenClosest.ClosestThingReachable(traveller.Position, pawn.Map, ThingRequest.ForDef(cachedPodDef), PathEndMode.InteractionCell, TraverseParms.For(pawn), 9999f, Validator); - if (thing != null) - { - return thing; - } - } - return null; - bool Validator(Thing t) - { - CompBiosculpterPod compBiosculpterPod = t.TryGetComp(); - if (biotuned && compBiosculpterPod.biotunedTo != traveller) - { - return false; - } - return compBiosculpterPod.CanAcceptOnceCycleChosen(traveller); - } - } - - public static bool WasLoadingCanceled(Thing thing) - { - CompBiosculpterPod compBiosculpterPod = thing.TryGetComp(); - if (compBiosculpterPod != null && compBiosculpterPod.State != 0) - { - return true; - } - return false; - } - - public void ClearCycle() - { - currentCycleKey = null; - } - - public void Notify_HauledTo(Pawn hauler, Thing thing, int count) - { - LiquifyNutrition(); - SoundDefOf.Standard_Drop.PlayOneShot(parent); - } -} -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\CompBiosculpterPod_Cycle.txt` -**相似度:** 0.7210 - -```csharp -public abstract class CompBiosculpterPod_Cycle : ThingComp -{ - private List tmpMissingResearchLabels = new List(); - - public CompProperties_BiosculpterPod_BaseCycle Props => (CompProperties_BiosculpterPod_BaseCycle)props; - - public abstract void CycleCompleted(Pawn occupant); - - public virtual string Description(Pawn tunedFor) - { - return Props.description; - } - - public List MissingResearchLabels() - { - tmpMissingResearchLabels.Clear(); - if (Props.requiredResearch.NullOrEmpty()) - { - return tmpMissingResearchLabels; - } - foreach (ResearchProjectDef item in Props.requiredResearch) - { - if (!item.IsFinished) - { - tmpMissingResearchLabels.Add(item.LabelCap); - } - } - return tmpMissingResearchLabels; - } -} -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\WorkGiver_HaulToBiosculpterPod.txt` -**相似度:** 0.7198 - -```csharp -public class WorkGiver_HaulToBiosculpterPod : WorkGiver_Scanner -{ - public override ThingRequest PotentialWorkThingRequest => ThingRequest.ForDef(ThingDefOf.BiosculpterPod); - - public override PathEndMode PathEndMode => PathEndMode.Touch; - - public override bool HasJobOnThing(Pawn pawn, Thing t, bool forced = false) - { - if (!ModLister.CheckIdeology("Biosculpting")) - { - return false; - } - if (!pawn.CanReserve(t, 1, -1, null, forced)) - { - return false; - } - if (pawn.Map.designationManager.DesignationOn(t, DesignationDefOf.Deconstruct) != null) - { - return false; - } - CompBiosculpterPod compBiosculpterPod = t.TryGetComp(); - if (compBiosculpterPod == null || !compBiosculpterPod.PowerOn || compBiosculpterPod.State != 0 || (!forced && !compBiosculpterPod.autoLoadNutrition)) - { - return false; - } - if (t.IsBurning()) - { - return false; - } - if (compBiosculpterPod.RequiredNutritionRemaining > 0f) - { - if (FindNutrition(pawn, compBiosculpterPod).Thing == null) - { - JobFailReason.Is("NoFood".Translate()); - return false; - } - return true; - } - return false; - } - - public override Job JobOnThing(Pawn pawn, Thing t, bool forced = false) - { - CompBiosculpterPod compBiosculpterPod = t.TryGetComp(); - if (compBiosculpterPod == null) - { - return null; - } - if (compBiosculpterPod.RequiredNutritionRemaining > 0f) - { - ThingCount thingCount = FindNutrition(pawn, compBiosculpterPod); - if (thingCount.Thing != null) - { - Job job = HaulAIUtility.HaulToContainerJob(pawn, thingCount.Thing, t); - job.count = Mathf.Min(job.count, thingCount.Count); - return job; - } - } - return null; - } - - private ThingCount FindNutrition(Pawn pawn, CompBiosculpterPod pod) - { - Thing thing = GenClosest.ClosestThingReachable(pawn.Position, pawn.Map, ThingRequest.ForGroup(ThingRequestGroup.FoodSourceNotPlantOrTree), PathEndMode.ClosestTouch, TraverseParms.For(pawn), 9999f, Validator); - if (thing == null) - { - return default(ThingCount); - } - int b = Mathf.CeilToInt(pod.RequiredNutritionRemaining / thing.GetStatValue(StatDefOf.Nutrition)); - return new ThingCount(thing, Mathf.Min(thing.stackCount, b)); - bool Validator(Thing x) - { - if (x.IsForbidden(pawn) || !pawn.CanReserve(x)) - { - return false; - } - if (!pod.CanAcceptNutrition(x)) - { - return false; - } - return true; - } - } -} -``` \ No newline at end of file diff --git a/MCP/vector_cache/BiosculpterPod.txt b/MCP/vector_cache/BiosculpterPod.txt deleted file mode 100644 index db82d121..00000000 --- a/MCP/vector_cache/BiosculpterPod.txt +++ /dev/null @@ -1,74 +0,0 @@ -根据向量相似度分析,与 'BiosculpterPod' 最相关的代码定义如下: - ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\CompProperties_BiosculpterPod_BaseCycle.txt` -**相似度:** 0.6754 - -```csharp -public abstract class CompProperties_BiosculpterPod_BaseCycle : CompProperties -{ - [NoTranslate] - public string key; - - [MustTranslate] - public string label; - - [MustTranslate] - public string description; - - [NoTranslate] - public string iconPath; - - public float durationDays; - - public Color operatingColor = new Color(0.5f, 0.7f, 0.5f); - - public ThoughtDef gainThoughtOnCompletion; - - public List requiredResearch; - - public List extraRequiredIngredients; - - private Texture2D icon; - - public Texture2D Icon - { - get - { - if (icon == null) - { - icon = ContentFinder.Get(iconPath); - } - return icon; - } - } - - public string LabelCap => label.CapitalizeFirst(); -} -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\CompProperties_BiosculpterPod_PleasureCycle.txt` -**相似度:** 0.6624 - -```csharp -public class CompProperties_BiosculpterPod_PleasureCycle : CompProperties_BiosculpterPod_BaseCycle -{ - public CompProperties_BiosculpterPod_PleasureCycle() - { - compClass = typeof(CompBiosculpterPod_PleasureCycle); - } -} -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\CompProperties_BiosculpterPod_AgeReversalCycle.txt` -**相似度:** 0.6461 - -```csharp -public class CompProperties_BiosculpterPod_AgeReversalCycle : CompProperties_BiosculpterPod_BaseCycle -{ - public CompProperties_BiosculpterPod_AgeReversalCycle() - { - compClass = typeof(CompBiosculpterPod_AgeReversalCycle); - } -} -``` \ No newline at end of file diff --git a/MCP/vector_cache/Building_Bed.txt b/MCP/vector_cache/Building_Bed.txt deleted file mode 100644 index 10294a2c..00000000 --- a/MCP/vector_cache/Building_Bed.txt +++ /dev/null @@ -1,1122 +0,0 @@ -根据向量相似度分析,与 'Building_Bed' 最相关的代码定义如下: - ---- -**文件路径 (精确匹配):** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\Building_Bed.txt` - -```csharp -public class Building_Bed : Building -{ - private BedOwnerType forOwnerType; - - private bool medicalInt; - - private bool alreadySetDefaultMed; - - private static int lastBedOwnerSetChangeFrame = -1; - - private static List tmpOrderedInteractionCells = new List(8); - - private static readonly Color SheetColorNormal = new Color(0.6313726f, 71f / 85f, 0.7058824f); - - private static readonly Color SheetColorRoyal = new Color(57f / 85f, 0.9137255f, 38f / 51f); - - public static readonly Color SheetColorForPrisoner = new Color(1f, 61f / 85f, 11f / 85f); - - private static readonly Color SheetColorMedical = new Color(33f / 85f, 53f / 85f, 0.8862745f); - - private static readonly Color SheetColorMedicalForPrisoner = new Color(0.654902f, 32f / 85f, 13f / 85f); - - private static readonly Color SheetColorForSlave = new Color32(252, 244, 3, byte.MaxValue); - - private static readonly Color SheetColorMedicalForSlave = new Color32(153, 148, 0, byte.MaxValue); - - private static readonly BedInteractionCellSearchPattern defaultBedInteractionCellsOrder = new BedInteractionCellSearchPattern(); - - public List OwnersForReading => CompAssignableToPawn.AssignedPawnsForReading; - - public CompAssignableToPawn CompAssignableToPawn => GetComp(); - - public bool ForPrisoners - { - get - { - return forOwnerType == BedOwnerType.Prisoner; - } - set - { - if (value == ForPrisoners || !def.building.bed_humanlike || ForHumanBabies) - { - return; - } - if (Current.ProgramState != ProgramState.Playing && Scribe.mode != 0) - { - Log.Error("Tried to set ForPrisoners while game mode was " + Current.ProgramState); - return; - } - RemoveAllOwners(); - if (value) - { - forOwnerType = BedOwnerType.Prisoner; - } - else - { - forOwnerType = BedOwnerType.Colonist; - Log.Error("Bed ForPrisoners=false, but should it be for for colonists or slaves? Set ForOwnerType instead."); - } - Notify_ColorChanged(); - NotifyRoomBedTypeChanged(); - } - } - - public bool ForSlaves => ForOwnerType == BedOwnerType.Slave; - - public bool ForColonists => ForOwnerType == BedOwnerType.Colonist; - - public bool ForHumanBabies - { - get - { - if (def.building.bed_humanlike) - { - return def.building.bed_maxBodySize < LifeStageDefOf.HumanlikeChild.bodySizeFactor; - } - return false; - } - } - - public BedOwnerType ForOwnerType - { - get - { - return forOwnerType; - } - set - { - if (value != forOwnerType && def.building.bed_humanlike && !ForHumanBabies && (value != BedOwnerType.Slave || ModLister.CheckIdeology("Slavery"))) - { - RemoveAllOwners(); - forOwnerType = value; - Notify_ColorChanged(); - NotifyRoomBedTypeChanged(); - } - } - } - - public bool Medical - { - get - { - return medicalInt; - } - set - { - if (value != medicalInt && (!value || def.building.bed_canBeMedical)) - { - RemoveAllOwners(); - medicalInt = value; - Notify_ColorChanged(); - if (base.Spawned) - { - base.Map.mapDrawer.MapMeshDirty(base.Position, MapMeshFlagDefOf.Things); - NotifyRoomBedTypeChanged(); - } - FacilityChanged(); - } - } - } - - public bool AnyUnownedSleepingSlot - { - get - { - if (Medical) - { - Log.Warning("Tried to check for unowned sleeping slot on medical bed " + this); - return false; - } - return CompAssignableToPawn.HasFreeSlot; - } - } - - public int TotalSleepingSlots - { - get - { - if (Medical) - { - Log.Warning("Tried to check for total sleeping slots on medical bed " + this); - return 0; - } - return CompAssignableToPawn.TotalSlots; - } - } - - public bool AnyUnoccupiedSleepingSlot - { - get - { - for (int i = 0; i < SleepingSlotsCount; i++) - { - if (GetCurOccupant(i) == null) - { - return true; - } - } - return false; - } - } - - public IEnumerable CurOccupants - { - get - { - for (int i = 0; i < SleepingSlotsCount; i++) - { - Pawn curOccupant = GetCurOccupant(i); - if (curOccupant != null) - { - yield return curOccupant; - } - } - } - } - - public bool AnyOccupants - { - get - { - for (int i = 0; i < SleepingSlotsCount; i++) - { - if (GetCurOccupant(i) != null) - { - return true; - } - } - return false; - } - } - - public override Color DrawColor - { - get - { - if (def.MadeFromStuff) - { - return base.DrawColor; - } - return DrawColorTwo; - } - } - - public override Color DrawColorTwo - { - get - { - if (def.building != null && !def.building.bed_UseSheetColor) - { - return base.DrawColorTwo; - } - bool medical = Medical; - switch (forOwnerType) - { - case BedOwnerType.Prisoner: - if (!medical) - { - return SheetColorForPrisoner; - } - return SheetColorMedicalForPrisoner; - case BedOwnerType.Slave: - if (!medical) - { - return SheetColorForSlave; - } - return SheetColorMedicalForSlave; - default: - if (medical) - { - return SheetColorMedical; - } - if (def == ThingDefOf.RoyalBed) - { - return SheetColorRoyal; - } - return SheetColorNormal; - } - } - } - - public int SleepingSlotsCount => BedUtility.GetSleepingSlotsCount(def.size); - - private bool PlayerCanSeeOwners => CompAssignableToPawn.PlayerCanSeeAssignments; - - public override IntVec3 InteractionCell => FindPreferredInteractionCell(base.Position) ?? base.InteractionCell; - - public override void SpawnSetup(Map map, bool respawningAfterLoad) - { - base.SpawnSetup(map, respawningAfterLoad); - Region validRegionAt_NoRebuild = map.regionGrid.GetValidRegionAt_NoRebuild(base.Position); - if (validRegionAt_NoRebuild != null && validRegionAt_NoRebuild.Room.IsPrisonCell) - { - ForPrisoners = true; - } - if (!alreadySetDefaultMed) - { - alreadySetDefaultMed = true; - if (def.building.bed_defaultMedical) - { - Medical = true; - } - } - if (!respawningAfterLoad) - { - District district = this.GetDistrict(); - if (district != null) - { - district.Notify_RoomShapeOrContainedBedsChanged(); - district.Room.Notify_RoomShapeChanged(); - } - } - } - - public override void DeSpawn(DestroyMode mode = DestroyMode.Vanish) - { - if (mode != DestroyMode.WillReplace) - { - if (mode != 0) - { - RemoveAllOwners(mode == DestroyMode.KillFinalize); - } - else if (InstallBlueprintUtility.ExistingBlueprintFor(this) == null) - { - foreach (Pawn item in OwnersForReading) - { - Messages.Message("MessageBedLostAssignment".Translate(def, item), new LookTargets(this, item), MessageTypeDefOf.CautionInput, historical: false); - } - } - ForOwnerType = BedOwnerType.Colonist; - Medical = false; - alreadySetDefaultMed = false; - } - District district = this.GetDistrict(); - base.DeSpawn(mode); - if (district != null) - { - district.Notify_RoomShapeOrContainedBedsChanged(); - district.Room.Notify_RoomShapeChanged(); - } - } - - public override void ExposeData() - { - base.ExposeData(); - Scribe_Values.Look(ref medicalInt, "medical", defaultValue: false); - Scribe_Values.Look(ref alreadySetDefaultMed, "alreadySetDefaultMed", defaultValue: false); - Scribe_Values.Look(ref forOwnerType, "forOwnerType", BedOwnerType.Colonist); - BackCompatibility.PostExposeData(this); - } - - public override void DrawExtraSelectionOverlays() - { - base.DrawExtraSelectionOverlays(); - Room room = this.GetRoom(); - if (room != null && RoomCanBePrisonCell(room)) - { - room.DrawFieldEdges(); - } - } - - public static bool RoomCanBePrisonCell(Room r) - { - if (r.ProperRoom) - { - return !r.IsHuge; - } - return false; - } - - public override IEnumerable GetGizmos() - { - foreach (Gizmo gizmo in base.GetGizmos()) - { - yield return gizmo; - } - if (base.Faction != Faction.OfPlayer) - { - yield break; - } - if (def.building.bed_humanlike && !ForHumanBabies) - { - if (ModsConfig.IdeologyActive) - { - yield return new Command_SetBedOwnerType(this); - } - else - { - Command_Toggle command_Toggle = new Command_Toggle(); - command_Toggle.defaultLabel = "CommandBedSetForPrisonersLabel".Translate(); - command_Toggle.defaultDesc = "CommandBedSetForPrisonersDesc".Translate(); - command_Toggle.icon = ContentFinder.Get("UI/Commands/ForPrisoners"); - command_Toggle.isActive = () => ForPrisoners; - command_Toggle.toggleAction = delegate - { - SetBedOwnerTypeByInterface((!ForPrisoners) ? BedOwnerType.Prisoner : BedOwnerType.Colonist); - }; - if (!RoomCanBePrisonCell(this.GetRoom()) && !ForPrisoners) - { - command_Toggle.Disable("CommandBedSetForPrisonersFailOutdoors".Translate()); - } - command_Toggle.hotKey = KeyBindingDefOf.Misc3; - command_Toggle.turnOffSound = null; - command_Toggle.turnOnSound = null; - yield return command_Toggle; - } - } - if (def.building.bed_canBeMedical) - { - Command_Toggle command_Toggle2 = new Command_Toggle(); - command_Toggle2.defaultLabel = "CommandBedSetAsMedicalLabel".Translate(); - command_Toggle2.defaultDesc = "CommandBedSetAsMedicalDesc".Translate(); - command_Toggle2.icon = ContentFinder.Get("UI/Commands/AsMedical"); - command_Toggle2.isActive = () => Medical; - command_Toggle2.toggleAction = delegate - { - Medical = !Medical; - }; - command_Toggle2.hotKey = KeyBindingDefOf.Misc2; - yield return command_Toggle2; - } - } - - public void SetBedOwnerTypeByInterface(BedOwnerType ownerType) - { - if (lastBedOwnerSetChangeFrame == Time.frameCount) - { - return; - } - lastBedOwnerSetChangeFrame = Time.frameCount; - ((ForOwnerType != ownerType) ? SoundDefOf.Checkbox_TurnedOn : SoundDefOf.Checkbox_TurnedOff).PlayOneShotOnCamera(); - List bedsToAffect = new List(); - foreach (Building_Bed item in Find.Selector.SelectedObjects.OfType()) - { - if (item.ForOwnerType == ownerType) - { - continue; - } - Room room = item.GetRoom(); - if (room == null && ownerType != BedOwnerType.Prisoner) - { - if (!bedsToAffect.Contains(item)) - { - bedsToAffect.Add(item); - } - continue; - } - foreach (Building_Bed containedBed in room.ContainedBeds) - { - if (containedBed.ForOwnerType != ownerType) - { - if (containedBed.ForOwnerType == BedOwnerType.Prisoner && !bedsToAffect.Contains(containedBed)) - { - bedsToAffect.Add(containedBed); - } - else if (ownerType == BedOwnerType.Prisoner && RoomCanBePrisonCell(room) && !bedsToAffect.Contains(containedBed)) - { - bedsToAffect.Add(containedBed); - } - else if (containedBed == item && !bedsToAffect.Contains(containedBed)) - { - bedsToAffect.Add(containedBed); - } - } - } - } - Action action = delegate - { - List list = new List(); - List list2 = new List(); - foreach (Building_Bed item2 in bedsToAffect) - { - District district = item2.GetDistrict(); - Room room2 = district.Room; - if (ownerType == BedOwnerType.Prisoner && room2.TouchesMapEdge) - { - item2.ForOwnerType = BedOwnerType.Colonist; - } - else - { - item2.ForOwnerType = ownerType; - } - if (!room2.TouchesMapEdge) - { - if (!list2.Contains(room2)) - { - list2.Add(room2); - } - if (!list.Contains(district)) - { - list.Add(district); - } - } - } - foreach (District item3 in list) - { - item3.Notify_RoomShapeOrContainedBedsChanged(); - } - foreach (Room item4 in list2) - { - item4.Notify_RoomShapeChanged(); - } - }; - if (bedsToAffect.Where((Building_Bed b) => b.OwnersForReading.Any((Pawn owner) => owner.RaceProps.Humanlike) && b != this).Count() == 0) - { - action(); - return; - } - StringBuilder stringBuilder = new StringBuilder(); - if (!ModsConfig.IdeologyActive) - { - if (ownerType == BedOwnerType.Prisoner) - { - stringBuilder.Append("TurningOnPrisonerBedWarning".Translate()); - } - else - { - stringBuilder.Append("TurningOffPrisonerBedWarning".Translate()); - } - } - else - { - stringBuilder.Append("ChangingOwnerTypeBedWarning".Translate()); - } - stringBuilder.AppendLine(); - foreach (Building_Bed item5 in bedsToAffect) - { - if (ownerType != item5.ForOwnerType) - { - for (int i = 0; i < item5.OwnersForReading.Count; i++) - { - stringBuilder.AppendLine(); - stringBuilder.Append(item5.OwnersForReading[i].LabelShort); - } - } - } - stringBuilder.AppendLine(); - stringBuilder.AppendLine(); - stringBuilder.Append("AreYouSure".Translate()); - Find.WindowStack.Add(Dialog_MessageBox.CreateConfirmation(stringBuilder.ToString(), action)); - } - - public override string GetInspectString() - { - StringBuilder stringBuilder = new StringBuilder(); - stringBuilder.Append(base.GetInspectString()); - if (def.building.bed_humanlike && def.building.bed_DisplayOwnerType && base.Faction == Faction.OfPlayer) - { - switch (ForOwnerType) - { - case BedOwnerType.Prisoner: - stringBuilder.AppendInNewLine("ForPrisonerUse".Translate()); - break; - case BedOwnerType.Slave: - stringBuilder.AppendInNewLine("ForSlaveUse".Translate()); - break; - case BedOwnerType.Colonist: - stringBuilder.AppendInNewLine("ForColonistUse".Translate()); - break; - default: - Log.Error($"Unknown bed owner type: {ForOwnerType}"); - break; - } - } - if (Medical) - { - stringBuilder.AppendInNewLine("MedicalBed".Translate()); - if (base.Spawned) - { - stringBuilder.AppendInNewLine("RoomInfectionChanceFactor".Translate() + ": " + this.GetRoom().GetStat(RoomStatDefOf.InfectionChanceFactor).ToStringPercent()); - } - } - else if (PlayerCanSeeOwners && def.building.bed_DisplayOwnersInInspectString) - { - if (OwnersForReading.Count == 0) - { - stringBuilder.AppendInNewLine("Owner".Translate() + ": " + "Nobody".Translate()); - } - else if (OwnersForReading.Count == 1) - { - stringBuilder.AppendInNewLine("Owner".Translate() + ": " + OwnersForReading[0].Label); - } - else - { - stringBuilder.AppendInNewLine("Owners".Translate() + ": "); - bool flag = false; - for (int i = 0; i < OwnersForReading.Count; i++) - { - if (flag) - { - stringBuilder.Append(", "); - } - flag = true; - stringBuilder.Append(OwnersForReading[i].LabelShort); - } - } - if (OwnersForReading.Count == 1 && ChildcareUtility.CanSuckle(OwnersForReading[0], out var _)) - { - Pawn p = OwnersForReading[0]; - float ambientTemperature = base.AmbientTemperature; - if (!p.SafeTemperatureRange().IncludesEpsilon(ambientTemperature)) - { - stringBuilder.AppendInNewLine("BedUnsafeTemperature".Translate().Colorize(ColoredText.WarningColor)); - } - else if (!p.ComfortableTemperatureRange().IncludesEpsilon(ambientTemperature)) - { - stringBuilder.AppendInNewLine("BedUncomfortableTemperature".Translate()); - } - } - } - return stringBuilder.ToString(); - } - - public override IEnumerable GetFloatMenuOptions(Pawn myPawn) - { - FloatMenuOption bedRestFloatMenuOption = GetBedRestFloatMenuOption(myPawn); - if (bedRestFloatMenuOption != null) - { - yield return bedRestFloatMenuOption; - } - } - - public FloatMenuOption GetBedRestFloatMenuOption(Pawn myPawn) - { - if (myPawn.RaceProps.Humanlike && !ForPrisoners && Medical && !myPawn.Drafted && base.Faction == Faction.OfPlayer && RestUtility.CanUseBedEver(myPawn, def)) - { - if (!HealthAIUtility.ShouldSeekMedicalRest(myPawn)) - { - if (myPawn.health.surgeryBills.AnyShouldDoNow && !WorkGiver_PatientGoToBedTreatment.AnyAvailableDoctorFor(myPawn)) - { - return new FloatMenuOption("UseMedicalBed".Translate() + " (" + "NoDoctor".Translate() + ")", null); - } - return new FloatMenuOption("UseMedicalBed".Translate() + " (" + "NotInjured".Translate() + ")", null); - } - if (myPawn.IsSlaveOfColony && !ForSlaves) - { - return new FloatMenuOption("UseMedicalBed".Translate() + " (" + "NotForSlaves".Translate() + ")", null); - } - Action action = delegate - { - if (!ForPrisoners && Medical && myPawn.CanReserveAndReach(this, PathEndMode.ClosestTouch, Danger.Deadly, SleepingSlotsCount, -1, null, ignoreOtherReservations: true)) - { - if (myPawn.CurJobDef == JobDefOf.LayDown && myPawn.CurJob.GetTarget(TargetIndex.A).Thing == this) - { - myPawn.CurJob.restUntilHealed = true; - } - else - { - Job job = JobMaker.MakeJob(JobDefOf.LayDown, this); - job.restUntilHealed = true; - myPawn.jobs.TryTakeOrderedJob(job, JobTag.Misc); - } - myPawn.mindState.ResetLastDisturbanceTick(); - } - }; - return FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption("UseMedicalBed".Translate(), action), myPawn, this, (AnyUnoccupiedSleepingSlot ? "ReservedBy" : "SomeoneElseSleeping").CapitalizeFirst()); - } - return null; - } - - public override void DrawGUIOverlay() - { - if (Medical || Find.CameraDriver.CurrentZoom != 0 || !PlayerCanSeeOwners) - { - return; - } - Color defaultThingLabelColor = GenMapUI.DefaultThingLabelColor; - if (!OwnersForReading.Any()) - { - GenMapUI.DrawThingLabel(this, "Unowned".Translate(), defaultThingLabelColor); - return; - } - if (OwnersForReading.Count == 1) - { - Pawn pawn = OwnersForReading[0]; - if ((!pawn.InBed() || pawn.CurrentBed() != this) && (!pawn.RaceProps.Animal || Prefs.AnimalNameMode.ShouldDisplayAnimalName(pawn))) - { - GenMapUI.DrawThingLabel(this, pawn.LabelShort, defaultThingLabelColor); - } - return; - } - for (int i = 0; i < OwnersForReading.Count; i++) - { - Pawn pawn2 = OwnersForReading[i]; - if (!pawn2.InBed() || OwnersForReading[i].CurrentBed() != this || !(pawn2.Position == GetSleepingSlotPos(i))) - { - if (pawn2.RaceProps.Animal && !Prefs.AnimalNameMode.ShouldDisplayAnimalName(pawn2)) - { - break; - } - GenMapUI.DrawThingLabel(GetMultiOwnersLabelScreenPosFor(i), pawn2.LabelShort, defaultThingLabelColor); - } - } - } - - public Pawn GetCurOccupant(int slotIndex) - { - if (!base.Spawned) - { - return null; - } - IntVec3 sleepingSlotPos = GetSleepingSlotPos(slotIndex); - List list = base.Map.thingGrid.ThingsListAt(sleepingSlotPos); - for (int i = 0; i < list.Count; i++) - { - if (list[i] is Pawn { CurJob: not null } pawn && pawn.GetPosture().InBed()) - { - return pawn; - } - } - return null; - } - - public int GetCurOccupantSlotIndex(Pawn curOccupant) - { - for (int i = 0; i < SleepingSlotsCount; i++) - { - if (GetCurOccupant(i) == curOccupant) - { - return i; - } - } - Log.Error("Could not find pawn " + curOccupant?.ToString() + " on any of sleeping slots."); - return 0; - } - - public Pawn GetCurOccupantAt(IntVec3 pos) - { - for (int i = 0; i < SleepingSlotsCount; i++) - { - if (GetSleepingSlotPos(i) == pos) - { - return GetCurOccupant(i); - } - } - return null; - } - - public IntVec3 GetSleepingSlotPos(int index) - { - return BedUtility.GetSleepingSlotPos(index, base.Position, base.Rotation, def.size); - } - - public IntVec3 GetFootSlotPos(int index) - { - return BedUtility.GetFeetSlotPos(index, base.Position, base.Rotation, def.size); - } - - public bool IsOwner(Pawn p) - { - int? assignedSleepingSlot; - return IsOwner(p, out assignedSleepingSlot); - } - - public bool IsOwner(Pawn p, out int? assignedSleepingSlot) - { - int num = GetComp().AssignedPawnsForReading.IndexOf(p); - if (num >= 0) - { - assignedSleepingSlot = num; - return true; - } - assignedSleepingSlot = null; - return false; - } - - private void RemoveAllOwners(bool destroyed = false) - { - for (int num = OwnersForReading.Count - 1; num >= 0; num--) - { - Pawn pawn = OwnersForReading[num]; - pawn.ownership.UnclaimBed(); - string key = "MessageBedLostAssignment"; - if (destroyed) - { - key = "MessageBedDestroyed"; - } - Messages.Message(key.Translate(def, pawn), new LookTargets(this, pawn), MessageTypeDefOf.CautionInput, historical: false); - } - } - - private void NotifyRoomBedTypeChanged() - { - this.GetRoom()?.Notify_BedTypeChanged(); - } - - public void NotifyRoomAssignedPawnsChanged() - { - this.GetRoom()?.Notify_BedTypeChanged(); - } - - private void FacilityChanged() - { - CompFacility compFacility = this.TryGetComp(); - CompAffectedByFacilities compAffectedByFacilities = this.TryGetComp(); - compFacility?.Notify_ThingChanged(); - compAffectedByFacilities?.Notify_ThingChanged(); - } - - private Vector3 GetMultiOwnersLabelScreenPosFor(int slotIndex) - { - IntVec3 sleepingSlotPos = GetSleepingSlotPos(slotIndex); - Vector3 drawPos = DrawPos; - if (base.Rotation.IsHorizontal) - { - drawPos.z = (float)sleepingSlotPos.z + 0.6f; - } - else - { - drawPos.x = (float)sleepingSlotPos.x + 0.5f; - drawPos.z += -0.4f; - } - Vector2 vector = drawPos.MapToUIPosition(); - if (!base.Rotation.IsHorizontal && SleepingSlotsCount == 2) - { - vector = AdjustOwnerLabelPosToAvoidOverlapping(vector, slotIndex); - } - return vector; - } - - private Vector3 AdjustOwnerLabelPosToAvoidOverlapping(Vector3 screenPos, int slotIndex) - { - Text.Font = GameFont.Tiny; - float num = Text.CalcSize(OwnersForReading[slotIndex].LabelShort).x + 1f; - Vector2 vector = DrawPos.MapToUIPosition(); - float num2 = Mathf.Abs(screenPos.x - vector.x); - IntVec3 sleepingSlotPos = GetSleepingSlotPos(slotIndex); - if (num > num2 * 2f) - { - float num3 = 0f; - num3 = ((slotIndex != 0) ? ((float)GetSleepingSlotPos(0).x) : ((float)GetSleepingSlotPos(1).x)); - if ((float)sleepingSlotPos.x < num3) - { - screenPos.x -= (num - num2 * 2f) / 2f; - } - else - { - screenPos.x += (num - num2 * 2f) / 2f; - } - } - return screenPos; - } - - private bool RemoveLeastDesirableInteractionCells(List cells, Map map) - { - cells.RemoveAll(map, (Map innerMap, IntVec3 cell) => !cell.Standable(innerMap) || !TouchPathEndModeUtility.IsAdjacentOrInsideAndAllowedToTouch(cell, new LocalTargetInfo(this), map.pathing.Normal)); - if (cells.RemoveAll_IfNotAll(map, delegate(Map innerMap, IntVec3 cell) - { - Building building = map.edificeGrid[cell]; - return building == null || building.def?.IsBed != true; - })) - { - return cells.RemoveAll_IfNotAll(map, (Map innerMap, IntVec3 cell) => cell.GetDoor(map) == null); - } - return false; - } - - public IntVec3? FindPreferredInteractionCell(IntVec3 occupantLocation, CellSearchPattern customSearchPattern = null) - { - CellRect cellRect = this.OccupiedRect(); - if (!cellRect.Contains(occupantLocation)) - { - Log.Error($"interiorLocation {occupantLocation} is not within the bounds of this bed {cellRect}."); - return null; - } - tmpOrderedInteractionCells.Clear(); - (customSearchPattern ?? defaultBedInteractionCellsOrder).AddCellsToList(tmpOrderedInteractionCells, this, cellRect, occupantLocation, base.Rotation); - RemoveLeastDesirableInteractionCells(tmpOrderedInteractionCells, base.Map); - if (tmpOrderedInteractionCells.Count == 0) - { - return null; - } - return tmpOrderedInteractionCells[0]; - } -} -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\RoomRoleWorker_Bedroom.txt` -**相似度:** 0.5705 - -```csharp -public class RoomRoleWorker_Bedroom : RoomRoleWorker -{ - private static List tmpBeds = new List(); - - private static List children = new List(); - - private static List adults = new List(); - - public override float GetScore(Room room) - { - tmpBeds.Clear(); - List containedAndAdjacentThings = room.ContainedAndAdjacentThings; - int num = 0; - for (int i = 0; i < containedAndAdjacentThings.Count; i++) - { - if (containedAndAdjacentThings[i] is Building_Bed building_Bed && building_Bed.def.building.bed_humanlike && building_Bed.def.building.bed_countsForBedroomOrBarracks) - { - if (building_Bed.Medical || building_Bed.ForPrisoners) - { - tmpBeds.Clear(); - return 0f; - } - num++; - tmpBeds.Add(building_Bed); - } - } - if (num == 0) - { - tmpBeds.Clear(); - return 0f; - } - bool num2 = IsBedroom(tmpBeds); - tmpBeds.Clear(); - if (!num2) - { - return 0f; - } - return 100000f; - } - - public static bool IsBedroom(List beds) - { - children.Clear(); - adults.Clear(); - bool result = IsBedroomHelper(beds); - children.Clear(); - adults.Clear(); - return result; - } - - private static bool IsBedroomHelper(List beds) - { - List list = null; - int num = 0; - int num2 = 0; - int num3 = 0; - foreach (Building_Bed bed in beds) - { - List ownersForReading = bed.OwnersForReading; - if (ownersForReading.NullOrEmpty() && bed.def.building.bed_emptyCountsForBarracks) - { - num++; - continue; - } - if (ownersForReading.Count > 0) - { - num2++; - } - bool flag = false; - foreach (Pawn item in ownersForReading) - { - if (item.DevelopmentalStage.Juvenile()) - { - children.Add(item); - continue; - } - adults.Add(item); - if (list == null) - { - list = item.GetLoveCluster(); - } - if (!list.Contains(item)) - { - flag = true; - } - } - if (flag) - { - num3++; - } - } - if (num == 1 && num2 == 0) - { - return true; - } - if (num == 0 && num2 == 1) - { - return true; - } - if (num > 0) - { - return false; - } - if (adults.NullOrEmpty()) - { - return true; - } - if (num3 > 0) - { - return false; - } - foreach (Pawn child in children) - { - Pawn mother = child.GetMother(); - Pawn father = child.GetFather(); - if (!adults.Any((Pawn adult) => adult == mother || adult == father)) - { - return false; - } - } - return true; - } -} -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\RoomRoleWorker_Barracks.txt` -**相似度:** 0.5548 - -```csharp -public class RoomRoleWorker_Barracks : RoomRoleWorker -{ - private static List tmpBeds = new List(); - - public override float GetScore(Room room) - { - tmpBeds.Clear(); - int num = 0; - List containedAndAdjacentThings = room.ContainedAndAdjacentThings; - for (int i = 0; i < containedAndAdjacentThings.Count; i++) - { - if (containedAndAdjacentThings[i] is Building_Bed building_Bed && building_Bed.def.building.bed_humanlike && building_Bed.def.building.bed_countsForBedroomOrBarracks) - { - if (building_Bed.ForPrisoners) - { - tmpBeds.Clear(); - return 0f; - } - tmpBeds.Add(building_Bed); - if (!building_Bed.Medical) - { - num++; - } - } - } - bool num2 = RoomRoleWorker_Bedroom.IsBedroom(tmpBeds); - tmpBeds.Clear(); - if (num2) - { - return 0f; - } - return (float)num * 100100f; - } -} -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld.BaseGen\SymbolResolver_PrisonerBed.txt` -**相似度:** 0.5535 - -```csharp -public class SymbolResolver_PrisonerBed : SymbolResolver -{ - public override void Resolve(ResolveParams rp) - { - ResolveParams resolveParams = rp; - Action prevPostThingSpawn = resolveParams.postThingSpawn; - resolveParams.postThingSpawn = delegate(Thing x) - { - if (prevPostThingSpawn != null) - { - prevPostThingSpawn(x); - } - if (x is Building_Bed building_Bed) - { - building_Bed.ForPrisoners = true; - } - }; - BaseGen.symbolStack.Push("bed", resolveParams); - } -} -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\WorkGiver_TakeToBed.txt` -**相似度:** 0.5270 - -```csharp -public abstract class WorkGiver_TakeToBed : WorkGiver_Scanner -{ - protected Building_Bed FindBed(Pawn pawn, Pawn patient) - { - return RestUtility.FindBedFor(patient, pawn, checkSocialProperness: false, ignoreOtherReservations: false, patient.GuestStatus); - } -} -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\CompAssignableToPawn_DeathrestCasket.txt` -**相似度:** 0.5238 - -```csharp -public class CompAssignableToPawn_DeathrestCasket : CompAssignableToPawn_Bed -{ - public override string CompInspectStringExtra() - { - return null; - } - - public override bool AssignedAnything(Pawn pawn) - { - return pawn.ownership.AssignedDeathrestCasket != null; - } - - public override void TryAssignPawn(Pawn pawn) - { - Building_Bed building_Bed = (Building_Bed)parent; - pawn.ownership.ClaimDeathrestCasket(building_Bed); - building_Bed.NotifyRoomAssignedPawnsChanged(); - } - - public override void TryUnassignPawn(Pawn pawn, bool sort = true, bool uninstall = false) - { - Building_Bed ownedBed = pawn.ownership.OwnedBed; - pawn.ownership.UnclaimDeathrestCasket(); - ownedBed?.NotifyRoomAssignedPawnsChanged(); - } - - public override AcceptanceReport CanAssignTo(Pawn pawn) - { - Building_Bed building_Bed = (Building_Bed)parent; - if (pawn.BodySize > building_Bed.def.building.bed_maxBodySize) - { - return "TooLargeForBed".Translate(); - } - if (building_Bed.ForSlaves && !pawn.IsSlave) - { - return "CannotAssignBedToColonist".Translate(); - } - if (building_Bed.ForColonists && pawn.IsSlave) - { - return "CannotAssignBedToSlave".Translate(); - } - CompDeathrestBindable compDeathrestBindable = parent.TryGetComp(); - if (compDeathrestBindable != null && compDeathrestBindable.BoundPawn != null && compDeathrestBindable.BoundPawn != pawn) - { - return "CannotAssignAlreadyBound".Translate(compDeathrestBindable.BoundPawn); - } - Gene_Deathrest gene_Deathrest = pawn.genes?.GetFirstGeneOfType(); - if (gene_Deathrest == null) - { - return "CannotAssignBedCannotDeathrest".Translate(); - } - if (compDeathrestBindable != null && gene_Deathrest.BindingWillExceedStackLimit(compDeathrestBindable)) - { - return "CannotAssignBedCannotBindToMoreBuildings".Translate(NamedArgumentUtility.Named(parent.def, "BUILDING")); - } - return AcceptanceReport.WasAccepted; - } - - protected override void PostPostExposeData() - { - if (Scribe.mode == LoadSaveMode.PostLoadInit && ModsConfig.BiotechActive && assignedPawns.RemoveAll((Pawn x) => x.ownership.AssignedDeathrestCasket != parent) > 0) - { - Log.Warning(parent.ToStringSafe() + " had pawns assigned that don't have it as an assigned bed. Removing."); - } - } -} -``` \ No newline at end of file diff --git a/MCP/vector_cache/CarryToBiosculpterPod-JobDefOf-JobDriver_CarryToBiosculpterPod.txt b/MCP/vector_cache/CarryToBiosculpterPod-JobDefOf-JobDriver_CarryToBiosculpterPod.txt deleted file mode 100644 index cbec2925..00000000 --- a/MCP/vector_cache/CarryToBiosculpterPod-JobDefOf-JobDriver_CarryToBiosculpterPod.txt +++ /dev/null @@ -1,198 +0,0 @@ -根据向量相似度分析,与 'JobDriver_CarryToBiosculpterPod, JobDefOf, CarryToBiosculpterPod' 最相关的代码定义如下: - ---- -**文件路径 (精确匹配):** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\JobDriver_CarryToBiosculpterPod.txt` - -```csharp -public class JobDriver_CarryToBiosculpterPod : JobDriver -{ - private const TargetIndex TakeeInd = TargetIndex.A; - - private const TargetIndex IngredientInd = TargetIndex.B; - - private const TargetIndex PodInd = TargetIndex.C; - - private List pickedUpIngredients = new List(); - - private List thingsToTransfer = new List(); - - private Pawn Takee => (Pawn)job.GetTarget(TargetIndex.A).Thing; - - private CompBiosculpterPod Pod => job.GetTarget(TargetIndex.C).Thing.TryGetComp(); - - public override bool TryMakePreToilReservations(bool errorOnFailed) - { - if (!pawn.Reserve(Takee, job, 1, -1, null, errorOnFailed) || !pawn.Reserve(Pod.parent, job, 1, -1, null, errorOnFailed)) - { - return false; - } - List targetQueue = job.GetTargetQueue(TargetIndex.B); - for (int i = 0; i < targetQueue.Count; i++) - { - if (!pawn.Reserve(targetQueue[i], job, 1, -1, null, errorOnFailed)) - { - return false; - } - } - return true; - } - - protected override IEnumerable MakeNewToils() - { - if (!ModLister.CheckIdeology("Biosculpting")) - { - yield break; - } - AddFinishAction(delegate - { - if (Pod != null) - { - if (Pod.queuedEnterJob == job) - { - Pod.ClearQueuedInformation(); - } - if (Pod.Occupant != Takee) - { - foreach (Thing pickedUpIngredient in pickedUpIngredients) - { - Thing lastResultingThing; - if (pawn.inventory.Contains(pickedUpIngredient)) - { - pawn.inventory.innerContainer.TryDrop(pickedUpIngredient, ThingPlaceMode.Near, out lastResultingThing); - } - else if (Takee.inventory.Contains(pickedUpIngredient)) - { - Takee.inventory.innerContainer.TryDrop(pickedUpIngredient, ThingPlaceMode.Near, out lastResultingThing); - } - } - } - } - }); - this.FailOnDestroyedOrNull(TargetIndex.A); - this.FailOnDestroyedOrNull(TargetIndex.C); - this.FailOnAggroMentalState(TargetIndex.A); - this.FailOn(() => job.biosculpterCycleKey == null || !Pod.CanAcceptOnceCycleChosen(Takee)); - Toil goToTakee = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.OnCell).FailOnDestroyedNullOrForbidden(TargetIndex.A).FailOnDespawnedNullOrForbidden(TargetIndex.C) - .FailOn(() => Takee.IsFreeColonist && !Takee.Downed) - .FailOnSomeonePhysicallyInteracting(TargetIndex.A); - Toil startCarryingTakee = Toils_Haul.StartCarryThing(TargetIndex.A); - Toil goToThing = Toils_Goto.GotoThing(TargetIndex.C, PathEndMode.InteractionCell); - Toil toil = Toils_Jump.JumpIf(goToThing, () => pawn.IsCarryingPawn(Takee) && job.GetTargetQueue(TargetIndex.B).NullOrEmpty()); - Toil jumpIfGoToTakee = Toils_Jump.JumpIf(goToTakee, () => job.GetTargetQueue(TargetIndex.B).NullOrEmpty()); - yield return toil; - yield return jumpIfGoToTakee; - yield return DropCarryToGrabIngredients(); - foreach (Toil item in JobDriver_EnterBiosculpterPod.CollectIngredientsToilsHelper(TargetIndex.B, pawn, pickedUpIngredients)) - { - yield return item; - } - yield return goToTakee; - yield return TransferIngredientsAndPrepareCarryDownedPawn(); - yield return startCarryingTakee; - yield return goToThing.FailOn(() => !Pod.PawnCarryingExtraCycleIngredients(Takee, job.biosculpterCycleKey)); - yield return JobDriver_EnterBiosculpterPod.PrepareToEnterToil(TargetIndex.C); - Toil toil2 = ToilMaker.MakeToil("MakeNewToils"); - toil2.initAction = delegate - { - Pod.TryAcceptPawn(Takee, job.biosculpterCycleKey); - }; - toil2.defaultCompleteMode = ToilCompleteMode.Instant; - yield return toil2; - } - - private Toil TransferIngredientsAndPrepareCarryDownedPawn() - { - Toil toil = ToilMaker.MakeToil("TransferIngredientsAndPrepareCarryDownedPawn"); - toil.initAction = delegate - { - List extraRequiredIngredients = Pod.GetCycle(job.biosculpterCycleKey).Props.extraRequiredIngredients; - if (extraRequiredIngredients != null && !Pod.devFillPodLatch) - { - ThingOwner innerContainer = pawn.inventory.innerContainer; - foreach (ThingDefCountClass item in extraRequiredIngredients) - { - if (Takee.inventory.Count(item.thingDef) < item.count) - { - if (pawn.inventory.Count(item.thingDef) < item.count) - { - EndJobWith(JobCondition.Incompletable); - return; - } - thingsToTransfer.Clear(); - int num = 0; - foreach (Thing item2 in innerContainer) - { - if (num >= item.count) - { - break; - } - if (item2.def == item.thingDef) - { - int num2 = Mathf.Min(item.count - num, item2.stackCount); - thingsToTransfer.Add(new ThingCount(item2, Mathf.Min(item.count - num, item2.stackCount))); - num += num2; - } - } - foreach (ThingCount item3 in thingsToTransfer) - { - int num3 = Takee.inventory.innerContainer.TryAddOrTransfer(item3.Thing, item3.Count); - if (num3 != item3.Count) - { - Log.Warning($"Only able to transfer x{num3} of the expected x{item3.Count} of {item3.Thing.Label} while CarryToBiosculpter"); - EndJobWith(JobCondition.Incompletable); - return; - } - } - } - } - } - job.count = 1; - }; - toil.defaultCompleteMode = ToilCompleteMode.Instant; - return toil; - } - - private Toil DropCarryToGrabIngredients() - { - Toil toil = ToilMaker.MakeToil("DropCarryToGrabIngredients"); - toil.initAction = delegate - { - if (pawn.carryTracker.CarriedThing != null) - { - pawn.carryTracker.TryDropCarriedThing(pawn.Position, ThingPlaceMode.Near, out var _); - } - }; - toil.defaultCompleteMode = ToilCompleteMode.Instant; - return toil; - } - - public override string GetReport() - { - if (!Pod.PawnCarryingExtraCycleIngredients(Takee, job.biosculpterCycleKey) && !Pod.PawnCarryingExtraCycleIngredients(pawn, job.biosculpterCycleKey)) - { - return "BiosculpterJobReportCollectIngredients".Translate(); - } - return base.GetReport(); - } - - public override void ExposeData() - { - base.ExposeData(); - Scribe_Collections.Look(ref pickedUpIngredients, "pickedUpIngredients", LookMode.Reference); - } -} -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\Ideology\Defs\JobDefs\Jobs_Misc.xml` -**相似度:** 0.5483 - -```xml - CarryToBiosculpterPod - JobDriver_CarryToBiosculpterPod - carrying TargetA to biosculpter pod. - false - - - - RecolorApparel -``` \ No newline at end of file diff --git a/MCP/vector_cache/ColonistBarColonistDrawer-DrawIcons.txt b/MCP/vector_cache/ColonistBarColonistDrawer-DrawIcons.txt deleted file mode 100644 index 54867b4b..00000000 --- a/MCP/vector_cache/ColonistBarColonistDrawer-DrawIcons.txt +++ /dev/null @@ -1,985 +0,0 @@ -根据向量相似度分析,与 'DrawIcons, ColonistBarColonistDrawer' 最相关的代码定义如下: - ---- -**文件路径 (精确匹配):** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\ColonistBarColonistDrawer.txt` - -```csharp -public class ColonistBarColonistDrawer -{ - private struct IconDrawCall - { - public Texture2D texture; - - public string tooltip; - - public Color? color; - - public IconDrawCall(Texture2D texture, string tooltip = null, Color? color = null) - { - this.texture = texture; - this.tooltip = tooltip; - this.color = color; - } - } - - private Dictionary pawnLabelsCache = new Dictionary(); - - private static readonly Texture2D MoodBGTex = SolidColorMaterials.NewSolidColorTexture(new Color(0.4f, 0.47f, 0.53f, 0.44f)); - - private static readonly Texture2D MoodAtlas = ContentFinder.Get("UI/Widgets/SubtleGradient"); - - private static readonly Texture2D DeadColonistTex = ContentFinder.Get("UI/Misc/DeadColonist"); - - private static readonly Texture2D Icon_FormingCaravan = ContentFinder.Get("UI/Icons/ColonistBar/FormingCaravan"); - - private static readonly Texture2D Icon_MentalStateNonAggro = ContentFinder.Get("UI/Icons/ColonistBar/MentalStateNonAggro"); - - private static readonly Texture2D Icon_MentalStateAggro = ContentFinder.Get("UI/Icons/ColonistBar/MentalStateAggro"); - - private static readonly Texture2D Icon_MedicalRest = ContentFinder.Get("UI/Icons/ColonistBar/MedicalRest"); - - private static readonly Texture2D Icon_Sleeping = ContentFinder.Get("UI/Icons/ColonistBar/Sleeping"); - - private static readonly Texture2D Icon_Fleeing = ContentFinder.Get("UI/Icons/ColonistBar/Fleeing"); - - private static readonly Texture2D Icon_Attacking = ContentFinder.Get("UI/Icons/ColonistBar/Attacking"); - - private static readonly Texture2D Icon_Idle = ContentFinder.Get("UI/Icons/ColonistBar/Idle"); - - private static readonly Texture2D Icon_Burning = ContentFinder.Get("UI/Icons/ColonistBar/Burning"); - - private static readonly Texture2D Icon_Inspired = ContentFinder.Get("UI/Icons/ColonistBar/Inspired"); - - private static readonly Texture2D MoodGradient = ContentFinder.Get("UI/Widgets/MoodGradient"); - - public static readonly Vector2 PawnTextureSize = new Vector2(ColonistBar.BaseSize.x - 2f, 75f); - - public static readonly Vector3 PawnTextureCameraOffset = new Vector3(0f, 0f, 0.3f); - - public const float PawnTextureCameraZoom = 1.28205f; - - private const float PawnTextureHorizontalPadding = 1f; - - private static readonly float BaseIconAreaWidth = PawnTextureSize.x; - - private static readonly float BaseIconMaxSize = 20f; - - private const float BaseGroupFrameMargin = 12f; - - public const float DoubleClickTime = 0.5f; - - public const float FactionIconSpacing = 2f; - - public const float IdeoRoleIconSpacing = 2f; - - public const float SlaveIconSpacing = 2f; - - private const float MoodGradientHeight = 35f; - - private static List tmpIconsToDraw = new List(); - - private ColonistBar ColonistBar => Find.ColonistBar; - - public void DrawColonist(Rect rect, Pawn colonist, Map pawnMap, bool highlight, bool reordering) - { - float alpha = ColonistBar.GetEntryRectAlpha(rect); - bool num = Prefs.VisibleMood && colonist.needs?.mood != null && colonist.mindState.mentalBreaker.CanDoRandomMentalBreaks && !colonist.Dead && !colonist.Downed; - MoodThreshold moodThreshold = MoodThresholdExtensions.CurrentMoodThresholdFor(colonist); - Color color = moodThreshold.GetColor(); - color.a *= alpha; - ApplyEntryInAnotherMapAlphaFactor(pawnMap, ref alpha); - if (reordering) - { - alpha *= 0.5f; - } - Color color3 = (GUI.color = new Color(1f, 1f, 1f, alpha)); - if (num && alpha >= 1f) - { - float num2 = moodThreshold.EdgeExpansion(); - if (num2 > 0f) - { - GUI.color = color; - Widgets.DrawAtlas(rect.ExpandedBy(num2), MoodAtlas); - GUI.color = color3; - } - } - GUI.DrawTexture(rect, ColonistBar.BGTex); - if (colonist.needs != null && colonist.needs.mood != null) - { - Rect position = rect.ContractedBy(2f); - float num3 = position.height * colonist.needs.mood.CurLevelPercentage; - position.yMin = position.yMax - num3; - position.height = num3; - GUI.DrawTexture(position, MoodBGTex); - } - if (num && alpha >= 1f) - { - float transparency = ((moodThreshold < MoodThreshold.Major) ? 0.1f : 0.15f); - Widgets.DrawBoxSolid(rect, moodThreshold.GetColor().ToTransparent(transparency)); - } - if (highlight) - { - int thickness = ((rect.width <= 22f) ? 2 : 3); - GUI.color = Color.white; - Widgets.DrawBox(rect, thickness); - GUI.color = color3; - } - Rect rect2 = rect.ContractedBy(-2f * ColonistBar.Scale); - if ((colonist.Dead ? Find.Selector.SelectedObjects.Contains(colonist.Corpse) : Find.Selector.SelectedObjects.Contains(colonist)) && !WorldRendererUtility.WorldSelected) - { - DrawSelectionOverlayOnGUI(colonist, rect2); - } - else if (WorldRendererUtility.WorldSelected && colonist.IsCaravanMember() && Find.WorldSelector.IsSelected(colonist.GetCaravan())) - { - DrawCaravanSelectionOverlayOnGUI(colonist.GetCaravan(), rect2); - } - GUI.DrawTexture(GetPawnTextureRect(rect.position), PortraitsCache.Get(colonist, PawnTextureSize, Rot4.South, PawnTextureCameraOffset, 1.28205f)); - if (num) - { - Rect rect3 = rect.ContractedBy(1f); - Widgets.BeginGroup(rect3); - Rect position2 = rect3.AtZero(); - position2.yMin = position2.yMax - 35f; - GUI.color = color; - GUI.DrawTexture(position2, MoodGradient); - GUI.color = color3; - Widgets.EndGroup(); - } - GUI.color = new Color(1f, 1f, 1f, alpha * 0.8f); - DrawIcons(rect, colonist); - GUI.color = color3; - if (colonist.Dead) - { - GUI.DrawTexture(rect, DeadColonistTex); - } - float num4 = 4f * ColonistBar.Scale; - Vector2 pos = new Vector2(rect.center.x, rect.yMax - num4); - GenMapUI.DrawPawnLabel(colonist, pos, alpha, rect.width + ColonistBar.SpaceBetweenColonistsHorizontal - 2f, pawnLabelsCache); - Text.Font = GameFont.Small; - GUI.color = Color.white; - } - - private Rect GroupFrameRect(int group) - { - float num = 99999f; - float num2 = 0f; - float num3 = 0f; - List entries = ColonistBar.Entries; - List drawLocs = ColonistBar.DrawLocs; - for (int i = 0; i < entries.Count; i++) - { - if (entries[i].group == group) - { - num = Mathf.Min(num, drawLocs[i].x); - num2 = Mathf.Max(num2, drawLocs[i].x + ColonistBar.Size.x); - num3 = Mathf.Max(num3, drawLocs[i].y + ColonistBar.Size.y); - } - } - return new Rect(num, 0f, num2 - num, num3 - 0f).ContractedBy(-12f * ColonistBar.Scale); - } - - public void DrawGroupFrame(int group) - { - Rect position = GroupFrameRect(group); - Map map = ColonistBar.Entries.Find((ColonistBar.Entry x) => x.group == group).map; - float num = ((map == null) ? ((!WorldRendererUtility.WorldSelected) ? 0.75f : 1f) : ((map == Find.CurrentMap && !WorldRendererUtility.WorldSelected) ? 1f : 0.75f)); - Widgets.DrawRectFast(position, new Color(0.5f, 0.5f, 0.5f, 0.4f * num)); - } - - private void ApplyEntryInAnotherMapAlphaFactor(Map map, ref float alpha) - { - if (map == null) - { - if (!WorldRendererUtility.WorldSelected) - { - alpha = Mathf.Min(alpha, 0.4f); - } - } - else if (map != Find.CurrentMap || WorldRendererUtility.WorldSelected) - { - alpha = Mathf.Min(alpha, 0.4f); - } - } - - public void HandleClicks(Rect rect, Pawn colonist, int reorderableGroup, out bool reordering) - { - if (Event.current.type == EventType.MouseDown && Event.current.button == 0 && Event.current.clickCount == 2 && Mouse.IsOver(rect)) - { - Event.current.Use(); - CameraJumper.TryJump(colonist); - } - reordering = ReorderableWidget.Reorderable(reorderableGroup, rect, useRightButton: true); - if (Event.current.type == EventType.MouseDown && Event.current.button == 1 && Mouse.IsOver(rect)) - { - Event.current.Use(); - } - } - - public void HandleGroupFrameClicks(int group) - { - Rect rect = GroupFrameRect(group); - if (Event.current.type == EventType.MouseUp && Event.current.button == 0 && Mouse.IsOver(rect) && !ColonistBar.AnyColonistOrCorpseAt(UI.MousePositionOnUIInverted)) - { - bool worldSelected = WorldRendererUtility.WorldSelected; - if ((!worldSelected && !Find.Selector.dragBox.IsValidAndActive) || (worldSelected && !Find.WorldSelector.dragBox.IsValidAndActive)) - { - Find.Selector.dragBox.active = false; - Find.WorldSelector.dragBox.active = false; - ColonistBar.Entry entry = ColonistBar.Entries.Find((ColonistBar.Entry x) => x.group == group); - Map map = entry.map; - if (map == null) - { - if (WorldRendererUtility.WorldSelected) - { - CameraJumper.TrySelect(entry.pawn); - } - else - { - CameraJumper.TryJumpAndSelect(entry.pawn); - } - } - else - { - if (!CameraJumper.TryHideWorld() && Find.CurrentMap != map) - { - SoundDefOf.MapSelected.PlayOneShotOnCamera(); - } - Current.Game.CurrentMap = map; - } - } - } - if (Event.current.type == EventType.MouseDown && Event.current.button == 1 && Mouse.IsOver(rect)) - { - Event.current.Use(); - } - } - - public void Notify_RecachedEntries() - { - pawnLabelsCache.Clear(); - } - - public void ClearLabelCache() - { - pawnLabelsCache.Clear(); - } - - public Rect GetPawnTextureRect(Vector2 pos) - { - float x = pos.x; - float y = pos.y; - Vector2 vector = PawnTextureSize * ColonistBar.Scale; - return new Rect(x + 1f, y - (vector.y - ColonistBar.Size.y) - 1f, vector.x, vector.y).ContractedBy(1f); - } - - private void DrawIcons(Rect rect, Pawn colonist) - { - if (colonist.Dead) - { - return; - } - tmpIconsToDraw.Clear(); - bool flag = false; - if (colonist.CurJob != null) - { - JobDef def = colonist.CurJob.def; - if (def == JobDefOf.AttackMelee || def == JobDefOf.AttackStatic) - { - flag = true; - } - else if (def == JobDefOf.Wait_Combat && colonist.stances.curStance is Stance_Busy stance_Busy && stance_Busy.focusTarg.IsValid) - { - flag = true; - } - } - if (colonist.IsFormingCaravan()) - { - tmpIconsToDraw.Add(new IconDrawCall(Icon_FormingCaravan, "ActivityIconFormingCaravan".Translate())); - } - if (colonist.InAggroMentalState) - { - tmpIconsToDraw.Add(new IconDrawCall(Icon_MentalStateAggro, colonist.MentalStateDef.LabelCap)); - } - else if (colonist.InMentalState) - { - tmpIconsToDraw.Add(new IconDrawCall(Icon_MentalStateNonAggro, colonist.MentalStateDef.LabelCap)); - } - else if (colonist.InBed() && colonist.CurrentBed().Medical) - { - tmpIconsToDraw.Add(new IconDrawCall(Icon_MedicalRest, "ActivityIconMedicalRest".Translate())); - } - else - { - if (colonist.CurJob != null && colonist.jobs.curDriver.asleep) - { - goto IL_01c5; - } - if (colonist.GetCaravan() != null) - { - Pawn_NeedsTracker needs = colonist.needs; - if (needs != null && needs.rest?.Resting == true) - { - goto IL_01c5; - } - } - if (colonist.CurJob != null && colonist.CurJob.def == JobDefOf.FleeAndCower) - { - tmpIconsToDraw.Add(new IconDrawCall(Icon_Fleeing, "ActivityIconFleeing".Translate())); - } - else if (flag) - { - tmpIconsToDraw.Add(new IconDrawCall(Icon_Attacking, "ActivityIconAttacking".Translate())); - } - else if (colonist.mindState.IsIdle && GenDate.DaysPassed >= 1) - { - tmpIconsToDraw.Add(new IconDrawCall(Icon_Idle, "ActivityIconIdle".Translate())); - } - } - goto IL_02b4; - IL_01c5: - tmpIconsToDraw.Add(new IconDrawCall(Icon_Sleeping, "ActivityIconSleeping".Translate())); - goto IL_02b4; - IL_02b4: - if (colonist.IsBurning()) - { - tmpIconsToDraw.Add(new IconDrawCall(Icon_Burning, "ActivityIconBurning".Translate())); - } - if (colonist.Inspired) - { - tmpIconsToDraw.Add(new IconDrawCall(Icon_Inspired, colonist.InspirationDef.LabelCap)); - } - if (colonist.IsSlaveOfColony) - { - tmpIconsToDraw.Add(new IconDrawCall(colonist.guest.GetIcon())); - } - else - { - bool flag2 = false; - if (colonist.Ideo != null) - { - Ideo ideo = colonist.Ideo; - Precept_Role role = ideo.GetRole(colonist); - if (role != null) - { - tmpIconsToDraw.Add(new IconDrawCall(role.Icon, null, ideo.Color)); - flag2 = true; - } - } - if (!flag2) - { - Faction faction = null; - if (colonist.HasExtraMiniFaction()) - { - faction = colonist.GetExtraMiniFaction(); - } - else if (colonist.HasExtraHomeFaction()) - { - faction = colonist.GetExtraHomeFaction(); - } - if (faction != null) - { - tmpIconsToDraw.Add(new IconDrawCall(faction.def.FactionIcon, null, faction.Color)); - } - } - } - float num = Mathf.Min(BaseIconAreaWidth / (float)tmpIconsToDraw.Count, BaseIconMaxSize) * ColonistBar.Scale; - Vector2 pos = new Vector2(rect.x + 1f, rect.yMax - num - 1f); - foreach (IconDrawCall item in tmpIconsToDraw) - { - GUI.color = item.color ?? Color.white; - DrawIcon(item.texture, ref pos, num, item.tooltip); - GUI.color = Color.white; - } - } - - private void DrawIcon(Texture2D icon, ref Vector2 pos, float iconSize, string tooltip = null) - { - Rect rect = new Rect(pos.x, pos.y, iconSize, iconSize); - GUI.DrawTexture(rect, icon); - if (tooltip != null) - { - TooltipHandler.TipRegion(rect, tooltip); - } - pos.x += iconSize; - } - - private void DrawSelectionOverlayOnGUI(Pawn colonist, Rect rect) - { - Thing target = colonist; - if (colonist.Dead) - { - target = colonist.Corpse; - } - SelectionDrawerUtility.DrawSelectionOverlayOnGUI(target, rect, 0.4f * ColonistBar.Scale, 20f * ColonistBar.Scale); - } - - private void DrawCaravanSelectionOverlayOnGUI(Caravan caravan, Rect rect) - { - SelectionDrawerUtility.DrawSelectionOverlayOnGUI(caravan, rect, 0.4f * ColonistBar.Scale, 20f * ColonistBar.Scale); - } -} -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\ColonistBar.txt` -**相似度:** 0.7704 - -```csharp -public class ColonistBar -{ - public struct Entry - { - public Pawn pawn; - - public Map map; - - public int group; - - public Action reorderAction; - - public Action extraDraggedItemOnGUI; - - public Entry(Pawn pawn, Map map, int group) - { - this.pawn = pawn; - this.map = map; - this.group = group; - reorderAction = delegate(int from, int to) - { - Find.ColonistBar.Reorder(from, to, group); - }; - extraDraggedItemOnGUI = delegate(int index, Vector2 dragStartPos) - { - Find.ColonistBar.DrawColonistMouseAttachment(index, dragStartPos, group); - }; - } - } - - public ColonistBarColonistDrawer drawer = new ColonistBarColonistDrawer(); - - private ColonistBarDrawLocsFinder drawLocsFinder = new ColonistBarDrawLocsFinder(); - - private List cachedEntries = new List(); - - private List cachedDrawLocs = new List(); - - private List cachedReorderableGroups = new List(); - - private float cachedScale = 1f; - - private bool entriesDirty = true; - - private List colonistsToHighlight = new List(); - - public static readonly Texture2D BGTex = Command.BGTex; - - public static readonly Vector2 BaseSize = new Vector2(48f, 48f); - - public const float BaseSelectedTexJump = 20f; - - public const float BaseSelectedTexScale = 0.4f; - - public const float EntryInAnotherMapAlpha = 0.4f; - - public const float BaseSpaceBetweenGroups = 25f; - - public const float BaseSpaceBetweenColonistsHorizontal = 24f; - - public const float BaseSpaceBetweenColonistsVertical = 32f; - - private const float WeaponIconOffsetScaleFactor = 1.05f; - - private const float WeaponIconScaleFactor = 0.75f; - - private static List tmpPawns = new List(); - - private static List tmpMaps = new List(); - - private static List tmpCaravans = new List(); - - private static List tmpColonistsInOrder = new List(); - - private static List> tmpColonistsWithMap = new List>(); - - private static List tmpColonists = new List(); - - private static List tmpMapColonistsOrCorpsesInScreenRect = new List(); - - private static List tmpCaravanPawns = new List(); - - public List Entries - { - get - { - CheckRecacheEntries(); - return cachedEntries; - } - } - - private bool ShowGroupFrames - { - get - { - List entries = Entries; - int num = -1; - for (int i = 0; i < entries.Count; i++) - { - num = Mathf.Max(num, entries[i].group); - } - return num >= 1; - } - } - - public float Scale => cachedScale; - - public List DrawLocs => cachedDrawLocs; - - public Vector2 Size => BaseSize * Scale; - - public float SpaceBetweenColonistsHorizontal => 24f * Scale; - - private bool Visible - { - get - { - if (UI.screenWidth < 800 || UI.screenHeight < 500) - { - return false; - } - if (Find.TilePicker.Active) - { - return false; - } - return true; - } - } - - public void MarkColonistsDirty() - { - entriesDirty = true; - } - - public void ColonistBarOnGUI() - { - if (!Visible) - { - return; - } - if (Event.current.type != EventType.Layout) - { - List entries = Entries; - int num = -1; - bool showGroupFrames = ShowGroupFrames; - int value = -1; - for (int i = 0; i < cachedDrawLocs.Count; i++) - { - Rect rect = new Rect(cachedDrawLocs[i].x, cachedDrawLocs[i].y, Size.x, Size.y); - Entry entry = entries[i]; - bool flag = num != entry.group; - num = entry.group; - if (Event.current.type == EventType.Repaint) - { - if (flag) - { - value = ReorderableWidget.NewGroup(entry.reorderAction, ReorderableDirection.Horizontal, new Rect(0f, 0f, UI.screenWidth, UI.screenHeight), SpaceBetweenColonistsHorizontal, entry.extraDraggedItemOnGUI); - } - cachedReorderableGroups[i] = value; - } - bool reordering; - if (entry.pawn != null) - { - drawer.HandleClicks(rect, entry.pawn, cachedReorderableGroups[i], out reordering); - } - else - { - reordering = false; - } - if (Event.current.type != EventType.Repaint) - { - continue; - } - if (flag && showGroupFrames) - { - drawer.DrawGroupFrame(entry.group); - } - if (entry.pawn != null) - { - drawer.DrawColonist(rect, entry.pawn, entry.map, colonistsToHighlight.Contains(entry.pawn), reordering); - ThingWithComps thingWithComps = entry.pawn.equipment?.Primary; - if ((Prefs.ShowWeaponsUnderPortraitMode == ShowWeaponsUnderPortraitMode.Always || (Prefs.ShowWeaponsUnderPortraitMode == ShowWeaponsUnderPortraitMode.WhileDrafted && entry.pawn.Drafted)) && thingWithComps != null && thingWithComps.def.IsWeapon) - { - Widgets.ThingIcon(new Rect(rect.x, rect.y + rect.height * 1.05f, rect.width, rect.height).ScaledBy(0.75f), thingWithComps, 1f, null, stackOfOne: true); - } - } - } - num = -1; - if (showGroupFrames) - { - for (int j = 0; j < cachedDrawLocs.Count; j++) - { - Entry entry2 = entries[j]; - bool num2 = num != entry2.group; - num = entry2.group; - if (num2) - { - drawer.HandleGroupFrameClicks(entry2.group); - } - } - } - } - if (Event.current.type == EventType.Repaint) - { - colonistsToHighlight.Clear(); - } - } - - private void CheckRecacheEntries() - { - if (!entriesDirty) - { - return; - } - entriesDirty = false; - cachedEntries.Clear(); - int num = 0; - if (Find.PlaySettings.showColonistBar) - { - tmpMaps.Clear(); - tmpMaps.AddRange(Find.Maps); - tmpMaps.SortBy((Map x) => !x.IsPlayerHome, (Map x) => x.uniqueID); - for (int i = 0; i < tmpMaps.Count; i++) - { - tmpPawns.Clear(); - tmpPawns.AddRange(tmpMaps[i].mapPawns.FreeColonists); - tmpPawns.AddRange(tmpMaps[i].mapPawns.ColonySubhumansControllable); - List list = tmpMaps[i].listerThings.ThingsInGroup(ThingRequestGroup.Corpse); - for (int j = 0; j < list.Count; j++) - { - if (!list[j].IsDessicated()) - { - Pawn innerPawn = ((Corpse)list[j]).InnerPawn; - if (innerPawn != null && innerPawn.IsColonist) - { - tmpPawns.Add(innerPawn); - } - } - } - IReadOnlyList allPawnsSpawned = tmpMaps[i].mapPawns.AllPawnsSpawned; - for (int k = 0; k < allPawnsSpawned.Count; k++) - { - if (allPawnsSpawned[k].carryTracker.CarriedThing is Corpse corpse && !corpse.IsDessicated() && corpse.InnerPawn.IsColonist) - { - tmpPawns.Add(corpse.InnerPawn); - } - } - foreach (Pawn tmpPawn in tmpPawns) - { - if (tmpPawn.playerSettings.displayOrder == -9999999) - { - tmpPawn.playerSettings.displayOrder = Mathf.Max(tmpPawns.MaxBy((Pawn p) => p.playerSettings.displayOrder).playerSettings.displayOrder, 0) + 1; - } - } - PlayerPawnsDisplayOrderUtility.Sort(tmpPawns); - foreach (Pawn tmpPawn2 in tmpPawns) - { - cachedEntries.Add(new Entry(tmpPawn2, tmpMaps[i], num)); - } - if (!tmpPawns.Any()) - { - cachedEntries.Add(new Entry(null, tmpMaps[i], num)); - } - num++; - } - tmpCaravans.Clear(); - tmpCaravans.AddRange(Find.WorldObjects.Caravans); - tmpCaravans.SortBy((Caravan x) => x.ID); - for (int l = 0; l < tmpCaravans.Count; l++) - { - if (!tmpCaravans[l].IsPlayerControlled) - { - continue; - } - tmpPawns.Clear(); - tmpPawns.AddRange(tmpCaravans[l].PawnsListForReading); - PlayerPawnsDisplayOrderUtility.Sort(tmpPawns); - for (int m = 0; m < tmpPawns.Count; m++) - { - if (tmpPawns[m].IsColonist || tmpPawns[m].IsColonySubhumanPlayerControlled) - { - cachedEntries.Add(new Entry(tmpPawns[m], null, num)); - } - } - num++; - } - } - cachedReorderableGroups.Clear(); - foreach (Entry cachedEntry in cachedEntries) - { - _ = cachedEntry; - cachedReorderableGroups.Add(-1); - } - drawer.Notify_RecachedEntries(); - tmpPawns.Clear(); - tmpMaps.Clear(); - tmpCaravans.Clear(); - drawLocsFinder.CalculateDrawLocs(cachedDrawLocs, out cachedScale, num); - } - - public float GetEntryRectAlpha(Rect rect) - { - if (Messages.CollidesWithAnyMessage(rect, out var messageAlpha)) - { - return Mathf.Lerp(1f, 0.2f, messageAlpha); - } - return 1f; - } - - public void Highlight(Pawn pawn) - { - if (Visible && !colonistsToHighlight.Contains(pawn)) - { - colonistsToHighlight.Add(pawn); - } - } - - public void Reorder(int from, int to, int entryGroup) - { - int num = 0; - Pawn pawn = null; - Pawn pawn2 = null; - Pawn pawn3 = null; - for (int i = 0; i < cachedEntries.Count; i++) - { - if (cachedEntries[i].group == entryGroup && cachedEntries[i].pawn != null) - { - if (num == from) - { - pawn = cachedEntries[i].pawn; - } - if (num == to) - { - pawn2 = cachedEntries[i].pawn; - } - pawn3 = cachedEntries[i].pawn; - num++; - } - } - if (pawn == null) - { - return; - } - int num2 = pawn2?.playerSettings.displayOrder ?? (pawn3.playerSettings.displayOrder + 1); - for (int j = 0; j < cachedEntries.Count; j++) - { - Pawn pawn4 = cachedEntries[j].pawn; - if (pawn4 == null) - { - continue; - } - if (pawn4.playerSettings.displayOrder == num2) - { - if (pawn2 != null && cachedEntries[j].group == entryGroup) - { - pawn4.playerSettings.displayOrder++; - } - } - else if (pawn4.playerSettings.displayOrder > num2) - { - pawn4.playerSettings.displayOrder++; - } - else - { - pawn4.playerSettings.displayOrder--; - } - } - pawn.playerSettings.displayOrder = num2; - MarkColonistsDirty(); - MainTabWindowUtility.NotifyAllPawnTables_PawnsChanged(); - } - - public void DrawColonistMouseAttachment(int index, Vector2 dragStartPos, int entryGroup) - { - Pawn pawn = null; - Vector2 vector = default(Vector2); - int num = 0; - for (int i = 0; i < cachedEntries.Count; i++) - { - if (cachedEntries[i].group == entryGroup && cachedEntries[i].pawn != null) - { - if (num == index) - { - pawn = cachedEntries[i].pawn; - vector = cachedDrawLocs[i]; - break; - } - num++; - } - } - if (pawn != null) - { - RenderTexture iconTex = PortraitsCache.Get(pawn, ColonistBarColonistDrawer.PawnTextureSize, Rot4.South, ColonistBarColonistDrawer.PawnTextureCameraOffset, 1.28205f); - Rect rect = new Rect(vector.x, vector.y, Size.x, Size.y); - Rect pawnTextureRect = drawer.GetPawnTextureRect(rect.position); - pawnTextureRect.position += Event.current.mousePosition - dragStartPos; - Rect? customRect = pawnTextureRect; - GenUI.DrawMouseAttachment(iconTex, "", 0f, default(Vector2), customRect); - } - } - - public bool AnyColonistOrCorpseAt(Vector2 pos) - { - if (!TryGetEntryAt(pos, out var entry)) - { - return false; - } - return entry.pawn != null; - } - - public bool TryGetEntryAt(Vector2 pos, out Entry entry) - { - List drawLocs = DrawLocs; - List entries = Entries; - Vector2 size = Size; - for (int i = 0; i < drawLocs.Count; i++) - { - if (new Rect(drawLocs[i].x, drawLocs[i].y, size.x, size.y).Contains(pos)) - { - entry = entries[i]; - return true; - } - } - entry = default(Entry); - return false; - } - - public List GetColonistsInOrder() - { - List entries = Entries; - tmpColonistsInOrder.Clear(); - for (int i = 0; i < entries.Count; i++) - { - if (entries[i].pawn != null) - { - tmpColonistsInOrder.Add(entries[i].pawn); - } - } - return tmpColonistsInOrder; - } - - public List ColonistsOrCorpsesInScreenRect(Rect rect) - { - List drawLocs = DrawLocs; - List entries = Entries; - Vector2 size = Size; - tmpColonistsWithMap.Clear(); - for (int i = 0; i < drawLocs.Count; i++) - { - if (rect.Overlaps(new Rect(drawLocs[i].x, drawLocs[i].y, size.x, size.y))) - { - Pawn pawn = entries[i].pawn; - if (pawn != null) - { - Thing first = ((!pawn.Dead || pawn.Corpse == null || !pawn.Corpse.SpawnedOrAnyParentSpawned) ? ((Thing)pawn) : ((Thing)pawn.Corpse)); - tmpColonistsWithMap.Add(new Pair(first, entries[i].map)); - } - } - } - if (WorldRendererUtility.WorldSelected && tmpColonistsWithMap.Any((Pair x) => x.Second == null)) - { - tmpColonistsWithMap.RemoveAll((Pair x) => x.Second != null); - } - else if (tmpColonistsWithMap.Any((Pair x) => x.Second == Find.CurrentMap)) - { - tmpColonistsWithMap.RemoveAll((Pair x) => x.Second != Find.CurrentMap); - } - tmpColonists.Clear(); - for (int j = 0; j < tmpColonistsWithMap.Count; j++) - { - tmpColonists.Add(tmpColonistsWithMap[j].First); - } - tmpColonistsWithMap.Clear(); - return tmpColonists; - } - - public List MapColonistsOrCorpsesInScreenRect(Rect rect) - { - tmpMapColonistsOrCorpsesInScreenRect.Clear(); - if (!Visible) - { - return tmpMapColonistsOrCorpsesInScreenRect; - } - List list = ColonistsOrCorpsesInScreenRect(rect); - for (int i = 0; i < list.Count; i++) - { - if (list[i].Spawned) - { - tmpMapColonistsOrCorpsesInScreenRect.Add(list[i]); - } - } - return tmpMapColonistsOrCorpsesInScreenRect; - } - - public List CaravanMembersInScreenRect(Rect rect) - { - tmpCaravanPawns.Clear(); - if (!Visible) - { - return tmpCaravanPawns; - } - List list = ColonistsOrCorpsesInScreenRect(rect); - for (int i = 0; i < list.Count; i++) - { - if (list[i] is Pawn pawn && pawn.IsCaravanMember()) - { - tmpCaravanPawns.Add(pawn); - } - } - return tmpCaravanPawns; - } - - public List CaravanMembersCaravansInScreenRect(Rect rect) - { - tmpCaravans.Clear(); - if (!Visible) - { - return tmpCaravans; - } - List list = CaravanMembersInScreenRect(rect); - for (int i = 0; i < list.Count; i++) - { - tmpCaravans.Add(list[i].GetCaravan()); - } - return tmpCaravans; - } - - public Caravan CaravanMemberCaravanAt(Vector2 at) - { - if (!Visible) - { - return null; - } - if (ColonistOrCorpseAt(at) is Pawn pawn && pawn.IsCaravanMember()) - { - return pawn.GetCaravan(); - } - return null; - } - - public Thing ColonistOrCorpseAt(Vector2 pos) - { - if (!Visible) - { - return null; - } - if (!TryGetEntryAt(pos, out var entry)) - { - return null; - } - Pawn pawn = entry.pawn; - if (pawn != null && pawn.Dead && pawn.Corpse != null && pawn.Corpse.SpawnedOrAnyParentSpawned) - { - return pawn.Corpse; - } - return pawn; - } -} -``` \ No newline at end of file diff --git a/MCP/vector_cache/CompBiosculpterPod-CompProperties_BiosculpterPod.txt b/MCP/vector_cache/CompBiosculpterPod-CompProperties_BiosculpterPod.txt deleted file mode 100644 index d14fb0bc..00000000 --- a/MCP/vector_cache/CompBiosculpterPod-CompProperties_BiosculpterPod.txt +++ /dev/null @@ -1,1485 +0,0 @@ -根据向量相似度分析,与 'CompProperties_BiosculpterPod, CompBiosculpterPod' 最相关的代码定义如下: - ---- -**文件路径 (精确匹配):** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\CompProperties_BiosculpterPod.txt` - -```csharp -public class CompProperties_BiosculpterPod : CompProperties -{ - public SoundDef enterSound; - - public SoundDef exitSound; - - public EffecterDef operatingEffecter; - - public EffecterDef readyEffecter; - - public Color selectCycleColor; - - public float biotunedCycleSpeedFactor; - - public CompProperties_BiosculpterPod() - { - compClass = typeof(CompBiosculpterPod); - } - - public override IEnumerable ConfigErrors(ThingDef parentDef) - { - foreach (string item in base.ConfigErrors(parentDef)) - { - yield return item; - } - if (parentDef.tickerType != TickerType.Normal) - { - yield return GetType().Name + " requires parent ticker type Normal"; - } - } -} -``` ---- -**文件路径 (精确匹配):** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\CompBiosculpterPod.txt` - -```csharp -public class CompBiosculpterPod : ThingComp, ISuspendableThingHolder, IThingHolder, IThingHolderWithDrawnPawn, IStoreSettingsParent, INotifyHauledTo, ISearchableContents -{ - private const int NoPowerEjectCumulativeTicks = 60000; - - private const int BiotunedDuration = 4800000; - - private const float NutritionRequired = 5f; - - private const float CacheForSecs = 2f; - - private static readonly Texture2D InterruptCycleIcon = ContentFinder.Get("UI/Designators/Cancel"); - - private static readonly Material BackgroundMat = SolidColorMaterials.NewSolidColorMaterial(new Color(0.082f, 0.078f, 0.063f), ShaderDatabase.SolidColorBehind); - - private const float BackgroundRect_YOff = 0.07317074f; - - private const float Pawn_YOff = 0.03658537f; - - private string currentCycleKey; - - private float currentCycleTicksRemaining; - - private int currentCyclePowerCutTicks; - - private ThingOwner innerContainer; - - private Pawn biotunedTo; - - private int biotunedCountdownTicks; - - private StorageSettings allowedNutritionSettings; - - private float liquifiedNutrition; - - public bool autoLoadNutrition = true; - - public bool devFillPodLatch; - - private bool autoAgeReversal; - - private int tickEntered = -99999; - - public Job queuedEnterJob; - - public Pawn queuedPawn; - - private List chosenExtraItems = new List(); - - private List cycleEligiblePawnOptions = new List(); - - private Pawn pawnEnteringBiosculpter; - - private Dictionary> cachedExtraIngredients = new Dictionary>(); - - private Dictionary cachedAnyPawnEligible = new Dictionary(); - - private static Dictionary> cachedBiotunedPods = new Dictionary>(); - - private Pawn cacheReachIngredientsPawn; - - private CompBiosculpterPod_Cycle cacheReachIngredientsCycle; - - private float cacheReachIngredientsTime = float.MinValue; - - private bool cacheReachIngredientsResult; - - private Effecter progressBarEffecter; - - private Effecter operatingEffecter; - - private Effecter readyEffecter; - - private Texture2D cachedAutoAgeReverseIcon; - - private List cachedAvailableCycles; - - private Dictionary cycleLookup; - - private static string cachedAgeReversalCycleKey = null; - - private List tmpIngredientsStrings = new List(); - - private static readonly List tmpItems = new List(); - - private CompPowerTrader powerTraderComp; - - private CompPower powerComp; - - private static List cachedPodDefs; - - public CompProperties_BiosculpterPod Props => props as CompProperties_BiosculpterPod; - - public ThingOwner SearchableContents => innerContainer; - - public bool IsContentsSuspended => true; - - public float RequiredNutritionRemaining => Mathf.Max(5f - liquifiedNutrition, 0f); - - public bool NutritionLoaded => RequiredNutritionRemaining <= 0f; - - public bool AutoAgeReversal => autoAgeReversal; - - private Texture2D AutoAgeReversalIcon - { - get - { - if (cachedAutoAgeReverseIcon == null) - { - cachedAutoAgeReverseIcon = ContentFinder.Get("UI/Gizmos/BiosculpterAutoAgeReversal"); - } - return cachedAutoAgeReverseIcon; - } - } - - public BiosculpterPodState State - { - get - { - if (Occupant != null) - { - return BiosculpterPodState.Occupied; - } - if (NutritionLoaded) - { - return BiosculpterPodState.SelectingCycle; - } - return BiosculpterPodState.LoadingNutrition; - } - } - - public Pawn Occupant - { - get - { - if (pawnEnteringBiosculpter != null) - { - return pawnEnteringBiosculpter; - } - if (currentCycleKey == null) - { - return null; - } - if (innerContainer.Count != 1) - { - return null; - } - return innerContainer[0] as Pawn; - } - } - - public CompBiosculpterPod_Cycle CurrentCycle - { - get - { - if (currentCycleKey == null) - { - return null; - } - foreach (CompBiosculpterPod_Cycle availableCycle in AvailableCycles) - { - if (availableCycle.Props.key == currentCycleKey) - { - return availableCycle; - } - } - return null; - } - } - - public List AvailableCycles - { - get - { - if (cachedAvailableCycles == null) - { - SetupCycleCaches(); - } - return cachedAvailableCycles; - } - } - - public string AgeReversalCycleKey - { - get - { - if (cachedAgeReversalCycleKey == null) - { - SetupCycleCaches(); - } - return cachedAgeReversalCycleKey; - } - } - - private float CycleSpeedFactorNoPawn => CleanlinessSpeedFactor * BiotunedSpeedFactor; - - public float CycleSpeedFactor - { - get - { - if (Occupant == null) - { - return Mathf.Max(0.1f, CycleSpeedFactorNoPawn); - } - return GetCycleSpeedFactorForPawn(Occupant); - } - } - - private float CleanlinessSpeedFactor => parent.GetStatValue(StatDefOf.BiosculpterPodSpeedFactor); - - private float BiotunedSpeedFactor - { - get - { - if (biotunedTo == null) - { - return 1f; - } - return Props.biotunedCycleSpeedFactor; - } - } - - public bool PowerOn => parent.TryGetComp().PowerOn; - - public float HeldPawnDrawPos_Y => parent.DrawPos.y - 0.03658537f; - - public float HeldPawnBodyAngle => parent.Rotation.Opposite.AsAngle; - - public PawnPosture HeldPawnPosture => PawnPosture.LayingOnGroundFaceUp; - - public bool StorageTabVisible => true; - - public CompBiosculpterPod() - { - innerContainer = new ThingOwner(this); - } - - public override void Initialize(CompProperties props) - { - base.Initialize(props); - allowedNutritionSettings = new StorageSettings(this); - if (parent.def.building.defaultStorageSettings != null) - { - allowedNutritionSettings.CopyFrom(parent.def.building.defaultStorageSettings); - } - } - - public override void PostSpawnSetup(bool respawningAfterLoad) - { - if (ModLister.CheckIdeology("Biosculpter pod comp")) - { - base.PostSpawnSetup(respawningAfterLoad); - } - } - - public override void PostExposeData() - { - base.PostExposeData(); - Scribe_Deep.Look(ref innerContainer, "innerContainer", this); - Scribe_Values.Look(ref currentCycleKey, "currentCycleKey"); - Scribe_Values.Look(ref currentCycleTicksRemaining, "currentCycleTicksRemaining", 0f); - Scribe_Values.Look(ref currentCyclePowerCutTicks, "currentCyclePowerCutTicks", 0); - Scribe_References.Look(ref biotunedTo, "biotunedTo"); - Scribe_Values.Look(ref biotunedCountdownTicks, "biotunedCountdownTicks", 0); - Scribe_Deep.Look(ref allowedNutritionSettings, "allowedNutritionSettings"); - Scribe_Values.Look(ref liquifiedNutrition, "liquifiedNutrition", 0f); - Scribe_Values.Look(ref autoLoadNutrition, "autoLoadNutrition", defaultValue: false); - Scribe_Values.Look(ref devFillPodLatch, "devFillPodLatch", defaultValue: false); - Scribe_Values.Look(ref autoAgeReversal, "autoAgeReversal", defaultValue: false); - Scribe_Values.Look(ref tickEntered, "tickEntered", 0); - Scribe_References.Look(ref queuedEnterJob, "queuedEnterJob"); - Scribe_References.Look(ref queuedPawn, "queuedPawn"); - if (allowedNutritionSettings == null) - { - allowedNutritionSettings = new StorageSettings(this); - if (parent.def.building.defaultStorageSettings != null) - { - allowedNutritionSettings.CopyFrom(parent.def.building.defaultStorageSettings); - } - } - if (Scribe.mode == LoadSaveMode.PostLoadInit) - { - if (currentCycleKey == "healing") - { - currentCycleKey = "medic"; - } - if (biotunedTo != null) - { - SetBiotuned(biotunedTo); - } - LiquifyNutrition(); - } - } - - public CompBiosculpterPod_Cycle GetCycle(string key) - { - if (cycleLookup == null) - { - SetupCycleCaches(); - } - return cycleLookup[key]; - } - - public float GetCycleSpeedFactorForPawn(Pawn p) - { - return Mathf.Max(0.1f, CycleSpeedFactorNoPawn * p.GetStatValue(StatDefOf.BiosculpterOccupantSpeed)); - } - - private void SetupCycleCaches() - { - cachedAvailableCycles = new List(); - cachedAvailableCycles.AddRange(parent.AllComps.OfType()); - cycleLookup = new Dictionary(); - foreach (CompBiosculpterPod_Cycle cachedAvailableCycle in cachedAvailableCycles) - { - if (cachedAvailableCycle is CompBiosculpterPod_AgeReversalCycle compBiosculpterPod_AgeReversalCycle) - { - cachedAgeReversalCycleKey = compBiosculpterPod_AgeReversalCycle.Props.key; - } - cycleLookup[cachedAvailableCycle.Props.key] = cachedAvailableCycle; - } - } - - public void SetBiotuned(Pawn newBiotunedTo) - { - if (newBiotunedTo != biotunedTo) - { - autoAgeReversal = false; - } - if (biotunedTo != null && cachedBiotunedPods.ContainsKey(biotunedTo)) - { - cachedBiotunedPods[biotunedTo].Remove(this); - } - if (newBiotunedTo != null && !cachedBiotunedPods.ContainsKey(newBiotunedTo)) - { - cachedBiotunedPods[newBiotunedTo] = new List(); - } - if (newBiotunedTo != null && !cachedBiotunedPods[newBiotunedTo].Contains(this)) - { - cachedBiotunedPods[newBiotunedTo].Add(this); - } - if (newBiotunedTo != null && newBiotunedTo != biotunedTo) - { - biotunedCountdownTicks = 4800000; - } - biotunedTo = newBiotunedTo; - } - - public override void PostDestroy(DestroyMode mode, Map previousMap) - { - SetBiotuned(null); - if (mode == DestroyMode.Deconstruct || mode == DestroyMode.KillFinalize) - { - EjectContents(interrupted: true, playSounds: false, previousMap); - } - innerContainer.ClearAndDestroyContents(); - base.PostDestroy(mode, previousMap); - } - - public override void PostDeSpawn(Map map, DestroyMode mode = DestroyMode.Vanish) - { - if (mode != DestroyMode.WillReplace) - { - EjectContents(interrupted: true, playSounds: false, map); - currentCycleKey = null; - } - progressBarEffecter?.Cleanup(); - progressBarEffecter = null; - operatingEffecter?.Cleanup(); - operatingEffecter = null; - readyEffecter?.Cleanup(); - readyEffecter = null; - } - - public override void DrawGUIOverlay() - { - base.DrawGUIOverlay(); - if (!Find.ScreenshotModeHandler.Active && (biotunedTo != null || Occupant != null)) - { - GenMapUI.DrawThingLabel(parent, biotunedTo?.LabelShort ?? Occupant.LabelShort, GenMapUI.DefaultThingLabelColor); - } - } - - public override string CompInspectStringExtra() - { - StringBuilder stringBuilder = new StringBuilder(); - BiosculpterPodState state = State; - if (parent.Spawned) - { - CompBiosculpterPod_Cycle currentCycle = CurrentCycle; - if (currentCycle != null) - { - stringBuilder.AppendLineIfNotEmpty().Append("BiosculpterPodCycleLabel".Translate()).Append(": ") - .Append(currentCycle.Props.LabelCap); - if (biotunedTo == null) - { - stringBuilder.Append(" " + "BiosculpterPodCycleWillBiotune".Translate()); - } - } - else if (state == BiosculpterPodState.SelectingCycle) - { - if (PowerOn) - { - if (queuedEnterJob != null && !queuedEnterJob.biosculpterCycleKey.NullOrEmpty()) - { - stringBuilder.Append("BiosculpterPodCycleStandby".Translate(GetCycle(queuedEnterJob.biosculpterCycleKey).Props.label.Named("CYCLE"), queuedPawn.Named("PAWN"))); - } - else - { - stringBuilder.Append("BiosculpterPodCycleSelection".Translate().CapitalizeFirst()); - } - } - else - { - stringBuilder.Append("BiosculpterPodCycleSelectionNoPower".Translate().CapitalizeFirst()); - } - } - if (state == BiosculpterPodState.LoadingNutrition) - { - stringBuilder.Append("BiosculpterPodCycleLabelLoading".Translate().CapitalizeFirst()); - stringBuilder.AppendLineIfNotEmpty().Append("Nutrition".Translate()).Append(": ") - .Append(liquifiedNutrition.ToStringByStyle(ToStringStyle.FloatMaxOne)) - .Append(" / ") - .Append(5f); - } - if (state == BiosculpterPodState.Occupied) - { - float num = currentCycleTicksRemaining / CycleSpeedFactor; - stringBuilder.AppendLineIfNotEmpty().Append("Contains".Translate()).Append(": ") - .Append(Occupant.NameShortColored.Resolve()); - if (!PowerOn) - { - stringBuilder.AppendLine().Append("BiosculpterCycleNoPowerInterrupt".Translate((60000 - currentCyclePowerCutTicks).ToStringTicksToPeriod().Named("TIME")).Colorize(ColorLibrary.RedReadable)); - } - stringBuilder.AppendLine().Append("BiosculpterCycleTimeRemaining".Translate()).Append(": ") - .Append(((int)num).ToStringTicksToPeriod().Colorize(ColoredText.DateTimeColor)); - Ideo ideo = Occupant.Ideo; - if (ideo != null && ideo.HasPrecept(PreceptDefOf.Biosculpting_Accelerated)) - { - stringBuilder.Append(" (" + "BiosculpterCycleAccelerated".Translate() + ")"); - } - if (biotunedTo != null) - { - stringBuilder.AppendLine().Append("BiosculpterBiotunedSpeedFactor".Translate()).Append(": ") - .Append(BiotunedSpeedFactor.ToStringPercent()); - } - stringBuilder.AppendLine().Append("BiosculpterCleanlinessSpeedFactor".Translate()).Append(": ") - .Append(CleanlinessSpeedFactor.ToStringPercent()); - } - } - if (biotunedTo != null && state != BiosculpterPodState.Occupied) - { - stringBuilder.AppendLineIfNotEmpty().Append("BiosculpterBiotunedTo".Translate()).Append(": ") - .Append(biotunedTo.LabelShort) - .Append(" (") - .Append(biotunedCountdownTicks.ToStringTicksToPeriod()) - .Append(")"); - } - if (stringBuilder.Length <= 0) - { - return null; - } - return stringBuilder.ToString(); - } - - public override IEnumerable CompGetGizmosExtra() - { - BiosculpterPodState state = State; - string cycleIndependentCannotUseReason = CannotUseNowReason(); - foreach (CompBiosculpterPod_Cycle cycle in AvailableCycles) - { - string text = cycleIndependentCannotUseReason ?? CannotUseNowCycleReason(cycle); - Command_Action command_Action = new Command_Action(); - command_Action.defaultLabel = "BiosculpterPodCycleCommand".Translate(cycle.Props.label) + ((biotunedTo != null) ? (" (" + biotunedTo.LabelShort + ")") : ""); - command_Action.defaultDesc = CycleDescription(cycle); - command_Action.icon = cycle.Props.Icon; - command_Action.action = delegate - { - SelectPawnsForCycleOptions(cycle, out var options2); - if (biotunedTo != null && options2.Count > 0) - { - options2[0].action(); - if (!(cycle is CompBiosculpterPod_HealingCycle)) - { - Messages.Message("BiosculpterEnteringMessage".Translate(biotunedTo.Named("PAWN"), cycle.Props.label.Named("CYCLE")).CapitalizeFirst(), parent, MessageTypeDefOf.SilentInput, historical: false); - } - } - else - { - Find.WindowStack.Add(new FloatMenu(options2)); - } - }; - command_Action.activateSound = SoundDefOf.Tick_Tiny; - command_Action.Disabled = text != null; - List options; - if (text != null) - { - command_Action.Disable(text); - } - else if (!SelectPawnsForCycleOptions(cycle, out options, shortCircuit: true)) - { - command_Action.Disable((biotunedTo != null) ? "BiosculpterNoEligiblePawnsBiotuned".Translate(biotunedTo.Named("PAWN")) : "BiosculpterNoEligiblePawns".Translate()); - } - yield return command_Action; - } - if (state == BiosculpterPodState.Occupied) - { - Command_Action command_Action2 = new Command_Action(); - command_Action2.defaultLabel = "BiosculpterInteruptCycle".Translate(); - command_Action2.defaultDesc = "BiosculpterInteruptCycleDesc".Translate(); - command_Action2.icon = InterruptCycleIcon; - command_Action2.action = delegate - { - EjectContents(interrupted: true, playSounds: true); - }; - command_Action2.activateSound = SoundDefOf.Designate_Cancel; - yield return command_Action2; - } - Command_Toggle command_Toggle = new Command_Toggle(); - command_Toggle.defaultLabel = "BiosculpterAutoLoadNutritionLabel".Translate(); - command_Toggle.defaultDesc = "BiosculpterAutoLoadNutritionDescription".Translate(); - command_Toggle.icon = (autoLoadNutrition ? TexCommand.ForbidOff : TexCommand.ForbidOn); - command_Toggle.isActive = () => autoLoadNutrition; - command_Toggle.toggleAction = delegate - { - autoLoadNutrition = !autoLoadNutrition; - }; - yield return command_Toggle; - if ((biotunedTo?.Ideo?.HasPrecept(PreceptDefOf.AgeReversal_Demanded)).GetValueOrDefault()) - { - Command_Toggle command_Toggle2 = new Command_Toggle(); - command_Toggle2.defaultLabel = "BiosculpterAutoAgeReversalLabel".Translate(biotunedTo.Named("PAWN")); - TaggedString taggedString = ((biotunedTo.ageTracker.AgeReversalDemandedDeadlineTicks > 0) ? "BiosculpterAutoAgeReversalDescriptionFuture".Translate(biotunedTo.Named("PAWN"), ((int)biotunedTo.ageTracker.AgeReversalDemandedDeadlineTicks).ToStringTicksToPeriodVague().Named("TIME")) : "BiosculpterAutoAgeReversalDescriptionNow".Translate(biotunedTo.Named("PAWN"))); - command_Toggle2.defaultDesc = "BiosculpterAutoAgeReversalDescription".Translate(biotunedTo.Named("PAWN"), taggedString.Named("NEXTTREATMENT")); - command_Toggle2.icon = AutoAgeReversalIcon; - command_Toggle2.isActive = () => AutoAgeReversal; - command_Toggle2.toggleAction = delegate - { - autoAgeReversal = !autoAgeReversal; - }; - if (!CanAgeReverse(biotunedTo)) - { - command_Toggle2.Disable("UnderMinBiosculpterAgeReversalAge".Translate(biotunedTo.ageTracker.AdultMinAge.Named("ADULTAGE")).CapitalizeFirst()); - autoAgeReversal = false; - } - yield return command_Toggle2; - } - foreach (Gizmo item in StorageSettingsClipboard.CopyPasteGizmosFor(allowedNutritionSettings)) - { - yield return item; - } - Gizmo gizmo = Building.SelectContainedItemGizmo(parent, Occupant); - if (gizmo != null) - { - yield return gizmo; - } - if (DebugSettings.ShowDevGizmos) - { - yield return new Command_Action - { - defaultLabel = "DEV: complete cycle", - action = delegate - { - currentCycleTicksRemaining = 10f; - }, - Disabled = (State != BiosculpterPodState.Occupied) - }; - yield return new Command_Action - { - defaultLabel = "DEV: advance cycle +1 day", - action = delegate - { - currentCycleTicksRemaining -= 60000f; - }, - Disabled = (State != BiosculpterPodState.Occupied) - }; - yield return new Command_Action - { - defaultLabel = "DEV: complete biotune timer", - action = delegate - { - biotunedCountdownTicks = 10; - }, - Disabled = (biotunedCountdownTicks <= 0) - }; - yield return new Command_Action - { - defaultLabel = "DEV: fill nutrition and cycle ingredients", - action = delegate - { - liquifiedNutrition = 5f; - devFillPodLatch = true; - }, - Disabled = (State == BiosculpterPodState.Occupied || (devFillPodLatch && liquifiedNutrition == 5f)) - }; - } - } - - private string IngredientsDescription(CompBiosculpterPod_Cycle cycle) - { - tmpIngredientsStrings.Clear(); - if (!cycle.Props.extraRequiredIngredients.NullOrEmpty() && !devFillPodLatch) - { - for (int i = 0; i < cycle.Props.extraRequiredIngredients.Count; i++) - { - tmpIngredientsStrings.Add(cycle.Props.extraRequiredIngredients[i].Summary); - } - } - return tmpIngredientsStrings.ToCommaList(useAnd: true); - } - - private string CycleDescription(CompBiosculpterPod_Cycle cycle) - { - StringBuilder stringBuilder = new StringBuilder(); - stringBuilder.Append(cycle.Description(biotunedTo)); - float num = cycle.Props.durationDays / CycleSpeedFactor; - float num2 = num / PreceptDefOf.Biosculpting_Accelerated.biosculpterPodCycleSpeedFactor; - stringBuilder.AppendLine("\n\n" + "BiosculpterPodCycleDuration".Translate() + ": " + ((int)(num * 60000f)).ToStringTicksToDays()); - if (!Find.IdeoManager.classicMode) - { - stringBuilder.Append("BiosculpterPodCycleDurationTranshumanists".Translate() + ": " + ((int)(num2 * 60000f)).ToStringTicksToDays()); - } - return stringBuilder.ToString(); - } - - public bool PawnCanUseNow(Pawn pawn, CompBiosculpterPod_Cycle cycle) - { - return (CannotUseNowReason() ?? CannotUseNowPawnReason(pawn) ?? CannotUseNowCycleReason(cycle) ?? CannotUseNowPawnCycleReason(pawn, cycle)) == null; - } - - public override IEnumerable CompFloatMenuOptions(Pawn selPawn) - { - if (selPawn.IsQuestLodger()) - { - yield return new FloatMenuOption("CannotEnter".Translate() + ": " + "CryptosleepCasketGuestsNotAllowed".Translate().CapitalizeFirst(), null); - yield break; - } - string cycleIndependentfailureReason = CannotUseNowReason() ?? CannotUseNowPawnReason(selPawn); - foreach (CompBiosculpterPod_Cycle cycle in AvailableCycles) - { - string text = cycleIndependentfailureReason ?? CannotUseNowCycleReason(cycle) ?? CannotUseNowPawnCycleReason(selPawn, cycle); - if (text != null) - { - yield return new FloatMenuOption(CannotStartText(cycle, text), null); - continue; - } - string label = "EnterBiosculpterPod".Translate(cycle.Props.label, ((int)(cycle.Props.durationDays / GetCycleSpeedFactorForPawn(selPawn) * 60000f)).ToStringTicksToDays()); - yield return FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption(label, delegate - { - PrepareCycleJob(selPawn, selPawn, cycle, EnterBiosculpterJob()); - }), selPawn, parent); - } - } - - public static bool CanAgeReverse(Pawn biosculptee) - { - return biosculptee.ageTracker.Adult; - } - - public static List BiotunedPods(Pawn pawn) - { - return cachedBiotunedPods.TryGetValue(pawn); - } - - public static bool HasBiotunedAutoAgeReversePod(Pawn pawn) - { - List list = cachedBiotunedPods.TryGetValue(pawn); - if (list == null) - { - return false; - } - foreach (CompBiosculpterPod item in list) - { - if (item.AutoAgeReversal) - { - return true; - } - } - return false; - } - - public static string CannotStartText(CompBiosculpterPod_Cycle cycle, string translatedReason) - { - return "BiosculpterCannotStartCycle".Translate(cycle.Props.label) + ": " + translatedReason.CapitalizeFirst(); - } - - public string CannotUseNowCycleReason(CompBiosculpterPod_Cycle cycle) - { - List list = cycle.MissingResearchLabels(); - if (list.Any()) - { - return "MissingRequiredResearch".Translate() + " " + list.ToCommaList(); - } - return null; - } - - public string CannotUseNowPawnCycleReason(Pawn p, CompBiosculpterPod_Cycle cycle, bool checkIngredients = true) - { - return CannotUseNowPawnCycleReason(p, p, cycle, checkIngredients); - } - - private bool CanReachOrHasIngredients(Pawn hauler, Pawn biosculptee, CompBiosculpterPod_Cycle cycle, bool useCache = false) - { - if (!PawnCarryingExtraCycleIngredients(biosculptee, cycle) && (biosculptee == hauler || !PawnCarryingExtraCycleIngredients(hauler, cycle))) - { - return CanReachRequiredIngredients(hauler, cycle, useCache); - } - return true; - } - - public string CannotUseNowPawnCycleReason(Pawn hauler, Pawn biosculptee, CompBiosculpterPod_Cycle cycle, bool checkIngredients = true) - { - if (AgeReversalCycleKey != null && cycle.Props.key == AgeReversalCycleKey && !CanAgeReverse(biosculptee)) - { - return "UnderMinBiosculpterAgeReversalAge".Translate(biosculptee.ageTracker.AdultMinAge.Named("ADULTAGE")).CapitalizeFirst(); - } - if (checkIngredients && !CanReachOrHasIngredients(hauler, biosculptee, cycle, useCache: true)) - { - return "BiosculpterMissingIngredients".Translate(IngredientsDescription(cycle).Named("INGREDIENTS")).CapitalizeFirst(); - } - return null; - } - - public string CannotUseNowPawnReason(Pawn p) - { - if (biotunedTo != null && biotunedTo != p) - { - return "BiosculpterBiotunedToAnother".Translate().CapitalizeFirst(); - } - if (!p.CanReach(parent, PathEndMode.InteractionCell, Danger.Deadly)) - { - return "NoPath".Translate().CapitalizeFirst(); - } - return null; - } - - public string CannotUseNowReason() - { - if (!PowerOn) - { - return "NoPower".Translate().CapitalizeFirst(); - } - if (State == BiosculpterPodState.LoadingNutrition) - { - return "BiosculpterNutritionNotLoaded".Translate().CapitalizeFirst(); - } - if (State == BiosculpterPodState.Occupied) - { - return "BiosculpterOccupied".Translate().CapitalizeFirst(); - } - return null; - } - - private List RequiredIngredients(CompBiosculpterPod_Cycle cycle) - { - List extraRequiredIngredients = cycle.Props.extraRequiredIngredients; - if (extraRequiredIngredients == null || devFillPodLatch) - { - return null; - } - if (!cachedExtraIngredients.ContainsKey(cycle)) - { - cachedExtraIngredients[cycle] = extraRequiredIngredients.Select((ThingDefCountClass tc) => tc.ToIngredientCount()).ToList(); - } - return cachedExtraIngredients[cycle]; - } - - private bool CanReachRequiredIngredients(Pawn pawn, CompBiosculpterPod_Cycle cycle, bool useCache = false) - { - chosenExtraItems.Clear(); - if (cycle.Props.extraRequiredIngredients == null || devFillPodLatch) - { - return true; - } - float realtimeSinceStartup = Time.realtimeSinceStartup; - if (useCache && cacheReachIngredientsPawn == pawn && cacheReachIngredientsCycle == cycle && realtimeSinceStartup < cacheReachIngredientsTime + 2f) - { - return cacheReachIngredientsResult; - } - cacheReachIngredientsPawn = pawn; - cacheReachIngredientsCycle = cycle; - cacheReachIngredientsTime = realtimeSinceStartup; - cacheReachIngredientsResult = WorkGiver_DoBill.TryFindBestFixedIngredients(RequiredIngredients(cycle), pawn, parent, chosenExtraItems); - return cacheReachIngredientsResult; - } - - private bool SelectPawnCycleOption(Pawn pawn, CompBiosculpterPod_Cycle cycle, out FloatMenuOption option) - { - string text = CannotUseNowPawnReason(pawn) ?? CannotUseNowPawnCycleReason(pawn, cycle, checkIngredients: false); - string label = pawn.Label + ((text == null) ? "" : (": " + text)); - Action action = null; - if (text == null) - { - action = delegate - { - PrepareCycleJob(pawn, pawn, cycle, EnterBiosculpterJob()); - }; - } - option = new FloatMenuOption(label, action); - return text == null; - } - - private bool SelectPawnsForCycleOptions(CompBiosculpterPod_Cycle cycle, out List options, bool shortCircuit = false) - { - cycleEligiblePawnOptions.Clear(); - options = cycleEligiblePawnOptions; - if (!cachedAnyPawnEligible.ContainsKey(cycle)) - { - cachedAnyPawnEligible[cycle] = new CacheAnyPawnEligibleCycle - { - gameTime = float.MinValue - }; - } - int ticksGame = Find.TickManager.TicksGame; - if (shortCircuit && (float)ticksGame < cachedAnyPawnEligible[cycle].gameTime + 2f) - { - return cachedAnyPawnEligible[cycle].anyEligible; - } - cachedAnyPawnEligible[cycle].gameTime = ticksGame; - if (biotunedTo != null) - { - if (biotunedTo.Dead || !biotunedTo.Spawned || biotunedTo.Map != parent.Map) - { - cachedAnyPawnEligible[cycle].anyEligible = false; - return cachedAnyPawnEligible[cycle].anyEligible; - } - if (SelectPawnCycleOption(biotunedTo, cycle, out var option) && shortCircuit) - { - cachedAnyPawnEligible[cycle].anyEligible = true; - return cachedAnyPawnEligible[cycle].anyEligible; - } - cycleEligiblePawnOptions.Add(option); - } - else - { - foreach (Pawn item in parent.Map.mapPawns.FreeColonistsSpawned) - { - if (SelectPawnCycleOption(item, cycle, out var option2) && shortCircuit) - { - cachedAnyPawnEligible[cycle].anyEligible = true; - return cachedAnyPawnEligible[cycle].anyEligible; - } - cycleEligiblePawnOptions.Add(option2); - } - } - cachedAnyPawnEligible[cycle].anyEligible = cycleEligiblePawnOptions.Count > 0; - return cachedAnyPawnEligible[cycle].anyEligible; - } - - public Job EnterBiosculpterJob() - { - return JobMaker.MakeJob(JobDefOf.EnterBiosculpterPod, parent); - } - - public Job MakeCarryToBiosculpterJob(Pawn willBeCarried) - { - return JobMaker.MakeJob(JobDefOf.CarryToBiosculpterPod, willBeCarried, LocalTargetInfo.Invalid, parent); - } - - public void ConfigureJobForCycle(Job job, CompBiosculpterPod_Cycle cycle, List extraIngredients) - { - if (!extraIngredients.NullOrEmpty()) - { - job.targetQueueB = new List(extraIngredients.Count); - job.countQueue = new List(extraIngredients.Count); - foreach (ThingCount extraIngredient in extraIngredients) - { - job.targetQueueB.Add(extraIngredient.Thing); - job.countQueue.Add(extraIngredient.Count); - } - } - job.haulMode = HaulMode.ToCellNonStorage; - job.biosculpterCycleKey = cycle.Props.key; - } - - public void PrepareCycleJob(Pawn hauler, Pawn biosculptee, CompBiosculpterPod_Cycle cycle, Job job) - { - OrderToPod(cycle, biosculptee, delegate - { - chosenExtraItems.Clear(); - if (!CanReachOrHasIngredients(hauler, biosculptee, cycle)) - { - Messages.Message("BiosculpterMissingIngredients".Translate(IngredientsDescription(cycle).Named("INGREDIENTS")).CapitalizeFirst(), parent, MessageTypeDefOf.NegativeEvent, historical: false); - } - else - { - ConfigureJobForCycle(job, cycle, chosenExtraItems); - if (cycle.Props.extraRequiredIngredients != null && !devFillPodLatch) - { - if (job.def == JobDefOf.CarryToBiosculpterPod) - { - Messages.Message("BiosculpterCarryStartedMessage".Translate(hauler.Named("PAWN"), IngredientsDescription(cycle).Named("INGREDIENTS"), biosculptee.Named("DOWNED"), cycle.Props.label.Named("CYCLE")), parent, MessageTypeDefOf.SilentInput, historical: false); - } - else - { - Messages.Message("BiosculpterLoadingStartedMessage".Translate(hauler.Named("PAWN"), IngredientsDescription(cycle).Named("INGREDIENTS"), cycle.Props.label.Named("CYCLE")), parent, MessageTypeDefOf.SilentInput, historical: false); - } - } - if (hauler.jobs.TryTakeOrderedJob(job, JobTag.Misc)) - { - SetQueuedInformation(job, biosculptee); - } - } - }); - } - - public void ClearQueuedInformation() - { - SetQueuedInformation(null, null); - } - - public void SetQueuedInformation(Job job, Pawn biosculptee) - { - queuedEnterJob = job; - queuedPawn = biosculptee; - } - - public bool CanAcceptNutrition(Thing thing) - { - return allowedNutritionSettings.AllowedToAccept(thing); - } - - public bool CanAcceptOnceCycleChosen(Pawn pawn) - { - if (State != BiosculpterPodState.SelectingCycle || !PowerOn) - { - return false; - } - if (biotunedTo != null && biotunedTo != pawn) - { - return false; - } - return true; - } - - public bool PawnCarryingExtraCycleIngredients(Pawn pawn, string cycleKey, bool remove = false) - { - return PawnCarryingExtraCycleIngredients(pawn, GetCycle(cycleKey), remove); - } - - public bool PawnCarryingExtraCycleIngredients(Pawn pawn, CompBiosculpterPod_Cycle cycle, bool remove = false) - { - if (cycle.Props.extraRequiredIngredients.NullOrEmpty() || devFillPodLatch) - { - return true; - } - foreach (ThingDefCountClass extraRequiredIngredient in cycle.Props.extraRequiredIngredients) - { - if (pawn.inventory.Count(extraRequiredIngredient.thingDef) < extraRequiredIngredient.count) - { - return false; - } - } - if (remove) - { - foreach (ThingDefCountClass extraRequiredIngredient2 in cycle.Props.extraRequiredIngredients) - { - pawn.inventory.RemoveCount(extraRequiredIngredient2.thingDef, extraRequiredIngredient2.count); - } - } - return true; - } - - public bool TryAcceptPawn(Pawn pawn, string cycleKey) - { - return TryAcceptPawn(pawn, GetCycle(cycleKey)); - } - - public bool TryAcceptPawn(Pawn pawn, CompBiosculpterPod_Cycle cycle) - { - if (!CanAcceptOnceCycleChosen(pawn)) - { - return false; - } - if (!PawnCarryingExtraCycleIngredients(pawn, cycle, remove: true)) - { - return false; - } - currentCycleKey = cycle.Props.key; - innerContainer.ClearAndDestroyContents(); - pawnEnteringBiosculpter = pawn; - bool num = pawn.DeSpawnOrDeselect(); - if (pawn.holdingOwner != null) - { - pawn.holdingOwner.TryTransferToContainer(pawn, innerContainer); - } - else - { - innerContainer.TryAdd(pawn); - } - if (num) - { - Find.Selector.Select(pawn, playSound: false, forceDesignatorDeselect: false); - } - pawnEnteringBiosculpter = null; - currentCycleTicksRemaining = cycle.Props.durationDays * 60000f; - liquifiedNutrition = 0f; - devFillPodLatch = false; - ClearQueuedInformation(); - tickEntered = Find.TickManager.TicksGame; - return true; - } - - public void EjectContents(bool interrupted, bool playSounds, Map destMap = null) - { - if (destMap == null) - { - destMap = parent.Map; - } - Pawn occupant = Occupant; - currentCycleKey = null; - currentCycleTicksRemaining = 0f; - currentCyclePowerCutTicks = 0; - liquifiedNutrition = 0f; - devFillPodLatch = false; - innerContainer.TryDropAll(parent.InteractionCell, destMap, ThingPlaceMode.Near); - if (occupant != null) - { - FilthMaker.TryMakeFilth(parent.InteractionCell, destMap, ThingDefOf.Filth_PodSlime, new IntRange(3, 6).RandomInRange); - if (interrupted) - { - occupant.needs?.mood.thoughts.memories.TryGainMemory(ThoughtDefOf.SoakingWet); - occupant.health?.AddHediff(HediffDefOf.BiosculptingSickness); - } - } - if (playSounds) - { - Props.exitSound?.PlayOneShot(SoundInfo.InMap(new TargetInfo(parent.Position, parent.Map))); - } - } - - private void CycleCompleted() - { - Pawn occupant = Occupant; - CompBiosculpterPod_Cycle currentCycle = CurrentCycle; - SetBiotuned(occupant); - currentCycle.CycleCompleted(occupant); - EjectContents(interrupted: false, playSounds: true); - if (occupant != null) - { - Need_Food need_Food = occupant.needs?.food; - if (need_Food != null) - { - need_Food.CurLevelPercentage = 1f; - } - Need_Rest need_Rest = occupant.needs?.rest; - if (need_Rest != null) - { - need_Rest.CurLevelPercentage = 1f; - } - if (currentCycle.Props.gainThoughtOnCompletion != null) - { - occupant.needs?.mood?.thoughts.memories.TryGainMemory(ThoughtDefOf.AgeReversalReceived); - } - Find.HistoryEventsManager.RecordEvent(new HistoryEvent(HistoryEventDefOf.UsedBiosculpterPod, occupant.Named(HistoryEventArgsNames.Doer))); - } - if (tickEntered > 0) - { - occupant.drugs.Notify_LeftSuspension(Find.TickManager.TicksGame - tickEntered); - } - } - - private void LiquifyNutrition() - { - tmpItems.AddRange(innerContainer); - foreach (Thing tmpItem in tmpItems) - { - float num = tmpItem.GetStatValue(StatDefOf.Nutrition) * (float)tmpItem.stackCount; - if (!(num <= 0f) && !(tmpItem is Pawn)) - { - liquifiedNutrition = Mathf.Min(5f, liquifiedNutrition + num); - tmpItem.Destroy(); - } - } - tmpItems.Clear(); - } - - public override void CompTick() - { - if (!ModLister.CheckIdeology("Biosculpting")) - { - return; - } - base.CompTick(); - if (State != BiosculpterPodState.SelectingCycle || !PowerOn) - { - readyEffecter?.Cleanup(); - readyEffecter = null; - } - else if (Props.readyEffecter != null) - { - if (readyEffecter == null) - { - readyEffecter = Props.readyEffecter.Spawn(); - ColorizeEffecter(readyEffecter, Props.selectCycleColor); - readyEffecter.Trigger(parent, new TargetInfo(parent.InteractionCell, parent.Map)); - } - readyEffecter.EffectTick(parent, new TargetInfo(parent.InteractionCell, parent.Map)); - } - if (State != BiosculpterPodState.Occupied) - { - progressBarEffecter?.Cleanup(); - progressBarEffecter = null; - operatingEffecter?.Cleanup(); - operatingEffecter = null; - } - else - { - Pawn occupant = Occupant; - biotunedCountdownTicks = 4800000; - if (PowerOn) - { - int num = 1; - currentCycleTicksRemaining -= (float)num * CycleSpeedFactor; - if (currentCycleTicksRemaining <= 0f) - { - CycleCompleted(); - } - } - else - { - currentCyclePowerCutTicks++; - if (currentCyclePowerCutTicks >= 60000) - { - EjectContents(interrupted: true, playSounds: true); - Messages.Message("BiosculpterNoPowerEjectedMessage".Translate(occupant.Named("PAWN")), occupant, MessageTypeDefOf.NegativeEvent, historical: false); - } - } - if (currentCycleTicksRemaining > 0f) - { - if (progressBarEffecter == null) - { - progressBarEffecter = EffecterDefOf.ProgressBar.Spawn(); - } - progressBarEffecter.EffectTick(parent, TargetInfo.Invalid); - MoteProgressBar moteProgressBar = (progressBarEffecter.children[0] as SubEffecter_ProgressBar)?.mote; - if (moteProgressBar != null) - { - float num2 = CurrentCycle.Props.durationDays * 60000f; - moteProgressBar.progress = 1f - Mathf.Clamp01(currentCycleTicksRemaining / num2); - int num3 = (parent.RotatedSize.z - 1) / 2; - moteProgressBar.offsetZ = 0f - ((float)num3 + 0.5f); - } - if (Props.operatingEffecter != null) - { - if (!PowerOn) - { - operatingEffecter?.Cleanup(); - operatingEffecter = null; - } - else - { - if (operatingEffecter == null) - { - operatingEffecter = Props.operatingEffecter.Spawn(); - ColorizeEffecter(operatingEffecter, CurrentCycle.Props.operatingColor); - operatingEffecter.Trigger(parent, new TargetInfo(parent.InteractionCell, parent.Map)); - } - operatingEffecter.EffectTick(parent, new TargetInfo(parent.InteractionCell, parent.Map)); - } - } - } - } - if (PowerOn && biotunedCountdownTicks > 0) - { - biotunedCountdownTicks--; - } - if (biotunedCountdownTicks <= 0) - { - SetBiotuned(null); - } - SetPower(); - if (biotunedTo?.Ideo != null && !biotunedTo.Ideo.HasPrecept(PreceptDefOf.AgeReversal_Demanded)) - { - autoAgeReversal = false; - } - } - - private void SetPower() - { - if (powerTraderComp == null) - { - powerTraderComp = parent.TryGetComp(); - } - if (powerComp == null) - { - powerComp = parent.TryGetComp(); - } - if (State == BiosculpterPodState.Occupied) - { - powerTraderComp.PowerOutput = 0f - powerComp.Props.PowerConsumption; - } - else - { - powerTraderComp.PowerOutput = 0f - powerComp.Props.idlePowerDraw; - } - } - - private void ColorizeEffecter(Effecter effecter, Color color) - { - foreach (SubEffecter child in effecter.children) - { - if (child is SubEffecter_Sprayer subEffecter_Sprayer) - { - subEffecter_Sprayer.colorOverride = color * child.def.color; - } - } - } - - public override void PostDraw() - { - base.PostDraw(); - Rot4 rotation = parent.Rotation; - Vector3 s = new Vector3(parent.def.graphicData.drawSize.x * 0.8f, 1f, parent.def.graphicData.drawSize.y * 0.8f); - Vector3 drawPos = parent.DrawPos; - drawPos.y -= 0.07317074f; - Graphics.DrawMesh(MeshPool.plane10, Matrix4x4.TRS(drawPos, rotation.AsQuat, s), BackgroundMat, 0); - if (State == BiosculpterPodState.Occupied) - { - Pawn occupant = Occupant; - Vector3 drawLoc = parent.DrawPos + FloatingOffset(currentCycleTicksRemaining + (float)currentCyclePowerCutTicks); - Rot4 rotation2 = parent.Rotation; - if (rotation2 == Rot4.East || rotation2 == Rot4.West) - { - drawLoc.z += 0.2f; - } - occupant.Drawer.renderer.RenderPawnAt(drawLoc, null, neverAimWeapon: true); - } - } - - public static Vector3 FloatingOffset(float tickOffset) - { - float num = tickOffset % 500f / 500f; - float num2 = Mathf.Sin(MathF.PI * num); - float z = num2 * num2 * 0.04f; - return new Vector3(0f, 0f, z); - } - - public void GetChildHolders(List outChildren) - { - ThingOwnerUtility.AppendThingHoldersFromThings(outChildren, GetDirectlyHeldThings()); - } - - public ThingOwner GetDirectlyHeldThings() - { - return innerContainer; - } - - public StorageSettings GetStoreSettings() - { - return allowedNutritionSettings; - } - - public StorageSettings GetParentStoreSettings() - { - return parent.def.building.fixedStorageSettings; - } - - public void Notify_SettingsChanged() - { - } - - private static void OrderToPod(CompBiosculpterPod_Cycle cycle, Pawn pawn, Action giveJobAct) - { - if (cycle is CompBiosculpterPod_HealingCycle compBiosculpterPod_HealingCycle) - { - string healingDescriptionForPawn = compBiosculpterPod_HealingCycle.GetHealingDescriptionForPawn(pawn); - string text = (healingDescriptionForPawn.NullOrEmpty() ? "BiosculpterNoCoditionsToHeal".Translate(pawn.Named("PAWN"), compBiosculpterPod_HealingCycle.Props.label.Named("CYCLE")).Resolve() : ("OnCompletionOfCycle".Translate(compBiosculpterPod_HealingCycle.Props.label.Named("CYCLE")).Resolve() + ":\n\n" + healingDescriptionForPawn)); - Find.WindowStack.Add(Dialog_MessageBox.CreateConfirmation(text, giveJobAct, healingDescriptionForPawn.NullOrEmpty())); - } - else - { - giveJobAct(); - } - } - - public static Thing FindPodFor(Pawn pawn, Pawn traveller, bool biotuned) - { - if (cachedPodDefs.NullOrEmpty()) - { - cachedPodDefs = DefDatabase.AllDefs.Where((ThingDef def) => def.GetCompProperties() != null).ToList(); - } - foreach (ThingDef cachedPodDef in cachedPodDefs) - { - Thing thing = GenClosest.ClosestThingReachable(traveller.Position, pawn.Map, ThingRequest.ForDef(cachedPodDef), PathEndMode.InteractionCell, TraverseParms.For(pawn), 9999f, Validator); - if (thing != null) - { - return thing; - } - } - return null; - bool Validator(Thing t) - { - CompBiosculpterPod compBiosculpterPod = t.TryGetComp(); - if (biotuned && compBiosculpterPod.biotunedTo != traveller) - { - return false; - } - return compBiosculpterPod.CanAcceptOnceCycleChosen(traveller); - } - } - - public static bool WasLoadingCanceled(Thing thing) - { - CompBiosculpterPod compBiosculpterPod = thing.TryGetComp(); - if (compBiosculpterPod != null && compBiosculpterPod.State != 0) - { - return true; - } - return false; - } - - public void ClearCycle() - { - currentCycleKey = null; - } - - public void Notify_HauledTo(Pawn hauler, Thing thing, int count) - { - LiquifyNutrition(); - SoundDefOf.Standard_Drop.PlayOneShot(parent); - } -} -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\CompProperties_BiosculpterPod_BaseCycle.txt` -**相似度:** 0.7539 - -```csharp -public abstract class CompProperties_BiosculpterPod_BaseCycle : CompProperties -{ - [NoTranslate] - public string key; - - [MustTranslate] - public string label; - - [MustTranslate] - public string description; - - [NoTranslate] - public string iconPath; - - public float durationDays; - - public Color operatingColor = new Color(0.5f, 0.7f, 0.5f); - - public ThoughtDef gainThoughtOnCompletion; - - public List requiredResearch; - - public List extraRequiredIngredients; - - private Texture2D icon; - - public Texture2D Icon - { - get - { - if (icon == null) - { - icon = ContentFinder.Get(iconPath); - } - return icon; - } - } - - public string LabelCap => label.CapitalizeFirst(); -} -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\CompProperties_BiosculpterPod_PleasureCycle.txt` -**相似度:** 0.7363 - -```csharp -public class CompProperties_BiosculpterPod_PleasureCycle : CompProperties_BiosculpterPod_BaseCycle -{ - public CompProperties_BiosculpterPod_PleasureCycle() - { - compClass = typeof(CompBiosculpterPod_PleasureCycle); - } -} -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\CompProperties_BiosculpterPod_AgeReversalCycle.txt` -**相似度:** 0.7237 - -```csharp -public class CompProperties_BiosculpterPod_AgeReversalCycle : CompProperties_BiosculpterPod_BaseCycle -{ - public CompProperties_BiosculpterPod_AgeReversalCycle() - { - compClass = typeof(CompBiosculpterPod_AgeReversalCycle); - } -} -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\CompBiosculpterPod_Cycle.txt` -**相似度:** 0.7087 - -```csharp -public abstract class CompBiosculpterPod_Cycle : ThingComp -{ - private List tmpMissingResearchLabels = new List(); - - public CompProperties_BiosculpterPod_BaseCycle Props => (CompProperties_BiosculpterPod_BaseCycle)props; - - public abstract void CycleCompleted(Pawn occupant); - - public virtual string Description(Pawn tunedFor) - { - return Props.description; - } - - public List MissingResearchLabels() - { - tmpMissingResearchLabels.Clear(); - if (Props.requiredResearch.NullOrEmpty()) - { - return tmpMissingResearchLabels; - } - foreach (ResearchProjectDef item in Props.requiredResearch) - { - if (!item.IsFinished) - { - tmpMissingResearchLabels.Add(item.LabelCap); - } - } - return tmpMissingResearchLabels; - } -} -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\CompProperties_BiosculpterPod_HealingCycle.txt` -**相似度:** 0.6966 - -```csharp -public class CompProperties_BiosculpterPod_HealingCycle : CompProperties_BiosculpterPod_BaseCycle -{ - public List bodyPartsToRestore; - - public List conditionsToPossiblyCure; -} -``` \ No newline at end of file diff --git a/MCP/vector_cache/CompBiosculpterPod-WorkGiver_HaulToBiosculpterPod.txt b/MCP/vector_cache/CompBiosculpterPod-WorkGiver_HaulToBiosculpterPod.txt deleted file mode 100644 index 6bbbe9dc..00000000 --- a/MCP/vector_cache/CompBiosculpterPod-WorkGiver_HaulToBiosculpterPod.txt +++ /dev/null @@ -1,91 +0,0 @@ -根据向量相似度分析,与 'WorkGiver_HaulToBiosculpterPod, CompBiosculpterPod' 最相关的代码定义如下: - ---- -**文件路径 (精确匹配):** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\WorkGiver_HaulToBiosculpterPod.txt` - -```csharp -public class WorkGiver_HaulToBiosculpterPod : WorkGiver_Scanner -{ - public override ThingRequest PotentialWorkThingRequest => ThingRequest.ForDef(ThingDefOf.BiosculpterPod); - - public override PathEndMode PathEndMode => PathEndMode.Touch; - - public override bool HasJobOnThing(Pawn pawn, Thing t, bool forced = false) - { - if (!ModLister.CheckIdeology("Biosculpting")) - { - return false; - } - if (!pawn.CanReserve(t, 1, -1, null, forced)) - { - return false; - } - if (pawn.Map.designationManager.DesignationOn(t, DesignationDefOf.Deconstruct) != null) - { - return false; - } - CompBiosculpterPod compBiosculpterPod = t.TryGetComp(); - if (compBiosculpterPod == null || !compBiosculpterPod.PowerOn || compBiosculpterPod.State != 0 || (!forced && !compBiosculpterPod.autoLoadNutrition)) - { - return false; - } - if (t.IsBurning()) - { - return false; - } - if (compBiosculpterPod.RequiredNutritionRemaining > 0f) - { - if (FindNutrition(pawn, compBiosculpterPod).Thing == null) - { - JobFailReason.Is("NoFood".Translate()); - return false; - } - return true; - } - return false; - } - - public override Job JobOnThing(Pawn pawn, Thing t, bool forced = false) - { - CompBiosculpterPod compBiosculpterPod = t.TryGetComp(); - if (compBiosculpterPod == null) - { - return null; - } - if (compBiosculpterPod.RequiredNutritionRemaining > 0f) - { - ThingCount thingCount = FindNutrition(pawn, compBiosculpterPod); - if (thingCount.Thing != null) - { - Job job = HaulAIUtility.HaulToContainerJob(pawn, thingCount.Thing, t); - job.count = Mathf.Min(job.count, thingCount.Count); - return job; - } - } - return null; - } - - private ThingCount FindNutrition(Pawn pawn, CompBiosculpterPod pod) - { - Thing thing = GenClosest.ClosestThingReachable(pawn.Position, pawn.Map, ThingRequest.ForGroup(ThingRequestGroup.FoodSourceNotPlantOrTree), PathEndMode.ClosestTouch, TraverseParms.For(pawn), 9999f, Validator); - if (thing == null) - { - return default(ThingCount); - } - int b = Mathf.CeilToInt(pod.RequiredNutritionRemaining / thing.GetStatValue(StatDefOf.Nutrition)); - return new ThingCount(thing, Mathf.Min(thing.stackCount, b)); - bool Validator(Thing x) - { - if (x.IsForbidden(pawn) || !pawn.CanReserve(x)) - { - return false; - } - if (!pod.CanAcceptNutrition(x)) - { - return false; - } - return true; - } - } -} -``` \ No newline at end of file diff --git a/MCP/vector_cache/CompProperties_Refuelable.txt b/MCP/vector_cache/CompProperties_Refuelable.txt deleted file mode 100644 index 89d178ca..00000000 --- a/MCP/vector_cache/CompProperties_Refuelable.txt +++ /dev/null @@ -1,881 +0,0 @@ -根据向量相似度分析,与 'CompProperties_Refuelable' 最相关的代码定义如下: - ---- -**文件路径 (精确匹配):** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\CompProperties_Refuelable.txt` - -```csharp -public class CompProperties_Refuelable : CompProperties -{ - public float fuelConsumptionRate = 1f; - - public float fuelCapacity = 2f; - - public float initialFuelPercent; - - public float autoRefuelPercent = 0.3f; - - public float fuelConsumptionPerTickInRain; - - public ThingFilter fuelFilter; - - public bool destroyOnNoFuel; - - public bool consumeFuelOnlyWhenUsed; - - public bool consumeFuelOnlyWhenPowered; - - public bool showFuelGizmo; - - public bool initialAllowAutoRefuel = true; - - public bool showAllowAutoRefuelToggle; - - public bool allowRefuelIfNotEmpty = true; - - public bool fuelIsMortarBarrel; - - public bool targetFuelLevelConfigurable; - - public float initialConfigurableTargetFuelLevel; - - public bool drawOutOfFuelOverlay = true; - - public float minimumFueledThreshold; - - public bool drawFuelGaugeInMap; - - public bool atomicFueling; - - private float fuelMultiplier = 1f; - - public bool factorByDifficulty; - - [MustTranslate] - public string fuelLabel; - - [MustTranslate] - public string fuelGizmoLabel; - - [MustTranslate] - public string outOfFuelMessage; - - [NoTranslate] - public string fuelIconPath; - - public bool externalTicking; - - public bool hideGizmosIfNotPlayerFaction; - - public bool functionsInVacuum = true; - - private Texture2D fuelIcon; - - public string FuelLabel - { - get - { - if (fuelLabel.NullOrEmpty()) - { - return "Fuel".TranslateSimple(); - } - return fuelLabel; - } - } - - public string FuelGizmoLabel - { - get - { - if (fuelGizmoLabel.NullOrEmpty()) - { - return "Fuel".TranslateSimple(); - } - return fuelGizmoLabel; - } - } - - public Texture2D FuelIcon - { - get - { - if (fuelIcon == null) - { - if (!fuelIconPath.NullOrEmpty()) - { - fuelIcon = ContentFinder.Get(fuelIconPath); - } - else - { - ThingDef thingDef = ((fuelFilter.AnyAllowedDef == null) ? ThingDefOf.Chemfuel : fuelFilter.AnyAllowedDef); - fuelIcon = thingDef.uiIcon; - } - } - return fuelIcon; - } - } - - public float FuelMultiplierCurrentDifficulty - { - get - { - if (factorByDifficulty && Find.Storyteller?.difficulty != null) - { - return fuelMultiplier / Find.Storyteller.difficulty.maintenanceCostFactor; - } - return fuelMultiplier; - } - } - - public CompProperties_Refuelable() - { - compClass = typeof(CompRefuelable); - } - - public override void ResolveReferences(ThingDef parentDef) - { - base.ResolveReferences(parentDef); - fuelFilter.ResolveReferences(); - } - - public override IEnumerable ConfigErrors(ThingDef parentDef) - { - foreach (string item in base.ConfigErrors(parentDef)) - { - yield return item; - } - if (destroyOnNoFuel && initialFuelPercent <= 0f) - { - yield return "Refuelable component has destroyOnNoFuel, but initialFuelPercent <= 0"; - } - if ((!consumeFuelOnlyWhenUsed || fuelConsumptionPerTickInRain > 0f) && parentDef.tickerType != TickerType.Normal) - { - yield return $"Refuelable component set to consume fuel per tick, but parent tickertype is {parentDef.tickerType} instead of {TickerType.Normal}"; - } - } - - public override IEnumerable SpecialDisplayStats(StatRequest req) - { - foreach (StatDrawEntry item in base.SpecialDisplayStats(req)) - { - yield return item; - } - if (((ThingDef)req.Def).building.IsTurret) - { - yield return new StatDrawEntry(StatCategoryDefOf.Building, "ShotsBeforeRearm".Translate(), ((int)fuelCapacity).ToString(), "ShotsBeforeRearmExplanation".Translate(), 3171); - } - } -} -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\CompRefuelable.txt` -**相似度:** 0.7548 - -```csharp -public class CompRefuelable : ThingComp_VacuumAware, IThingGlower -{ - private float fuel; - - private float configuredTargetFuelLevel = -1f; - - public bool allowAutoRefuel = true; - - private CompFlickable flickComp; - - private CompExplosive explosiveComp; - - public const string RefueledSignal = "Refueled"; - - public const string RanOutOfFuelSignal = "RanOutOfFuel"; - - private static readonly Texture2D SetTargetFuelLevelCommand = ContentFinder.Get("UI/Commands/SetTargetFuelLevel"); - - private static readonly Vector2 FuelBarSize = new Vector2(1f, 0.2f); - - private static readonly Material FuelBarFilledMat = SolidColorMaterials.SimpleSolidColorMaterial(new Color(0.6f, 0.56f, 0.13f)); - - private static readonly Material FuelBarUnfilledMat = SolidColorMaterials.SimpleSolidColorMaterial(new Color(0.3f, 0.3f, 0.3f)); - - protected override bool FunctionsInVacuum => Props.functionsInVacuum; - - public float TargetFuelLevel - { - get - { - if (configuredTargetFuelLevel >= 0f) - { - return configuredTargetFuelLevel; - } - if (Props.targetFuelLevelConfigurable) - { - return Props.initialConfigurableTargetFuelLevel; - } - return Props.fuelCapacity; - } - set - { - configuredTargetFuelLevel = Mathf.Clamp(value, 0f, Props.fuelCapacity); - } - } - - public CompProperties_Refuelable Props => (CompProperties_Refuelable)props; - - public float Fuel => fuel; - - public float FuelPercentOfTarget => fuel / TargetFuelLevel; - - public float FuelPercentOfMax => fuel / Props.fuelCapacity; - - public bool IsFull => TargetFuelLevel - fuel < 1f; - - public bool HasFuel - { - get - { - if (fuel > 0f && fuel >= Props.minimumFueledThreshold) - { - if (!FunctionsInVacuum) - { - return !base.InVacuum; - } - return true; - } - return false; - } - } - - private float ConsumptionRatePerTick => Props.fuelConsumptionRate / 60000f; - - public bool ShouldAutoRefuelNow - { - get - { - if (FuelPercentOfTarget <= Props.autoRefuelPercent && !IsFull && TargetFuelLevel > 0f) - { - return ShouldAutoRefuelNowIgnoringFuelPct; - } - return false; - } - } - - public bool ShouldAutoRefuelNowIgnoringFuelPct - { - get - { - if (!parent.IsBurning() && (flickComp == null || flickComp.SwitchIsOn) && parent.Map.designationManager.DesignationOn(parent, DesignationDefOf.Flick) == null) - { - return parent.Map.designationManager.DesignationOn(parent, DesignationDefOf.Deconstruct) == null; - } - return false; - } - } - - public bool ShouldBeLitNow() - { - return HasFuel; - } - - public override void Initialize(CompProperties props) - { - base.Initialize(props); - allowAutoRefuel = Props.initialAllowAutoRefuel; - fuel = Props.fuelCapacity * Props.initialFuelPercent; - } - - public override void PostSpawnSetup(bool respawningAfterLoad) - { - flickComp = parent.GetComp(); - explosiveComp = parent.GetComp(); - } - - public override void PostExposeData() - { - base.PostExposeData(); - Scribe_Values.Look(ref fuel, "fuel", 0f); - Scribe_Values.Look(ref configuredTargetFuelLevel, "configuredTargetFuelLevel", -1f); - Scribe_Values.Look(ref allowAutoRefuel, "allowAutoRefuel", defaultValue: false); - if (Scribe.mode == LoadSaveMode.PostLoadInit && !Props.showAllowAutoRefuelToggle) - { - allowAutoRefuel = Props.initialAllowAutoRefuel; - } - } - - public override void PostDraw() - { - base.PostDraw(); - if (!allowAutoRefuel) - { - parent.Map.overlayDrawer.DrawOverlay(parent, OverlayTypes.ForbiddenRefuel); - } - else if (!HasFuel && Props.drawOutOfFuelOverlay) - { - parent.Map.overlayDrawer.DrawOverlay(parent, OverlayTypes.OutOfFuel); - } - if (Props.drawFuelGaugeInMap) - { - GenDraw.FillableBarRequest r = default(GenDraw.FillableBarRequest); - r.center = parent.DrawPos + Vector3.up * 0.1f; - r.size = FuelBarSize; - r.fillPercent = FuelPercentOfMax; - r.filledMat = FuelBarFilledMat; - r.unfilledMat = FuelBarUnfilledMat; - r.margin = 0.15f; - Rot4 rotation = parent.Rotation; - rotation.Rotate(RotationDirection.Clockwise); - r.rotation = rotation; - GenDraw.DrawFillableBar(r); - } - } - - public override void PostDestroy(DestroyMode mode, Map previousMap) - { - base.PostDestroy(mode, previousMap); - if ((!Props.fuelIsMortarBarrel || !Find.Storyteller.difficulty.classicMortars) && mode != 0 && previousMap != null && Props.fuelFilter.AllowedDefCount == 1 && Props.initialFuelPercent == 0f) - { - ThingDef thingDef = Props.fuelFilter.AllowedThingDefs.First(); - int num = Mathf.FloorToInt(1f * fuel); - while (num > 0) - { - Thing thing = ThingMaker.MakeThing(thingDef); - thing.stackCount = Mathf.Min(num, thingDef.stackLimit); - num -= thing.stackCount; - GenPlace.TryPlaceThing(thing, parent.Position, previousMap, ThingPlaceMode.Near); - } - } - } - - public override string CompInspectStringExtra() - { - if (Props.fuelIsMortarBarrel && Find.Storyteller.difficulty.classicMortars) - { - return string.Empty; - } - string text = base.CompInspectStringExtra(); - text = ((text != null) ? (text + "\n") : string.Empty); - text = text + Props.FuelLabel + ": " + fuel.ToStringDecimalIfSmall() + " / " + Props.fuelCapacity.ToStringDecimalIfSmall(); - if (!Props.consumeFuelOnlyWhenUsed && HasFuel) - { - int numTicks = (int)(fuel / Props.fuelConsumptionRate * 60000f); - text = text + " (" + numTicks.ToStringTicksToPeriod() + ")"; - } - if (!HasFuel && !Props.outOfFuelMessage.NullOrEmpty()) - { - string arg = ((parent.def.building != null && parent.def.building.IsTurret) ? ("CannotShoot".Translate() + ": " + Props.outOfFuelMessage).Resolve() : Props.outOfFuelMessage); - text += $"\n{arg} ({GetFuelCountToFullyRefuel()}x {Props.fuelFilter.AnyAllowedDef.label})"; - } - if (Props.targetFuelLevelConfigurable) - { - text += "\n" + "ConfiguredTargetFuelLevel".Translate(TargetFuelLevel.ToStringDecimalIfSmall()); - } - return text; - } - - public override IEnumerable SpecialDisplayStats() - { - if (parent.def.building != null && parent.def.building.IsTurret) - { - TaggedString taggedString = "RearmCostExplanation".Translate(); - if (Props.factorByDifficulty) - { - taggedString += " (" + "RearmCostExplanationDifficulty".Translate() + ")"; - } - taggedString += "."; - yield return new StatDrawEntry(StatCategoryDefOf.Building, "RearmCost".Translate(), GenLabel.ThingLabel(Props.fuelFilter.AnyAllowedDef, null, GetFuelCountToFullyRefuel()).CapitalizeFirst(), taggedString, 3171); - } - } - - public override void CompTick() - { - base.CompTick(); - CompPowerTrader comp = parent.GetComp(); - if (!Props.consumeFuelOnlyWhenUsed && (flickComp == null || flickComp.SwitchIsOn) && (!Props.consumeFuelOnlyWhenPowered || (comp != null && comp.PowerOn)) && !Props.externalTicking) - { - ConsumeFuel(ConsumptionRatePerTick); - } - if (Props.fuelConsumptionPerTickInRain > 0f && parent.Spawned && parent.Map.weatherManager.RainRate > 0.4f && !parent.Map.roofGrid.Roofed(parent.Position) && !Props.externalTicking) - { - ConsumeFuel(Props.fuelConsumptionPerTickInRain); - } - } - - public void ConsumeFuel(float amount) - { - if ((!Props.fuelIsMortarBarrel || !Find.Storyteller.difficulty.classicMortars) && !(fuel <= 0f)) - { - fuel -= amount; - if (fuel <= 0f) - { - fuel = 0f; - Notify_RanOutOfFuel(); - } - } - } - - private void Notify_RanOutOfFuel() - { - if (Props.destroyOnNoFuel) - { - parent.Destroy(); - } - parent.BroadcastCompSignal("RanOutOfFuel"); - } - - public void Refuel(List fuelThings) - { - if (Props.atomicFueling && fuelThings.Sum((Thing t) => t.stackCount) < GetFuelCountToFullyRefuel()) - { - Log.ErrorOnce("Error refueling; not enough fuel available for proper atomic refuel", 19586442); - return; - } - int num = GetFuelCountToFullyRefuel(); - while (num > 0 && fuelThings.Count > 0) - { - Thing thing = fuelThings.Pop(); - int num2 = Mathf.Min(num, thing.stackCount); - Refuel(num2); - thing.SplitOff(num2).Destroy(); - num -= num2; - } - } - - public void Refuel(float amount) - { - fuel += amount * Props.FuelMultiplierCurrentDifficulty; - if (fuel > Props.fuelCapacity) - { - fuel = Props.fuelCapacity; - } - parent.BroadcastCompSignal("Refueled"); - } - - public AcceptanceReport CanEjectFuel() - { - CompExplosive compExplosive = explosiveComp; - if (compExplosive != null && compExplosive.wickStarted) - { - return "AboutToExplode".Translate(); - } - if (Fuel == 0f) - { - return "RefuelableNoFuelToEject".Translate(); - } - return true; - } - - public void EjectFuel() - { - ThingDef thingDef = Props.fuelFilter.AllowedThingDefs.First(); - int num = Mathf.FloorToInt(fuel); - while (num > 0) - { - Thing thing = ThingMaker.MakeThing(thingDef); - thing.stackCount = Mathf.Min(num, thingDef.stackLimit); - num -= thing.stackCount; - GenPlace.TryPlaceThing(thing, parent.Position, parent.Map, ThingPlaceMode.Near); - thing.SetForbidden(value: true); - } - fuel = 0f; - Notify_RanOutOfFuel(); - } - - public void Notify_UsedThisTick() - { - ConsumeFuel(ConsumptionRatePerTick); - } - - public int GetFuelCountToFullyRefuel() - { - if (Props.atomicFueling) - { - return Mathf.CeilToInt(Props.fuelCapacity / Props.FuelMultiplierCurrentDifficulty); - } - return Mathf.Max(Mathf.CeilToInt((TargetFuelLevel - fuel) / Props.FuelMultiplierCurrentDifficulty), 1); - } - - public override IEnumerable CompGetGizmosExtra() - { - if (Props.fuelIsMortarBarrel && Find.Storyteller.difficulty.classicMortars) - { - yield break; - } - if (!Props.hideGizmosIfNotPlayerFaction || parent.Faction == Faction.OfPlayer) - { - if (Find.Selector.SelectedObjects.Count == 1) - { - yield return new Gizmo_SetFuelLevel(this); - } - else - { - if (Props.targetFuelLevelConfigurable) - { - Command_SetTargetFuelLevel command_SetTargetFuelLevel = new Command_SetTargetFuelLevel(); - command_SetTargetFuelLevel.refuelable = this; - command_SetTargetFuelLevel.defaultLabel = "CommandSetTargetFuelLevel".Translate(); - command_SetTargetFuelLevel.defaultDesc = "CommandSetTargetFuelLevelDesc".Translate(); - command_SetTargetFuelLevel.icon = SetTargetFuelLevelCommand; - yield return command_SetTargetFuelLevel; - } - if (Props.showAllowAutoRefuelToggle) - { - string str = (allowAutoRefuel ? "On".Translate() : "Off".Translate()); - Command_Toggle command_Toggle = new Command_Toggle(); - command_Toggle.isActive = () => allowAutoRefuel; - command_Toggle.toggleAction = delegate - { - allowAutoRefuel = !allowAutoRefuel; - }; - command_Toggle.defaultLabel = "CommandToggleAllowAutoRefuel".Translate(); - command_Toggle.defaultDesc = "CommandToggleAllowAutoRefuelDescMult".Translate(str.UncapitalizeFirst().Named("ONOFF")); - command_Toggle.icon = (allowAutoRefuel ? TexCommand.ForbidOn : TexCommand.ForbidOff); - command_Toggle.Order = 20f; - command_Toggle.hotKey = KeyBindingDefOf.Command_ItemForbid; - yield return command_Toggle; - } - } - } - if (DebugSettings.ShowDevGizmos) - { - Command_Action command_Action = new Command_Action(); - command_Action.defaultLabel = "DEV: Set fuel to 0"; - command_Action.action = delegate - { - fuel = 0f; - parent.BroadcastCompSignal("Refueled"); - }; - yield return command_Action; - Command_Action command_Action2 = new Command_Action(); - command_Action2.defaultLabel = "DEV: Set fuel to 0.1"; - command_Action2.action = delegate - { - fuel = 0.1f; - parent.BroadcastCompSignal("Refueled"); - }; - yield return command_Action2; - Command_Action command_Action3 = new Command_Action(); - command_Action3.defaultLabel = "DEV: Fuel -20%"; - command_Action3.action = delegate - { - ConsumeFuel(Props.fuelCapacity * 0.2f); - }; - yield return command_Action3; - Command_Action command_Action4 = new Command_Action(); - command_Action4.defaultLabel = "DEV: Set fuel to max"; - command_Action4.action = delegate - { - fuel = Props.fuelCapacity; - parent.BroadcastCompSignal("Refueled"); - }; - yield return command_Action4; - } - } -} -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\Odyssey\Defs\ThingDefs_Buildings\Buildings_Gravship.xml` -**相似度:** 0.5864 - -```xml - ChemfuelTank - - A chemfuel storage tank that supplies fuel for thrusters on a gravship. - - Graphic_Multi - Things/Building/ChemfuelTank/ChemfuelTank - (2, 2) - - - 200 - 30 - 1 - -10 - 2000 - - (2, 2) - - 120 - - -
  • BasicGravtech
  • -
    - -
  • - 250 - true - 250 - - -
  • Chemfuel
  • - - - Chemfuel - Chemfuel - true - 1 - true - false - true - true - false - -
    -
    - - - LargeChemfuelTank -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\Core\Defs\ThingDefs_Buildings\Buildings_Power.xml` -**相似度:** 0.5793 - -```xml - WoodFiredGenerator - - Produces power by consuming wood. Must be periodically loaded with wood fuel by hand. - Building - MapMeshAndRealTime - - Things/Building/Power/WoodFiredGenerator - Graphic_Single - (2,2) - - (1.93,1,1.69) - (-0.03,0,-0.1) - - - Building - PassThroughOnly - 0.9 - 50 - false - true - false - - 300 - 2500 - 1.0 - -20 - - Normal - false - (2,2) - - BuildingDestroyed_Metal_Medium - - - 100 - 2 - - -
  • - CompPowerPlant - -1000 - true - WoodFiredGenerator_Ambience -
  • -
  • -
  • - 22.0 - 75.0 - - -
  • WoodLog
  • - - - true - true - -
  • - 6 - (217,112,33,0) -
  • -
  • - CompHeatPusherPowered - 6 -
  • -
  • -
  • - true - -
  • EMP
  • - - -
    - Medium - Power - 2100 - Misc3 - ConstructMetal - -
  • Electricity
  • -
    - 4 -
    - - - ChemfuelPoweredGenerator -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\Biotech\Defs\ThingDefs_Buildings\Buildings_Deathrest.xml` -**相似度:** 0.5764 - -```xml - - -
  • - CompPowerTrader - 100 - 0 - true -
  • -
  • -
  • - 0.5 - 5 - Hemogen - - -
  • HemogenPack
  • - - - 1 - true - true - 0.05 - true - -
    -
    -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\Core\Defs\ThingDefs_Buildings\Buildings_Temperature.xml` -**相似度:** 0.5668 - -```xml - BulletImpact_Ground - false - 0 - -
  • PlaceWorker_PreventInteractionSpotOverlap
  • -
  • PlaceWorker_Heater
  • -
  • PlaceWorker_GlowRadius
  • -
    - true - -
  • - 10.0 - 20.0 - 0.0006 - - -
  • WoodLog
  • - - - 1 - true - false - -
  • - 10 - (252,187,113,0) -
  • -
  • - CompHeatPusherPowered - 21 - 28 -
  • -
  • - 1 -
  • -
  • - CompGatherSpot -
  • -
  • - MeditationFocusStrength -
  • Flame
  • - -
  • - 0.12 -
  • -
  • - -
  • Campfire
  • -
  • TorchLamp
  • -
  • Brazier
  • -
  • DarklightBrazier
  • -
  • Darktorch
  • -
  • DarktorchFungus
  • - - 0.02 - 9.9 - 8 - MeditationFocusPerFlame - MeditationFocusPerFlameAbstract - -
    - -
    - Temperature - Misc1 - True - (0,0,-1) - -
  • CookMealSimple
  • -
  • CookMealSimpleBulk
  • -
  • Make_Pemmican
  • -
  • Make_PemmicanBulk
  • -
  • BurnApparel
  • -
  • BurnWeapon
  • -
  • BurnDrugs
  • -
  • Make_BabyFood
  • -
  • Make_BabyFoodBulk
  • -
    - -
  • ITab_Bills
  • -
    - - true - BillsTab - false - BuildingDestroyed_Wood_Small - -
    - - - PassiveCooler - - A traditional unpowered cooler that works by water evaporation. Must be regularly replenished with wood. Not efficient enough to refrigerate food. - Building - - Things/Building/Misc/PassiveCooler - Graphic_Single - false - false - true - - (0.9,0.3,0.9) - - - (0.2,0,0.6,0.1) - - - false - Building - PassThroughOnly - 30 - ConstructDirt - Normal - RealtimeOnly - 0.40 - - 80 - 200 - 1 - - true - - 50 - - - BuildingDestroyed_Metal_Small - - BulletImpact_Ground -``` \ No newline at end of file diff --git a/MCP/vector_cache/CryptosleepCasket.txt b/MCP/vector_cache/CryptosleepCasket.txt deleted file mode 100644 index 5502f0c1..00000000 --- a/MCP/vector_cache/CryptosleepCasket.txt +++ /dev/null @@ -1,267 +0,0 @@ -根据向量相似度分析,与 'CryptosleepCasket' 最相关的代码定义如下: - ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\RoomContents_CryptosleepCasket.txt` -**相似度:** 0.7176 - -```csharp -public class RoomContents_CryptosleepCasket : RoomContentsWorker -{ - private const string OpenedSignal = "OpenedSignal"; - - public override void FillRoom(Map map, LayoutRoom room, Faction faction, float? threatPoints = null) - { - if (!room.TryGetRandomCellInRoom(map, out var cell, 3)) - { - cell = room.rects[0].CenterCell; - } - int nextAncientCryptosleepCasketGroupID = Find.UniqueIDsManager.GetNextAncientCryptosleepCasketGroupID(); - PodContentsType type = Gen.RandomEnumValue(disallowFirstValue: true); - Building_AncientCryptosleepCasket pod = RoomGenUtility.SpawnCryptoCasket(cell, map, Rot4.Random, nextAncientCryptosleepCasketGroupID, type, ThingSetMakerDefOf.MapGen_ScarlandsAncientPodContents); - ThreatSignal = "OpenedSignal" + Find.UniqueIDsManager.GetNextSignalTagID(); - RoomGenUtility.SpawnOpenCryptoCasketSignal(pod, map, ThreatSignal); - base.FillRoom(map, room, faction, threatPoints); - } -} -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\Building_AncientCryptosleepPod.txt` -**相似度:** 0.7115 - -```csharp -public class Building_AncientCryptosleepPod : Building_AncientCryptosleepCasket -{ - public override IEnumerable GetFloatMenuOptions(Pawn myPawn) - { - return Enumerable.Empty(); - } -} -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\Building_AncientCryptosleepCasket.txt` -**相似度:** 0.7023 - -```csharp -public class Building_AncientCryptosleepCasket : Building_CryptosleepCasket -{ - public int groupID = -1; - - public override void ExposeData() - { - base.ExposeData(); - Scribe_Values.Look(ref groupID, "groupID", 0); - } - - public override void PreApplyDamage(ref DamageInfo dinfo, out bool absorbed) - { - base.PreApplyDamage(ref dinfo, out absorbed); - if (absorbed) - { - return; - } - if (!contentsKnown && innerContainer.Count > 0 && dinfo.Def.harmsHealth && dinfo.Instigator != null && dinfo.Instigator.Faction != null) - { - bool flag = false; - foreach (Thing item in (IEnumerable)innerContainer) - { - if (item is Pawn) - { - flag = true; - break; - } - } - if (flag) - { - EjectContents(); - } - } - absorbed = false; - } - - public override void EjectContents() - { - bool num = contentsKnown; - List list = null; - if (!num) - { - list = new List(); - list.AddRange(innerContainer); - list.AddRange(UnopenedCasketsInGroup().SelectMany((Building_AncientCryptosleepCasket c) => c.innerContainer)); - list.RemoveDuplicates(); - } - base.EjectContents(); - if ((bool)ClaimableBy(Faction.OfPlayer)) - { - SetFaction(null); - } - if (num) - { - return; - } - ThingDef filth_Slime = ThingDefOf.Filth_Slime; - FilthMaker.TryMakeFilth(base.Position, base.Map, filth_Slime, Rand.Range(8, 12)); - foreach (Building_AncientCryptosleepCasket item in UnopenedCasketsInGroup()) - { - item.contentsKnown = true; - item.EjectContents(); - } - IEnumerable enumerable = from p in list.OfType().ToList() - where p.RaceProps.Humanlike && p.GetLord() == null && p.Faction == Faction.OfAncientsHostile - select p; - if (enumerable.Any()) - { - LordMaker.MakeNewLord(Faction.OfAncientsHostile, new LordJob_AssaultColony(Faction.OfAncientsHostile, canKidnap: false, canTimeoutOrFlee: true, sappers: false, useAvoidGridSmart: false, canSteal: false), base.Map, enumerable); - } - } - - private IEnumerable UnopenedCasketsInGroup() - { - yield return this; - if (groupID == -1) - { - yield break; - } - foreach (Thing item in base.Map.listerThings.ThingsOfDef(ThingDefOf.AncientCryptosleepCasket)) - { - Building_AncientCryptosleepCasket building_AncientCryptosleepCasket = item as Building_AncientCryptosleepCasket; - if (building_AncientCryptosleepCasket.groupID == groupID && !building_AncientCryptosleepCasket.contentsKnown) - { - yield return building_AncientCryptosleepCasket; - } - } - } -} -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\ComplexThreatWorker_CryptosleepPods.txt` -**相似度:** 0.6424 - -```csharp -public class ComplexThreatWorker_CryptosleepPods : ComplexThreatWorker -{ - private const string TriggerOpenAction = "TriggerOpenAction"; - - private const string CompletedOpenAction = "CompletedOpenAction"; - - private const float RoomEntryTriggerChance = 0.25f; - - protected override bool CanResolveInt(ComplexResolveParams parms) - { - if (base.CanResolveInt(parms) && ComplexUtility.TryFindRandomSpawnCell(ThingDefOf.AncientCryptosleepPod, parms.room, parms.map, out var _) && parms.points >= PawnKindDefOf.AncientSoldier.combatPower) - { - if (parms.hostileFaction != null) - { - return parms.hostileFaction == Faction.OfAncientsHostile; - } - return true; - } - return false; - } - - protected override void ResolveInt(ComplexResolveParams parms, ref float threatPointsUsed, List outSpawnedThings) - { - List list = SpawnCasketsWithHostiles(parms.room, parms.points, parms.triggerSignal, parms.map); - SignalAction_OpenCasket signalAction_OpenCasket = (SignalAction_OpenCasket)ThingMaker.MakeThing(ThingDefOf.SignalAction_OpenCasket); - signalAction_OpenCasket.signalTag = parms.triggerSignal; - signalAction_OpenCasket.caskets.AddRange(list); - signalAction_OpenCasket.completedSignalTag = "CompletedOpenAction" + Find.UniqueIDsManager.GetNextSignalTagID(); - if (parms.delayTicks.HasValue) - { - signalAction_OpenCasket.delayTicks = parms.delayTicks.Value; - SignalAction_Message obj = (SignalAction_Message)ThingMaker.MakeThing(ThingDefOf.SignalAction_Message); - obj.signalTag = parms.triggerSignal; - obj.lookTargets = list; - obj.messageType = MessageTypeDefOf.ThreatBig; - obj.message = "MessageSleepingThreatDelayActivated".Translate(Faction.OfAncientsHostile, signalAction_OpenCasket.delayTicks.ToStringTicksToPeriod()); - GenSpawn.Spawn(obj, parms.room.rects[0].CenterCell, parms.map); - } - GenSpawn.Spawn(signalAction_OpenCasket, parms.map.Center, parms.map); - for (int i = 0; i < list.Count; i++) - { - if (!(list[i] is Building_Casket building_Casket)) - { - continue; - } - foreach (Thing item in (IEnumerable)building_Casket.GetDirectlyHeldThings()) - { - if (item is Pawn pawn) - { - threatPointsUsed += pawn.kindDef.combatPower; - } - } - } - SignalAction_Message obj2 = (SignalAction_Message)ThingMaker.MakeThing(ThingDefOf.SignalAction_Message); - obj2.signalTag = signalAction_OpenCasket.completedSignalTag; - obj2.lookTargets = list; - obj2.messageType = MessageTypeDefOf.ThreatBig; - obj2.message = "MessageSleepingPawnsWokenUp".Translate(Faction.OfAncientsHostile.def.pawnsPlural.CapitalizeFirst()); - GenSpawn.Spawn(obj2, parms.room.rects[0].CenterCell, parms.map); - } - - private List SpawnCasketsWithHostiles(LayoutRoom room, float threatPoints, string openSignal, Map map) - { - int num = Mathf.FloorToInt(threatPoints / PawnKindDefOf.AncientSoldier.combatPower); - List list = new List(); - for (int i = 0; i < num; i++) - { - if (!ComplexUtility.TryFindRandomSpawnCell(ThingDefOf.AncientCryptosleepPod, room, map, out var spawnPosition)) - { - break; - } - Building_AncientCryptosleepPod building_AncientCryptosleepPod = (Building_AncientCryptosleepPod)GenSpawn.Spawn(ThingDefOf.AncientCryptosleepPod, spawnPosition, map); - building_AncientCryptosleepPod.groupID = Find.UniqueIDsManager.GetNextAncientCryptosleepCasketGroupID(); - building_AncientCryptosleepPod.openedSignal = openSignal; - ThingSetMakerParams parms = default(ThingSetMakerParams); - parms.podContentsType = PodContentsType.AncientHostile; - List list2 = ThingSetMakerDefOf.MapGen_AncientPodContents.root.Generate(parms); - for (int j = 0; j < list2.Count; j++) - { - Pawn pawn = list2[j] as Pawn; - if (!building_AncientCryptosleepPod.TryAcceptThing(list2[j], allowSpecialEffects: false)) - { - if (pawn != null) - { - Find.WorldPawns.PassToWorld(pawn, PawnDiscardDecideMode.Discard); - } - else - { - list2[i].Destroy(); - } - } - } - list.Add(building_AncientCryptosleepPod); - } - return list; - } -} -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\Core\Defs\ThingDefs_Buildings\Buildings_Ancient_Active.xml` -**相似度:** 0.6040 - -```xml - - AncientCryptosleepPod - - Building_AncientCryptosleepPod - true - A single-use pod for preserving one person in a state of suspended animation. Unlike cryptosleep caskets, cryptosleep pods can only be used once. - - Things/Building/Ruins/AncientCryptosleepPod - Graphic_Multi - - - false - false - - - false - - 2000 - 200 - - - - - -``` \ No newline at end of file diff --git a/MCP/vector_cache/HediffDef-Luciferium.txt b/MCP/vector_cache/HediffDef-Luciferium.txt deleted file mode 100644 index b421e522..00000000 --- a/MCP/vector_cache/HediffDef-Luciferium.txt +++ /dev/null @@ -1,118 +0,0 @@ -根据向量相似度分析,与 'HediffDef, Luciferium' 最相关的代码定义如下: - ---- -**文件路径 (精确匹配):** `C:\Steam\steamapps\common\RimWorld\Data\Core\Defs\Drugs\Luciferium.xml` - -```xml - Luciferium - - A concoction of mechanites that dramatically improve the body's functioning in all respects. Over time, it can even heal old scarred-over wounds or brain damage, though it cannot regenerate lost limbs. Unfortunately, without the moderating effects of regular doses every five or six days, the mechanites lose cohesion, causing continuous berserk rages and, eventually, death.\n\nAfter the first dose, there is no way to get the mechanites out, ever.\n\nOn the urbworlds, they call Luciferium the 'Devil's Bargain'. Many have been forced to kill friends when no more of the seductive red pills could be found. - - LuciferiumHigh - LuciferiumAddiction - - - Things/Item/Drug/Luciferium - Graphic_StackCount - - false - - 70 - 0.01 - - Ultra - 10 - - Medical - -
  • - LuciferiumHigh - 1.00 - true -
  • -
    -
    - -
  • - Luciferium - 1.00 - 0.9 - 1010 -
  • -
    - -
  • ExoticMisc
  • -
    -
  • RewardStandardCore
  • - 50 -
    - - - LuciferiumHigh -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\Anomaly\Defs\Misc\Mutants.xml` -**相似度:** 0.5154 - -```xml - - -
  • AllWork
  • -
  • Shooting
  • -
    - true - false - false - - true - true - true - true - true - true - true - true - true - true - true - true - false - true - true - true - true - true - true - false - false - -
  • CryptosleepSickness
  • -
  • LuciferiumHigh
  • -
  • LuciferiumAddiction
  • -
  • Scaria
  • -
  • CorpseTorment
  • -
  • CubeInterest
  • -
  • CubeWithdrawal
  • -
  • CubeComa
  • -
  • CubeRage
  • -
  • HeartAttack
  • -
  • Scaria
  • -
  • PsychicAmplifier
  • -
  • MechlinkImplant
  • -
  • PregnantHuman
  • -
  • PregnancyLabor
  • -
  • HemogenAmplified
  • -
  • DeathrestExhaustion
  • -
  • InterruptedDeathrest
  • -
  • HemogenCraving
  • -
  • Deathrest
  • -
  • RegenerationComa
  • -
  • PostpartumExhaustion
  • -
  • Inhumanized
  • -
    - -
  • Hemogenic
  • -
  • Deathrest
  • -
    -
    -``` \ No newline at end of file diff --git a/MCP/vector_cache/HediffDef-Malnutrition.txt b/MCP/vector_cache/HediffDef-Malnutrition.txt deleted file mode 100644 index b318bf38..00000000 --- a/MCP/vector_cache/HediffDef-Malnutrition.txt +++ /dev/null @@ -1,750 +0,0 @@ -根据向量相似度分析,与 'HediffDef, Malnutrition' 最相关的代码定义如下: - ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\Core\Defs\HediffDefs\Hediffs_Global_Needs.xml` -**相似度:** 0.8237 - -```xml - - Malnutrition - - Abnormally low body fat and weight, typically caused by lack of food. Malnutrition is always very unpleasant, but its initial effects are mild. Without food, though, a malnourished creature will waste away, losing muscle mass and capacities. Malnutrition ends with death. Upon re-feeding malnutrition naturally recovers over time. Malnourished creatures have larger appetites than normal. - 1 - true - -
  • - - 1.5 - 0.5 - -
  • - Consciousness - -0.05 -
  • - - -
  • - 0.2 - - 2 - 0.6 - -
  • - Consciousness - -0.10 -
  • - - -
  • - 0.4 - - 2.5 - 0.6 - -
  • - Consciousness - -0.20 -
  • - - -
  • - 0.6 - - 3 - 0.6 - -
  • - Consciousness - -0.30 -
  • - - -
  • - 0.8 - - true - 0.6 - -
  • - Consciousness - 0.1 -
  • - - -
    -
    -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\StatPart_Malnutrition.txt` -**相似度:** 0.7310 - -```csharp -public class StatPart_Malnutrition : StatPart -{ - private SimpleCurve curve; - - public override void TransformValue(StatRequest req, ref float val) - { - if (TryGetMalnutritionFactor(req, out var _, out var factor)) - { - val *= factor; - } - } - - public override string ExplanationPart(StatRequest req) - { - if (TryGetMalnutritionFactor(req, out var malnutritionSeverity, out var factor)) - { - return "StatsReport_Malnutrition".Translate(malnutritionSeverity.ToStringPercent()) + ": x" + factor.ToStringPercent(); - } - return null; - } - - private bool TryGetMalnutritionFactor(StatRequest req, out float malnutritionSeverity, out float factor) - { - factor = 0f; - malnutritionSeverity = 0f; - if (!req.HasThing || !(req.Thing is Pawn pawn)) - { - return false; - } - Hediff firstHediffOfDef = pawn.health.hediffSet.GetFirstHediffOfDef(HediffDefOf.Malnutrition); - if (firstHediffOfDef == null) - { - return false; - } - malnutritionSeverity = firstHediffOfDef.Severity; - factor = curve.Evaluate(malnutritionSeverity); - return true; - } -} -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\Need_Food.txt` -**相似度:** 0.6580 - -```csharp -public class Need_Food : Need -{ - public int lastNonStarvingTick = -99999; - - public const float BaseFoodFallPerTick = 2.6666667E-05f; - - private const float BaseMalnutritionSeverityPerDay = 0.453f; - - private const float BaseMalnutritionSeverityPerInterval = 0.0011325f; - - private CompHoldingPlatformTarget platformComp; - - public bool Starving => CurCategory == HungerCategory.Starving; - - public float PercentageThreshUrgentlyHungry => pawn.RaceProps.FoodLevelPercentageWantEat * 0.4f; - - public float PercentageThreshHungry => pawn.RaceProps.FoodLevelPercentageWantEat * 0.8f; - - public float NutritionBetweenHungryAndFed => (1f - PercentageThreshHungry) * MaxLevel; - - private CompHoldingPlatformTarget PlatformTarget => platformComp ?? (platformComp = pawn.TryGetComp()); - - public HungerCategory CurCategory - { - get - { - if (base.CurLevelPercentage <= 0f) - { - return HungerCategory.Starving; - } - if (base.CurLevelPercentage < PercentageThreshUrgentlyHungry) - { - return HungerCategory.UrgentlyHungry; - } - if (base.CurLevelPercentage < PercentageThreshHungry) - { - return HungerCategory.Hungry; - } - return HungerCategory.Fed; - } - } - - public float FoodFallPerTick => FoodFallPerTickAssumingCategory(CurCategory); - - public int TicksUntilHungryWhenFed => Mathf.CeilToInt(NutritionBetweenHungryAndFed / FoodFallPerTickAssumingCategory(HungerCategory.Fed)); - - public int TicksUntilHungryWhenFedIgnoringMalnutrition => Mathf.CeilToInt(NutritionBetweenHungryAndFed / FoodFallPerTickAssumingCategory(HungerCategory.Fed, ignoreMalnutrition: true)); - - public override int GUIChangeArrow - { - get - { - if (GainingFood()) - { - return 1; - } - if (!(FoodFallPerTickAssumingCategory(HungerCategory.Hungry) > 0f)) - { - return 0; - } - return -1; - } - } - - public override float MaxLevel - { - get - { - if (Current.ProgramState != ProgramState.Playing) - { - return pawn.BodySize * pawn.ageTracker.CurLifeStage.foodMaxFactor; - } - return pawn.GetStatValue(StatDefOf.MaxNutrition, applyPostProcess: true, 15); - } - } - - public float NutritionWanted => MaxLevel - CurLevel; - - public int TicksStarving => Mathf.Max(0, Find.TickManager.TicksGame - lastNonStarvingTick); - - private float MalnutritionSeverityPerInterval => 0.0011325f * Mathf.Lerp(0.8f, 1.2f, Rand.ValueSeeded(pawn.thingIDNumber ^ 0x26EF7A)); - - protected override bool IsFrozen - { - get - { - if (!base.IsFrozen && !pawn.Deathresting) - { - return PlatformTarget?.CurrentlyHeldOnPlatform ?? false; - } - return true; - } - } - - public Need_Food(Pawn pawn) - : base(pawn) - { - } - - public bool GainingFood() - { - if (pawn.jobs?.curDriver is IEatingDriver { GainingNutritionNow: not false }) - { - return true; - } - if (ModsConfig.BiotechActive && ChildcareUtility.CanSuckle(pawn, out var _) && pawn.CarriedBy?.jobs.curDriver is JobDriver_FeedBaby { Feeding: not false }) - { - return true; - } - return false; - } - - public float FoodFallPerTickAssumingCategory(HungerCategory hunger, bool ignoreMalnutrition = false) - { - Building_Bed building_Bed = pawn.CurrentBed(); - float num = BaseHungerRate(pawn.ageTracker.CurLifeStage, pawn.def) * hunger.HungerMultiplier() * pawn.health.hediffSet.GetHungerRateFactor(ignoreMalnutrition ? HediffDefOf.Malnutrition : null) * (pawn.story?.traits?.HungerRateFactor ?? 1f) * (building_Bed?.GetStatValue(StatDefOf.BedHungerRateFactor) ?? 1f); - if (ModsConfig.BiotechActive) - { - Hediff firstHediffOfDef = pawn.health.hediffSet.GetFirstHediffOfDef(HediffDefOf.Lactating); - if (firstHediffOfDef != null) - { - HediffComp_Lactating hediffComp_Lactating = firstHediffOfDef.TryGetComp(); - if (hediffComp_Lactating != null) - { - num += hediffComp_Lactating.AddedNutritionPerDay() / 60000f; - } - } - } - if (ModsConfig.BiotechActive && pawn.genes != null) - { - int num2 = 0; - foreach (Gene item in pawn.genes.GenesListForReading) - { - if (!item.Overridden) - { - num2 += item.def.biostatMet; - } - } - num *= GeneTuning.MetabolismToFoodConsumptionFactorCurve.Evaluate(num2); - } - if (ModsConfig.AnomalyActive) - { - CompHoldingPlatformTarget platformTarget = PlatformTarget; - if (platformTarget != null && platformTarget.CurrentlyHeldOnPlatform) - { - num = 0f; - } - } - return num; - } - - public override void NeedInterval() - { - if (!IsFrozen) - { - CurLevel -= FoodFallPerTick * 150f; - } - if (!Starving) - { - lastNonStarvingTick = Find.TickManager.TicksGame; - } - if (!IsFrozen || pawn.Deathresting) - { - if (Starving) - { - HealthUtility.AdjustSeverity(pawn, HediffDefOf.Malnutrition, MalnutritionSeverityPerInterval); - } - else - { - HealthUtility.AdjustSeverity(pawn, HediffDefOf.Malnutrition, 0f - MalnutritionSeverityPerInterval); - } - } - } - - public override void SetInitialLevel() - { - StatDefOf.MaxNutrition.Worker.ClearCacheForThing(pawn); - base.CurLevelPercentage = (pawn.RaceProps.Humanlike ? 0.8f : Rand.Range(0.5f, 0.9f)); - if (Current.ProgramState == ProgramState.Playing) - { - lastNonStarvingTick = Find.TickManager.TicksGame; - } - } - - public override void OnNeedRemoved() - { - if (pawn.health.hediffSet.TryGetHediff(HediffDefOf.Malnutrition, out var hediff)) - { - pawn.health.RemoveHediff(hediff); - } - } - - public override string GetTipString() - { - return (base.LabelCap + ": " + base.CurLevelPercentage.ToStringPercent()).Colorize(ColoredText.TipSectionTitleColor) + " (" + CurLevel.ToString("0.##") + " / " + MaxLevel.ToString("0.##") + ")\n" + def.description; - } - - public override void DrawOnGUI(Rect rect, int maxThresholdMarkers = int.MaxValue, float customMargin = -1f, bool drawArrows = true, bool doTooltip = true, Rect? rectForTooltip = null, bool drawLabel = true) - { - if (threshPercents == null) - { - threshPercents = new List(); - } - threshPercents.Clear(); - threshPercents.Add(PercentageThreshHungry); - threshPercents.Add(PercentageThreshUrgentlyHungry); - base.DrawOnGUI(rect, maxThresholdMarkers, customMargin, drawArrows, doTooltip, rectForTooltip, drawLabel); - } - - public static float BaseHungerRate(LifeStageDef lifeStage, ThingDef pawnDef) - { - return lifeStage.hungerRateFactor * pawnDef.race.baseHungerRate * 2.6666667E-05f; - } - - public override void ExposeData() - { - base.ExposeData(); - Scribe_Values.Look(ref lastNonStarvingTick, "lastNonStarvingTick", -99999); - } -} -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\HediffDefOf.txt` -**相似度:** 0.6514 - -```csharp -public static class HediffDefOf -{ - public static HediffDef Cut; - - public static HediffDef SurgicalCut; - - public static HediffDef ExecutionCut; - - public static HediffDef Bite; - - public static HediffDef MissingBodyPart; - - public static HediffDef Misc; - - [MayRequireBiotech] - public static HediffDef BloodfeederMark; - - [MayRequireAnomaly] - public static HediffDef Decayed; - - [MayRequireAnomaly] - public static HediffDef Digested; - - [MayRequireOdyssey] - public static HediffDef PorcupineQuill; - - public static HediffDef BloodLoss; - - public static HediffDef Hypothermia; - - public static HediffDef Heatstroke; - - public static HediffDef Malnutrition; - - public static HediffDef ToxicBuildup; - - public static HediffDef PsychicShock; - - public static HediffDef ResurrectionSickness; - - public static HediffDef ResurrectionPsychosis; - - [MayRequireBiotech] - public static HediffDef PollutionStimulus; - - [MayRequireBiotech] - public static HediffDef ToxGasExposure; - - [MayRequireAnomaly] - public static HediffDef Shambler; - - [MayRequireAnomaly] - public static HediffDef ShamblerCorpse; - - [MayRequireAnomaly] - public static HediffDef Rising; - - [MayRequireAnomaly] - public static HediffDef DeathRefusal; - - [MayRequireAnomaly] - public static HediffDef DeathRefusalSickness; - - [MayRequireAnomaly] - public static HediffDef MetalhorrorImplant; - - [MayRequireAnomaly] - public static HediffDef MetalhorrorSpeedBoost; - - [MayRequireAnomaly] - public static HediffDef PsychicTrance; - - [MayRequireAnomaly] - public static HediffDef DuplicateSickness; - - [MayRequireAnomaly] - public static HediffDef VoidTouched; - - [MayRequireAnomaly] - public static HediffDef MeatHunger; - - [MayRequireAnomaly] - public static HediffDef ShardHolder; - - [MayRequireAnomaly] - public static HediffDef Inhumanized; - - [MayRequireAnomaly] - public static HediffDef DarknessExposure; - - [MayRequireAnomaly] - public static HediffDef LightExposure; - - [MayRequireAnomaly] - public static HediffDef DisruptorFlash; - - [MayRequireOdyssey] - public static HediffDef VacuumExposure; - - [MayRequireOdyssey] - public static HediffDef PsilocapHigh; - - [MayRequireOdyssey] - public static HediffDef GravNausea; - - [MayRequireOdyssey] - public static HediffDef VolcanicAsh; - - public static HediffDef Anesthetic; - - public static HediffDef CryptosleepSickness; - - public static HediffDef FoodPoisoning; - - public static HediffDef Pregnant; - - [MayRequireBiotech] - public static HediffDef PregnantHuman; - - [MayRequireBiotech] - public static HediffDef MorningSickness; - - [MayRequireBiotech] - public static HediffDef PregnancyMood; - - [MayRequireBiotech] - public static HediffDef PregnancyLabor; - - [MayRequireBiotech] - public static HediffDef PregnancyLaborPushing; - - [MayRequireBiotech] - public static HediffDef OvumExtracted; - - [MayRequireBiotech] - public static HediffDef VatLearning; - - [MayRequireBiotech] - public static HediffDef VatGrowing; - - public static HediffDef CatatonicBreakdown; - - public static HediffDef Scaria; - - [MayRequireIdeology] - public static HediffDef Scarification; - - [MayRequireIdeology] - public static HediffDef NeuralSupercharge; - - [MayRequireIdeology] - public static HediffDef BiosculptingSickness; - - [MayRequireRoyalty] - public static HediffDef PsychicEntropy; - - [MayRequireRoyalty] - public static HediffDef PsychicHangover; - - [MayRequireRoyalty] - public static HediffDef PsychicSuppression; - - [MayRequireRoyalty] - public static HediffDef Abasia; - - [MayRequireRoyalty] - public static HediffDef PsychicLove; - - public static HediffDef Sterilized; - - [MayRequireBiotech] - public static HediffDef Vasectomy; - - [MayRequireBiotech] - public static HediffDef ImplantedIUD; - - [MayRequireIdeology] - public static HediffDef WorkFocus; - - [MayRequireBiotech] - public static HediffDef ScanningSickness; - - [MayRequireBiotech] - public static HediffDef PsychicBond; - - [MayRequireBiotech] - public static HediffDef PsychicBondTorn; - - public static HediffDef LungRot; - - public static HediffDef LungRotExposure; - - public static HediffDef CoveredInFirefoam; - - [MayRequireAnomaly] - public static HediffDef BioferriteExtracted; - - public static HediffDef Plague; - - public static HediffDef WoundInfection; - - public static HediffDef ScariaInfection; - - public static HediffDef AlcoholHigh; - - public static HediffDef Hangover; - - public static HediffDef DrugOverdose; - - public static HediffDef WakeUpTolerance; - - public static HediffDef GoJuiceTolerance; - - public static HediffDef Blindness; - - public static HediffDef Carcinoma; - - public static HediffDef Dementia; - - public static HediffDef OrganDecay; - - [MayRequireBiotech] - public static HediffDef DetoxifierLung; - - [MayRequireRoyalty] - public static HediffDef LoveEnhancer; - - [MayRequireRoyalty] - public static HediffDef PsychicAmplifier; - - [MayRequireRoyalty] - public static HediffDef PsychicHarmonizer; - - [MayRequireBiotech] - public static HediffDef MechlinkImplant; - - [MayRequireBiotech] - public static HediffDef SelfShutdown; - - [MayRequireBiotech] - public static HediffDef InterruptedDeathrest; - - [MayRequireBiotech] - public static HediffDef InfantIllness; - - [MayRequireBiotech] - public static HediffDef Stillborn; - - [MayRequireBiotech] - public static HediffDef PostpartumExhaustion; - - [MayRequireBiotech] - public static HediffDef Lactating; - - [MayRequireBiotech] - public static HediffDef RegenerationComa; - - [MayRequireBiotech] - public static HediffDef XenogermLossShock; - - [MayRequireBiotech] - public static HediffDef XenogermReplicating; - - [MayRequireBiotech] - public static HediffDef GeneticDrugNeed; - - [MayRequireBiotech] - public static HediffDef BioStarvation; - - [MayRequireBiotech] - public static HediffDef XenogerminationComa; - - [MayRequireBiotech] - public static HediffDef Deathrest; - - [MayRequireBiotech] - public static HediffDef DeathrestExhaustion; - - [MayRequireBiotech] - public static HediffDef BandNode; - - [MayRequireBiotech] - public static HediffDef HemogenCraving; - - [MayRequireAnomaly] - public static HediffDef HoraxianInvisibility; - - [MayRequireAnomaly] - public static HediffDef RevenantHypnosis; - - [MayRequireAnomaly] - public static HediffDef AwokenHypnosis; - - [MayRequireAnomaly] - public static HediffDef DarkPsychicShock; - - [MayRequireAnomaly] - public static HediffDef Tentacle; - - [MayRequireAnomaly] - public static HediffDef FleshWhip; - - [MayRequireAnomaly] - public static HediffDef OrganDecayUndiagnosedDuplicaton; - - [MayRequireAnomaly] - public static HediffDef CrumblingMindUndiagnosedDuplication; - - [MayRequireAnomaly] - public static HediffDef OrganDecayCreepjoiner; - - [MayRequireAnomaly] - public static HediffDef CrumblingMind; - - [MayRequireAnomaly] - public static HediffDef CrumbledMind; - - [MayRequireAnomaly] - public static HediffDef BlissLobotomy; - - [MayRequireAnomaly] - public static HediffDef PleasurePulse; - - [MayRequireAnomaly] - public static HediffDef NeurosisPulse; - - [MayRequireAnomaly] - public static HediffDef BloodRage; - - [MayRequireAnomaly] - public static HediffDef FrenzyField; - - [MayRequireAnomaly] - public static HediffDef AgonyPulse; - - [MayRequireAnomaly] - public static HediffDef CubeInterest; - - [MayRequireAnomaly] - public static HediffDef CubeWithdrawal; - - [MayRequireAnomaly] - public static HediffDef CubeRage; - - [MayRequireAnomaly] - public static HediffDef CubeComa; - - [MayRequireAnomaly] - public static HediffDef BrainwipeComa; - - [MayRequireAnomaly] - public static HediffDef CorpseTorment; - - [MayRequireAnomaly] - public static HediffDef PsychicallyDead; - - [MayRequireAnomaly] - public static HediffDef Psychophage; - - [MayRequireAnomaly] - public static HediffDef SleepSuppression; - - [MayRequireAnomaly] - public static HediffDef RageSpeed; - - [MayRequireAnomaly] - public static HediffDef AwokenCorpse; - - [MayRequireAnomaly] - public static HediffDef RapidRegeneration; - - [MayRequireAnomaly] - public static HediffDef GhoulBarbs; - - [MayRequireAnomaly] - public static HediffDef GhoulPlating; - - [MayRequireAnomaly] - public static HediffDef AdrenalHeart; - - [MayRequireAnomaly] - public static HediffDef FleshmassStomach; - - [MayRequireAnomaly] - public static HediffDef FleshmassLung; - - [MayRequireAnomaly] - public static HediffDef Metalblood; - - [MayRequireOdyssey] - public static HediffDef SentienceCatalyst; - - static HediffDefOf() - { - DefOfHelper.EnsureInitializedInCtor(typeof(HediffDefOf)); - } -} -``` \ No newline at end of file diff --git a/MCP/vector_cache/Human-ThingDef.txt b/MCP/vector_cache/Human-ThingDef.txt deleted file mode 100644 index ac72ecd3..00000000 --- a/MCP/vector_cache/Human-ThingDef.txt +++ /dev/null @@ -1,2691 +0,0 @@ -根据向量相似度分析,与 'Human, ThingDef' 最相关的代码定义如下: - ---- -**文件路径 (精确匹配):** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\Verse\ThingDef.txt` - -```csharp -public class ThingDef : BuildableDef -{ - public Type thingClass; - - public ThingCategory category; - - public TickerType tickerType; - - public int stackLimit = 1; - - public IntVec2 size = IntVec2.One; - - public bool destroyable = true; - - public bool rotatable = true; - - public bool smallVolume; - - public bool useHitPoints = true; - - public bool receivesSignals; - - public List comps = new List(); - - public List virtualDefs = new List(); - - public ThingDef virtualDefParent; - - [NoTranslate] - public string devNote; - - public List killedLeavingsRanges; - - public List killedLeavings; - - public List killedLeavingsPlayerHostile; - - public float killedLeavingsChance = 1f; - - public bool forceLeavingsAllowed; - - public List butcherProducts; - - public List smeltProducts; - - public bool smeltable; - - public bool burnableByRecipe; - - public bool randomizeRotationOnSpawn; - - public List damageMultipliers; - - public bool isTechHediff; - - public RecipeMakerProperties recipeMaker; - - public ThingDef minifiedDef; - - public bool isUnfinishedThing; - - public bool leaveResourcesWhenKilled; - - public ThingDef slagDef; - - public bool isFrameInt; - - public List multipleInteractionCellOffsets; - - public IntVec3 interactionCellOffset = IntVec3.Zero; - - public bool hasInteractionCell; - - public ThingDef interactionCellIcon; - - public bool interactionCellIconReverse; - - public ThingDef filthLeaving; - - public bool forceDebugSpawnable; - - public bool intricate; - - public bool scatterableOnMapGen = true; - - public float deepCommonality; - - public int deepCountPerCell = 300; - - public int deepCountPerPortion = -1; - - public IntRange deepLumpSizeRange = IntRange.Zero; - - public float generateCommonality = 1f; - - public float generateAllowChance = 1f; - - private bool canOverlapZones = true; - - public FloatRange startingHpRange = FloatRange.One; - - [NoTranslate] - public List thingSetMakerTags; - - public bool alwaysFlee; - - public List recipes; - - public bool messageOnDeteriorateInStorage = true; - - public bool deteriorateFromEnvironmentalEffects = true; - - public bool canDeteriorateUnspawned; - - public bool canLoadIntoCaravan = true; - - public bool isMechClusterThreat; - - public FloatRange displayNumbersBetweenSameDefDistRange = FloatRange.Zero; - - public int minRewardCount = 1; - - public bool preventSkyfallersLandingOn; - - public FactionDef requiresFactionToAcquire; - - public float relicChance; - - public OrderedTakeGroupDef orderedTakeGroup; - - public int allowedArchonexusCount; - - public int possessionCount; - - public bool notifyMapRemoved; - - public bool canScatterOver = true; - - public bool genericMarketSellable = true; - - public bool drawHighlight; - - public Color? highlightColor; - - public bool drawHighlightOnlyForHostile; - - public bool autoTargetNearbyIdenticalThings; - - public bool preventDroppingThingsOn; - - public bool hiddenWhileUndiscovered; - - public bool disableImpassableShotOverConfigError; - - public bool showInSearch = true; - - public bool bringAlongOnGravship = true; - - public ThingDef dropPodFaller; - - public bool preventSpawningInResourcePod; - - public bool pathfinderDangerous; - - public bool noRightClickDraftAttack; - - public int gravshipSpawnPriority = 1; - - public List replaceTags; - - public GraphicData graphicData; - - public DrawerType drawerType = DrawerType.RealtimeOnly; - - public bool drawOffscreen; - - public ColorGenerator colorGenerator; - - public float hideAtSnowOrSandDepth = 99999f; - - public bool drawDamagedOverlay = true; - - public bool castEdgeShadows; - - public float staticSunShadowHeight; - - public bool useSameGraphicForGhost; - - public bool useBlueprintGraphicAsGhost; - - public List randomStyle; - - public float randomStyleChance; - - public bool canEditAnyStyle; - - public bool dontPrint; - - public ThingDef defaultStuff; - - public int killedLeavingsExpandRect; - - public bool minifiedManualDraw; - - public float minifiedDrawScale = 1f; - - public Rot4 overrideMinifiedRot = Rot4.Invalid; - - public Vector3 minifiedDrawOffset = Vector3.zero; - - public float deselectedSelectionBracketFactor = 1f; - - public bool selectable; - - public bool containedPawnsSelectable; - - public bool containedItemsSelectable; - - public bool neverMultiSelect; - - public bool isAutoAttackableMapObject; - - public bool hasTooltip; - - public List inspectorTabs; - - [Unsaved(false)] - public List inspectorTabsResolved; - - public bool seeThroughFog; - - public bool drawGUIOverlay; - - public bool drawGUIOverlayQuality = true; - - public ResourceCountPriority resourceReadoutPriority; - - public bool resourceReadoutAlwaysShow; - - public bool drawPlaceWorkersWhileSelected; - - public bool drawPlaceWorkersWhileInstallBlueprintSelected; - - public ConceptDef storedConceptLearnOpportunity; - - public float uiIconScale = 1f; - - public bool hasCustomRectForSelector; - - public bool hideStats; - - public bool hideInspect; - - public bool onlyShowInspectString; - - public bool hideMainDesc; - - public bool alwaysHaulable; - - public bool designateHaulable; - - public List thingCategories; - - public bool mineable; - - public bool socialPropernessMatters; - - public bool stealable = true; - - public SoundDef soundSpawned; - - public SoundDef soundDrop; - - public SoundDef soundPickup; - - public SoundDef soundInteract; - - public SoundDef soundImpactDefault; - - public SoundDef soundPlayInstrument; - - public SoundDef soundOpen; - - public bool saveCompressible; - - public bool isSaveable = true; - - public bool holdsRoof; - - public float fillPercent; - - public bool coversFloor; - - public bool neverOverlapFloors; - - public SurfaceType surfaceType; - - public bool wipesPlants; - - public bool blockPlants; - - public bool blockLight; - - public bool blockWind; - - public bool blockWeather; - - public Tradeability tradeability = Tradeability.All; - - [NoTranslate] - public List tradeTags; - - public bool tradeNeverStack; - - public bool tradeNeverGenerateStacked; - - public bool healthAffectsPrice = true; - - public ColorGenerator colorGeneratorInTraderStock; - - private List verbs; - - public List tools; - - public float equippedAngleOffset; - - public float equippedDistanceOffset; - - public EquipmentType equipmentType; - - public TechLevel techLevel; - - public List weaponClasses; - - [NoTranslate] - public List weaponTags; - - [NoTranslate] - public List techHediffsTags; - - public bool violentTechHediff; - - public bool destroyOnDrop; - - public List equippedStatOffsets; - - public SoundDef meleeHitSound; - - public float recoilPower = 1f; - - public float recoilRelaxation = 10f; - - public bool rotateInShelves = true; - - public bool mergeVerbGizmos = true; - - public BuildableDef entityDefToBuild; - - public ThingDef projectileWhenLoaded; - - public RulePackDef ideoBuildingNamerBase; - - public EntityCodexEntryDef entityCodexEntry; - - public IngestibleProperties ingestible; - - public FilthProperties filth; - - public GasProperties gas; - - public BuildingProperties building; - - public RaceProperties race; - - public ApparelProperties apparel; - - public MoteProperties mote; - - public PlantProperties plant; - - public ProjectileProperties projectile; - - public StuffProperties stuffProps; - - public SkyfallerProperties skyfaller; - - public PawnFlyerProperties pawnFlyer; - - public RitualFocusProperties ritualFocus; - - public IngredientProperties ingredient; - - public MapPortalProperties portal; - - public bool canBeUsedUnderRoof = true; - - [Unsaved(false)] - private string descriptionDetailedCached; - - [Unsaved(false)] - public Graphic interactionCellGraphic; - - [Unsaved(false)] - private bool? isNaturalOrganCached; - - [Unsaved(false)] - private bool? hasSunShadowsCached; - - [Unsaved(false)] - private List cachedRelevantStyleCategories; - - public const int SmallUnitPerVolume = 10; - - public const float SmallVolumePerUnit = 0.1f; - - public const float ArchonexusMaxItemStackMass = 5f; - - public const int ArchonexusMaxItemStackCount = 25; - - public const float ArchonexusMaxItemStackValue = 2000f; - - public const int ArchonexusAutoCalculateValue = -1; - - private List allRecipesCached; - - private static List EmptyVerbPropertiesList = new List(); - - private Dictionary concreteExamplesInt; - - public bool EverHaulable - { - get - { - if (!alwaysHaulable) - { - return designateHaulable; - } - return true; - } - } - - public bool EverPollutable => !building.isNaturalRock; - - public float VolumePerUnit - { - get - { - if (smallVolume) - { - return 0.1f; - } - return 1f; - } - } - - public override IntVec2 Size => size; - - public bool DiscardOnDestroyed => race == null; - - public int BaseMaxHitPoints => Mathf.RoundToInt(this.GetStatValueAbstract(StatDefOf.MaxHitPoints)); - - public float BaseFlammability => this.GetStatValueAbstract(StatDefOf.Flammability); - - public float BaseMarketValue - { - get - { - return this.GetStatValueAbstract(StatDefOf.MarketValue); - } - set - { - this.SetStatBaseValue(StatDefOf.MarketValue, value); - } - } - - public float BaseMass => this.GetStatValueAbstract(StatDefOf.Mass); - - public int ArchonexusMaxAllowedCount - { - get - { - if (allowedArchonexusCount == -1) - { - return Mathf.Min(stackLimit, 25, (BaseMass > 0f) ? ((int)(5f / BaseMass)) : 0, (BaseMarketValue > 0f) ? ((int)(2000f / BaseMarketValue)) : 0); - } - return allowedArchonexusCount; - } - } - - public bool PlayerAcquirable - { - get - { - if (destroyOnDrop) - { - return false; - } - if (this == ThingDefOf.ReinforcedBarrel && Find.Storyteller != null && Find.Storyteller.difficulty.classicMortars) - { - return false; - } - if (requiresFactionToAcquire != null && Find.World != null && Find.World.factionManager != null) - { - return Find.FactionManager.FirstFactionOfDef(requiresFactionToAcquire) != null; - } - return true; - } - } - - public bool EverTransmitsPower - { - get - { - for (int i = 0; i < comps.Count; i++) - { - if (comps[i] is CompProperties_Power { transmitsPower: not false }) - { - return true; - } - } - return false; - } - } - - public bool Minifiable => minifiedDef != null; - - public bool HasThingIDNumber => category != ThingCategory.Mote; - - public List AllRecipes - { - get - { - if (allRecipesCached == null) - { - allRecipesCached = new List(); - if (recipes != null) - { - for (int i = 0; i < recipes.Count; i++) - { - allRecipesCached.Add(recipes[i]); - } - } - List allDefsListForReading = DefDatabase.AllDefsListForReading; - for (int j = 0; j < allDefsListForReading.Count; j++) - { - if (allDefsListForReading[j].recipeUsers != null && allDefsListForReading[j].recipeUsers.Contains(this)) - { - allRecipesCached.Add(allDefsListForReading[j]); - } - } - } - return allRecipesCached; - } - } - - public bool ConnectToPower - { - get - { - if (EverTransmitsPower) - { - return false; - } - for (int i = 0; i < comps.Count; i++) - { - if (comps[i].compClass == typeof(CompPowerBattery)) - { - return true; - } - if (comps[i].compClass == typeof(CompPowerTrader)) - { - return true; - } - } - return false; - } - } - - public bool CoexistsWithFloors - { - get - { - if (!neverOverlapFloors) - { - return !coversFloor; - } - return false; - } - } - - public FillCategory Fillage - { - get - { - if (fillPercent < 0.01f) - { - return FillCategory.None; - } - if (fillPercent > 0.99f) - { - return FillCategory.Full; - } - return FillCategory.Partial; - } - } - - public bool MakeFog => Fillage == FillCategory.Full; - - public bool CanOverlapZones - { - get - { - if (building != null && building.SupportsPlants) - { - return false; - } - if (passability == Traversability.Impassable && category != ThingCategory.Plant && !HasComp(typeof(CompTransporter))) - { - return false; - } - if ((int)surfaceType >= 1) - { - return false; - } - if (typeof(ISlotGroupParent).IsAssignableFrom(thingClass)) - { - return false; - } - if (!canOverlapZones) - { - return false; - } - if ((IsBlueprint || IsFrame) && entityDefToBuild is ThingDef thingDef) - { - return thingDef.CanOverlapZones; - } - return true; - } - } - - public bool CountAsResource => resourceReadoutPriority != ResourceCountPriority.Uncounted; - - public List Verbs - { - get - { - if (verbs != null) - { - return verbs; - } - return EmptyVerbPropertiesList; - } - } - - public bool CanHaveFaction - { - get - { - if (IsBlueprint || IsFrame) - { - return true; - } - return category switch - { - ThingCategory.Pawn => true, - ThingCategory.Building => true, - _ => false, - }; - } - } - - public bool Claimable - { - get - { - if (building != null && building.claimable) - { - return !building.isNaturalRock; - } - return false; - } - } - - public ThingCategoryDef FirstThingCategory - { - get - { - if (thingCategories.NullOrEmpty()) - { - return null; - } - return thingCategories[0]; - } - } - - public float MedicineTendXpGainFactor => Mathf.Clamp(this.GetStatValueAbstract(StatDefOf.MedicalPotency) * 0.7f, 0.5f, 1f); - - public bool CanEverDeteriorate - { - get - { - if (!useHitPoints) - { - return false; - } - if (category != ThingCategory.Item) - { - if (plant != null) - { - return plant.canDeteriorate; - } - return false; - } - return true; - } - } - - public bool CanInteractThroughCorners - { - get - { - if (category != ThingCategory.Building) - { - return false; - } - if (!holdsRoof) - { - return false; - } - if (building != null && building.isNaturalRock && !IsSmoothed) - { - return false; - } - return true; - } - } - - public bool AffectsRegions - { - get - { - if (passability != Traversability.Impassable && !IsDoor) - { - return IsFence; - } - return true; - } - } - - public bool AffectsReachability - { - get - { - if (AffectsRegions) - { - return true; - } - if (passability == Traversability.Impassable || IsDoor) - { - return true; - } - if (TouchPathEndModeUtility.MakesOccupiedCellsAlwaysReachableDiagonally(this)) - { - return true; - } - return false; - } - } - - public string DescriptionDetailed - { - get - { - if (descriptionDetailedCached == null) - { - StringBuilder stringBuilder = new StringBuilder(); - stringBuilder.Append(description); - if (IsApparel) - { - stringBuilder.AppendLine(); - stringBuilder.AppendLine(); - stringBuilder.AppendLine(string.Format("{0}: {1}", "Layer".Translate(), apparel.GetLayersString())); - stringBuilder.Append(string.Format("{0}: {1}", "Covers".Translate(), apparel.GetCoveredOuterPartsString(BodyDefOf.Human))); - if (equippedStatOffsets != null && equippedStatOffsets.Count > 0) - { - stringBuilder.AppendLine(); - stringBuilder.AppendLine(); - for (int i = 0; i < equippedStatOffsets.Count; i++) - { - if (i > 0) - { - stringBuilder.AppendLine(); - } - StatModifier statModifier = equippedStatOffsets[i]; - stringBuilder.Append($"{statModifier.stat.LabelCap}: {statModifier.ValueToStringAsOffset}"); - } - } - } - descriptionDetailedCached = stringBuilder.ToString(); - } - return descriptionDetailedCached; - } - } - - public bool CanBenefitFromCover - { - get - { - if (category == ThingCategory.Pawn) - { - return true; - } - if (building != null && building.IsTurret) - { - return true; - } - return false; - } - } - - public bool PotentiallySmeltable - { - get - { - if (!smeltable) - { - return false; - } - if (base.MadeFromStuff) - { - foreach (ThingDef item in GenStuff.AllowedStuffsFor(this)) - { - if (item.smeltable) - { - return true; - } - } - return false; - } - return true; - } - } - - public bool HasSingleOrMultipleInteractionCells - { - get - { - if (!hasInteractionCell) - { - return !multipleInteractionCellOffsets.NullOrEmpty(); - } - return true; - } - } - - public bool IsApparel => apparel != null; - - public bool IsBed => typeof(Building_Bed).IsAssignableFrom(thingClass); - - public bool IsWall - { - get - { - if (building != null) - { - return building.isWall; - } - return false; - } - } - - public bool IsCorpse => typeof(Corpse).IsAssignableFrom(thingClass); - - public bool IsFrame => isFrameInt; - - public bool IsBlueprint - { - get - { - if (entityDefToBuild != null) - { - return category == ThingCategory.Ethereal; - } - return false; - } - } - - public bool IsStuff => stuffProps != null; - - public bool IsMedicine => statBases.StatListContains(StatDefOf.MedicalPotency); - - public bool IsDoor => typeof(Building_Door).IsAssignableFrom(thingClass); - - public bool IsFence - { - get - { - if (building != null) - { - return building.isFence; - } - return false; - } - } - - public bool IsFilth => filth != null; - - public bool IsIngestible => ingestible != null; - - public bool IsNutritionGivingIngestible - { - get - { - if (IsIngestible) - { - return ingestible.CachedNutrition > 0f; - } - return false; - } - } - - public bool IsNutritionGivingIngestibleForHumanlikeBabies - { - get - { - if (IsNutritionGivingIngestible && ingestible.HumanEdible) - { - return ingestible.babiesCanIngest; - } - return false; - } - } - - public bool IsWeapon - { - get - { - if (category == ThingCategory.Item && (!verbs.NullOrEmpty() || !tools.NullOrEmpty())) - { - return !IsApparel; - } - return false; - } - } - - public bool IsCommsConsole => typeof(Building_CommsConsole).IsAssignableFrom(thingClass); - - public bool IsOrbitalTradeBeacon => typeof(Building_OrbitalTradeBeacon).IsAssignableFrom(thingClass); - - public bool IsFoodDispenser => typeof(Building_NutrientPasteDispenser).IsAssignableFrom(thingClass); - - public bool IsDrug - { - get - { - if (ingestible != null) - { - return ingestible.drugCategory != DrugCategory.None; - } - return false; - } - } - - public bool IsPleasureDrug - { - get - { - if (IsDrug) - { - return ingestible.joy > 0f; - } - return false; - } - } - - public bool IsNonMedicalDrug - { - get - { - if (IsDrug) - { - return ingestible.drugCategory != DrugCategory.Medical; - } - return false; - } - } - - public bool IsTable - { - get - { - if (surfaceType == SurfaceType.Eat) - { - return HasComp(typeof(CompGatherSpot)); - } - return false; - } - } - - public bool IsWorkTable => typeof(Building_WorkTable).IsAssignableFrom(thingClass); - - public bool IsShell => projectileWhenLoaded != null; - - public bool IsArt => IsWithinCategory(ThingCategoryDefOf.BuildingsArt); - - public bool IsSmoothable => building?.smoothedThing != null; - - public bool IsSmoothed => building?.unsmoothedThing != null; - - public bool IsMetal - { - get - { - if (stuffProps != null) - { - return stuffProps.categories.Contains(StuffCategoryDefOf.Metallic); - } - return false; - } - } - - public bool IsCryptosleepCasket => typeof(Building_CryptosleepCasket).IsAssignableFrom(thingClass); - - public bool IsGibbetCage => typeof(Building_GibbetCage).IsAssignableFrom(thingClass); - - public bool IsMechGestator => typeof(Building_MechGestator).IsAssignableFrom(thingClass); - - public bool IsMechRecharger => typeof(Building_MechCharger).IsAssignableFrom(thingClass); - - public bool IsAddictiveDrug - { - get - { - CompProperties_Drug compProperties = GetCompProperties(); - if (compProperties != null) - { - return compProperties.addictiveness > 0f; - } - return false; - } - } - - public bool IsMeat - { - get - { - if (category == ThingCategory.Item && thingCategories != null) - { - return thingCategories.Contains(ThingCategoryDefOf.MeatRaw); - } - return false; - } - } - - public bool IsEgg - { - get - { - if (category == ThingCategory.Item && thingCategories != null) - { - if (!thingCategories.Contains(ThingCategoryDefOf.EggsFertilized)) - { - return thingCategories.Contains(ThingCategoryDefOf.EggsUnfertilized); - } - return true; - } - return false; - } - } - - public bool IsLeather - { - get - { - if (category == ThingCategory.Item && thingCategories != null) - { - return thingCategories.Contains(ThingCategoryDefOf.Leathers); - } - return false; - } - } - - public bool IsWool - { - get - { - if (category == ThingCategory.Item && thingCategories != null) - { - return thingCategories.Contains(ThingCategoryDefOf.Wools); - } - return false; - } - } - - public bool IsRangedWeapon - { - get - { - if (!IsWeapon) - { - return false; - } - if (!verbs.NullOrEmpty()) - { - for (int i = 0; i < verbs.Count; i++) - { - if (!verbs[i].IsMeleeAttack) - { - return true; - } - } - } - return false; - } - } - - public bool IsMeleeWeapon - { - get - { - if (IsWeapon) - { - return !IsRangedWeapon; - } - return false; - } - } - - public bool IsWeaponUsingProjectiles - { - get - { - if (!IsWeapon) - { - return false; - } - if (!verbs.NullOrEmpty()) - { - for (int i = 0; i < verbs.Count; i++) - { - if (verbs[i].LaunchesProjectile) - { - return true; - } - } - } - return false; - } - } - - public bool IsShieldThatBlocksRanged - { - get - { - if (HasComp(typeof(CompShield))) - { - return GetCompProperties().blocksRangedWeapons; - } - return false; - } - } - - public bool IsBuildingArtificial - { - get - { - if (category == ThingCategory.Building || IsFrame) - { - if (building != null) - { - if (!building.isNaturalRock) - { - return !building.isResourceRock; - } - return false; - } - return true; - } - return false; - } - } - - public bool IsNonResourceNaturalRock - { - get - { - if (category == ThingCategory.Building && building.isNaturalRock && !building.isResourceRock && !building.mineablePreventNaturalRockOnSurface) - { - return !IsSmoothed; - } - return false; - } - } - - public bool HasSunShadows - { - get - { - if (!hasSunShadowsCached.HasValue) - { - hasSunShadowsCached = typeof(Pawn).IsAssignableFrom(thingClass); - } - return hasSunShadowsCached.Value; - } - } - - public bool IsNaturalOrgan - { - get - { - if (!isNaturalOrganCached.HasValue) - { - if (category != ThingCategory.Item) - { - isNaturalOrganCached = false; - } - else - { - List allDefsListForReading = DefDatabase.AllDefsListForReading; - isNaturalOrganCached = false; - for (int i = 0; i < allDefsListForReading.Count; i++) - { - if (allDefsListForReading[i].spawnThingOnRemoved == this) - { - isNaturalOrganCached = true; - break; - } - } - } - } - return isNaturalOrganCached.Value; - } - } - - public bool IsFungus - { - get - { - if (ingestible != null) - { - return ingestible.foodType.HasFlag(FoodTypeFlags.Fungus); - } - return false; - } - } - - public bool IsAnimalProduct - { - get - { - if (ingestible != null) - { - return ingestible.foodType.HasFlag(FoodTypeFlags.AnimalProduct); - } - return false; - } - } - - public bool IsProcessedFood - { - get - { - if (ingestible != null) - { - return ingestible.foodType.HasFlag(FoodTypeFlags.Processed); - } - return false; - } - } - - public bool CanAffectLinker - { - get - { - if (graphicData == null || !graphicData.Linked) - { - return IsDoor; - } - return true; - } - } - - public bool IsNonDeconstructibleAttackableBuilding - { - get - { - if (IsBuildingArtificial && !building.IsDeconstructible && destroyable && !mineable && building.isTargetable) - { - return building.draftAttackNonDeconstructable; - } - return false; - } - } - - public bool IsPlant => typeof(Plant).IsAssignableFrom(thingClass); - - public bool IsDeadPlant => typeof(DeadPlant).IsAssignableFrom(thingClass); - - public bool IsStudiable => HasAssignableCompFrom(typeof(CompStudiable)); - - public List RelevantStyleCategories - { - get - { - if (cachedRelevantStyleCategories == null) - { - cachedRelevantStyleCategories = new List(); - foreach (StyleCategoryDef allDef in DefDatabase.AllDefs) - { - if (allDef.thingDefStyles.NullOrEmpty()) - { - continue; - } - foreach (ThingDefStyle thingDefStyle in allDef.thingDefStyles) - { - if (thingDefStyle.ThingDef == this) - { - cachedRelevantStyleCategories.Add(allDef); - break; - } - } - } - } - return cachedRelevantStyleCategories; - } - } - - public string LabelAsStuff - { - get - { - if (!stuffProps.stuffAdjective.NullOrEmpty()) - { - return stuffProps.stuffAdjective; - } - return label; - } - } - - public bool BlocksPlanting(bool canWipePlants = false) - { - if (building != null && building.SupportsPlants) - { - return false; - } - if (building != null && building.isAttachment) - { - return false; - } - if (blockPlants) - { - return true; - } - if (!canWipePlants && category == ThingCategory.Plant) - { - return true; - } - if ((int)Fillage > 0) - { - return true; - } - if (this.IsEdifice()) - { - return true; - } - return false; - } - - public virtual bool CanSpawnAt(IntVec3 pos, Rot4 rot, Map map) - { - return true; - } - - public bool EverStorable(bool willMinifyIfPossible) - { - if (typeof(MinifiedThing).IsAssignableFrom(thingClass)) - { - return true; - } - if (!thingCategories.NullOrEmpty()) - { - if (category == ThingCategory.Item) - { - return true; - } - if (willMinifyIfPossible && Minifiable) - { - return true; - } - } - return false; - } - - public Thing GetConcreteExample(ThingDef stuff = null) - { - if (concreteExamplesInt == null) - { - concreteExamplesInt = new Dictionary(); - } - if (stuff == null) - { - stuff = ThingDefOf.Steel; - } - if (!concreteExamplesInt.ContainsKey(stuff)) - { - if (race == null) - { - concreteExamplesInt[stuff] = ThingMaker.MakeThing(this, base.MadeFromStuff ? stuff : null); - } - else - { - concreteExamplesInt[stuff] = PawnGenerator.GeneratePawn(DefDatabase.AllDefsListForReading.FirstOrDefault((PawnKindDef pkd) => pkd.race == this)); - } - } - return concreteExamplesInt[stuff]; - } - - public CompProperties CompDefFor() where T : ThingComp - { - for (int i = 0; i < comps.Count; i++) - { - if (comps[i].compClass == typeof(T)) - { - return comps[i]; - } - } - return null; - } - - public CompProperties CompDefForAssignableFrom() where T : ThingComp - { - for (int i = 0; i < comps.Count; i++) - { - if (typeof(T).IsAssignableFrom(comps[i].compClass)) - { - return comps[i]; - } - } - return null; - } - - public bool HasComp(Type compType) - { - for (int i = 0; i < comps.Count; i++) - { - if (comps[i].compClass == compType) - { - return true; - } - } - return false; - } - - public bool HasComp() where T : ThingComp - { - for (int i = 0; i < comps.Count; i++) - { - if (comps[i].compClass == typeof(T) || typeof(T).IsAssignableFrom(comps[i].compClass)) - { - return true; - } - } - return false; - } - - public bool HasAssignableCompFrom(Type compType) - { - for (int i = 0; i < comps.Count; i++) - { - if (compType.IsAssignableFrom(comps[i].compClass)) - { - return true; - } - } - return false; - } - - public T GetCompProperties() where T : CompProperties - { - for (int i = 0; i < comps.Count; i++) - { - if (comps[i] is T result) - { - return result; - } - } - return null; - } - - public override void PostLoad() - { - if (graphicData != null) - { - LongEventHandler.ExecuteWhenFinished(delegate - { - GraphicData graphicData = this.graphicData; - if (graphicData.shaderType == null) - { - graphicData.shaderType = ShaderTypeDefOf.Cutout; - } - ContentFinderRequester.requester = this; - try - { - graphic = this.graphicData.Graphic; - if (drawerType != DrawerType.RealtimeOnly) - { - TextureAtlasGroup textureAtlasGroup = category.ToAtlasGroup(); - graphic.TryInsertIntoAtlas(textureAtlasGroup); - if (textureAtlasGroup == TextureAtlasGroup.Building && Minifiable) - { - graphic.TryInsertIntoAtlas(TextureAtlasGroup.Item); - } - } - } - finally - { - ContentFinderRequester.requester = null; - } - }); - } - if (tools != null) - { - for (int i = 0; i < tools.Count; i++) - { - tools[i].id = i.ToString(); - } - } - if (verbs != null && verbs.Count == 1 && verbs[0].label.NullOrEmpty()) - { - verbs[0].label = label; - } - base.PostLoad(); - if (category == ThingCategory.Building && building == null) - { - building = new BuildingProperties(); - } - building?.PostLoadSpecial(this); - apparel?.PostLoadSpecial(this); - plant?.PostLoadSpecial(this); - if (comps == null) - { - return; - } - foreach (CompProperties comp in comps) - { - comp.PostLoadSpecial(this); - } - } - - protected override void ResolveIcon() - { - base.ResolveIcon(); - if (category == ThingCategory.Pawn) - { - if (!uiIconPath.NullOrEmpty()) - { - uiIcon = ContentFinder.Get(uiIconPath); - } - else - { - if (race.Humanlike) - { - return; - } - PawnKindDef anyPawnKind = race.AnyPawnKind; - if (anyPawnKind != null) - { - Material material = ((ModsConfig.BiotechActive && anyPawnKind.RaceProps.IsMechanoid) ? anyPawnKind.lifeStages.First() : anyPawnKind.lifeStages.Last()).bodyGraphicData.Graphic.MatAt(Rot4.East); - uiIcon = (Texture2D)material.mainTexture; - uiIconColor = material.color; - if (ShaderDatabase.TryGetUIShader(material.shader, out var uiShader) && MaterialPool.TryGetRequestForMat(material, out var request)) - { - request.shader = uiShader; - uiIconMaterial = MaterialPool.MatFrom(request); - } - } - } - } - else - { - ThingDef thingDef = GenStuff.DefaultStuffFor(this); - if (colorGenerator != null && (thingDef == null || thingDef.stuffProps.allowColorGenerators)) - { - uiIconColor = colorGenerator.ExemplaryColor; - } - else if (thingDef != null) - { - uiIconColor = GetColorForStuff(thingDef); - } - else if (graphicData != null) - { - uiIconColor = graphicData.color; - } - if (rotatable && graphic != null && graphic != BaseContent.BadGraphic && graphic.ShouldDrawRotated && defaultPlacingRot == Rot4.South) - { - uiIconAngle = 180f + graphic.DrawRotatedExtraAngleOffset; - } - } - } - - public override void ResolveReferences() - { - base.ResolveReferences(); - if (ingestible != null) - { - ingestible.parent = this; - } - if (stuffProps != null) - { - stuffProps.parent = this; - } - building?.ResolveReferencesSpecial(); - graphicData?.ResolveReferencesSpecial(); - race?.ResolveReferencesSpecial(); - stuffProps?.ResolveReferencesSpecial(); - apparel?.ResolveReferencesSpecial(); - if (soundImpactDefault == null) - { - soundImpactDefault = SoundDefOf.BulletImpact_Ground; - } - if (soundDrop == null) - { - soundDrop = SoundDefOf.Standard_Drop; - } - if (soundPickup == null) - { - soundPickup = SoundDefOf.Standard_Pickup; - } - if (soundInteract == null) - { - soundInteract = SoundDefOf.Standard_Pickup; - } - if (inspectorTabs != null && inspectorTabs.Any()) - { - inspectorTabsResolved = new List(); - for (int i = 0; i < inspectorTabs.Count; i++) - { - try - { - inspectorTabsResolved.Add(InspectTabManager.GetSharedInstance(inspectorTabs[i])); - } - catch (Exception ex) - { - Log.Error("Could not instantiate inspector tab of type " + inspectorTabs[i]?.ToString() + ": " + ex); - } - } - } - if (comps != null) - { - for (int j = 0; j < comps.Count; j++) - { - comps[j].ResolveReferences(this); - } - } - } - - public override IEnumerable ConfigErrors() - { - foreach (string item in base.ConfigErrors()) - { - yield return item; - } - if (category != ThingCategory.Ethereal && label.NullOrEmpty()) - { - yield return "no label"; - } - if (category == ThingCategory.Building && !IsFrame && building.IsDeconstructible && thingClass != null && typeof(Building).IsSubclassOf(thingClass)) - { - yield return "has building category and is marked as deconstructible, but thing class is not a subclass of building (" + thingClass.Name + ")"; - } - if (graphicData != null) - { - foreach (string item2 in graphicData.ConfigErrors(this)) - { - yield return item2; - } - } - if (projectile != null) - { - foreach (string item3 in projectile.ConfigErrors(this)) - { - yield return item3; - } - } - if (statBases != null) - { - foreach (StatModifier statBase in statBases) - { - if (statBases.Count((StatModifier st) => st.stat == statBase.stat) > 1) - { - yield return "defines the stat base " + statBase.stat?.ToString() + " more than once."; - } - } - } - if (!BeautyUtility.BeautyRelevant(category) && this.StatBaseDefined(StatDefOf.Beauty)) - { - yield return "Beauty stat base is defined, but Things of category " + category.ToString() + " cannot have beauty."; - } - if (!BeautyUtility.BeautyRelevant(category) && this.StatBaseDefined(StatDefOf.BeautyOutdoors)) - { - yield return "BeautyOutdoors stat base is defined, but Things of category " + category.ToString() + " cannot have beauty."; - } - if (char.IsNumber(defName[defName.Length - 1])) - { - yield return "ends with a numerical digit, which is not allowed on ThingDefs."; - } - if (thingClass == null) - { - yield return "has null thingClass."; - } - if (comps.Count > 0 && !typeof(ThingWithComps).IsAssignableFrom(thingClass)) - { - yield return "has components but it's thingClass is not a ThingWithComps"; - } - if (ConnectToPower && drawerType == DrawerType.RealtimeOnly && IsFrame) - { - yield return "connects to power but does not add to map mesh. Will not create wire meshes."; - } - if (costList != null) - { - foreach (ThingDefCountClass cost in costList) - { - if (cost.count == 0) - { - yield return "cost in " + cost.thingDef?.ToString() + " is zero."; - } - } - } - ThingCategoryDef thingCategoryDef = thingCategories?.FirstOrDefault((ThingCategoryDef cat) => thingCategories.Count((ThingCategoryDef c) => c == cat) > 1); - if (thingCategoryDef != null) - { - yield return "has duplicate thingCategory " + thingCategoryDef?.ToString() + "."; - } - if (Fillage == FillCategory.Full && category != ThingCategory.Building) - { - yield return "gives full cover but is not a building."; - } - if (equipmentType != 0) - { - if (techLevel == TechLevel.Undefined && !destroyOnDrop) - { - yield return "is equipment but has no tech level."; - } - if (!comps.Any((CompProperties c) => typeof(CompEquippable).IsAssignableFrom(c.compClass))) - { - yield return "is equipment but has no CompEquippable"; - } - } - if (thingClass == typeof(Bullet) && projectile.damageDef == null) - { - yield return " is a bullet but has no damageDef."; - } - if (destroyOnDrop && tradeability != 0) - { - yield return "destroyOnDrop but tradeability is " + tradeability; - } - if (stackLimit > 1 && !drawGUIOverlay) - { - yield return "has stackLimit > 1 but also has drawGUIOverlay = false."; - } - if (damageMultipliers != null) - { - foreach (DamageMultiplier mult in damageMultipliers) - { - if (damageMultipliers.Count((DamageMultiplier m) => m.damageDef == mult.damageDef) > 1) - { - yield return "has multiple damage multipliers for damageDef " + mult.damageDef; - break; - } - } - } - if (Fillage == FillCategory.Full && !this.IsEdifice()) - { - yield return "fillPercent is 1.00 but is not edifice"; - } - if (base.MadeFromStuff && constructEffect != null) - { - yield return "madeFromStuff but has a defined constructEffect (which will always be overridden by stuff's construct animation)."; - } - if (base.MadeFromStuff && stuffCategories.NullOrEmpty()) - { - yield return "madeFromStuff but has no stuffCategories."; - } - if (costList.NullOrEmpty() && costStuffCount <= 0 && recipeMaker != null) - { - yield return "has a recipeMaker but no costList or costStuffCount."; - } - if (costStuffCount > 0 && stuffCategories.NullOrEmpty()) - { - yield return "has costStuffCount but no stuffCategories."; - } - if (this.GetStatValueAbstract(StatDefOf.DeteriorationRate) > 1E-05f && !CanEverDeteriorate && !destroyOnDrop) - { - yield return "has >0 DeteriorationRate but can't deteriorate."; - } - if (smeltProducts != null && !smeltable) - { - yield return "has smeltProducts but has smeltable=false"; - } - if (smeltable && smeltProducts.NullOrEmpty() && base.CostList.NullOrEmpty() && !IsStuff && !base.MadeFromStuff && !destroyOnDrop) - { - yield return "is smeltable but does not give anything for smelting."; - } - if (equipmentType != 0 && verbs.NullOrEmpty() && tools.NullOrEmpty()) - { - yield return "is equipment but has no verbs or tools"; - } - if (Minifiable && thingCategories.NullOrEmpty()) - { - yield return "is minifiable but not in any thing category"; - } - if (category == ThingCategory.Building && !Minifiable && !thingCategories.NullOrEmpty()) - { - yield return "is not minifiable yet has thing categories (could be confusing in thing filters because it can't be moved/stored anyway)"; - } - if (!destroyOnDrop && !typeof(MinifiedThing).IsAssignableFrom(thingClass) && (EverHaulable || Minifiable) && (statBases.NullOrEmpty() || !statBases.Any((StatModifier s) => s.stat == StatDefOf.Mass))) - { - yield return "is haulable, but does not have an authored mass value"; - } - if (ingestible == null && this.GetStatValueAbstract(StatDefOf.Nutrition) != 0f) - { - yield return "has nutrition but ingestible properties are null"; - } - if (BaseFlammability != 0f && !useHitPoints && category != ThingCategory.Pawn && !destroyOnDrop) - { - yield return "flammable but has no hitpoints (will burn indefinitely)"; - } - if (graphicData?.shadowData != null && staticSunShadowHeight > 0f) - { - yield return "graphicData defines a shadowInfo but staticSunShadowHeight > 0"; - } - if (saveCompressible && Claimable) - { - yield return "claimable item is compressible; faction will be unset after load"; - } - if (deepCommonality > 0f != deepLumpSizeRange.TrueMax > 0) - { - yield return "if deepCommonality or deepLumpSizeRange is set, the other also must be set"; - } - if (deepCommonality > 0f && deepCountPerPortion <= 0) - { - yield return "deepCommonality > 0 but deepCountPerPortion is not set"; - } - if (verbs != null) - { - for (int i = 0; i < verbs.Count; i++) - { - foreach (string item4 in verbs[i].ConfigErrors(this)) - { - yield return $"verb {i}: {item4}"; - } - } - } - if (building != null) - { - foreach (string item5 in building.ConfigErrors(this)) - { - yield return item5; - } - if ((building.isAirtight || building.isStuffableAirtight) && Fillage != FillCategory.Full) - { - yield return "is airtight but Fillage is not Full"; - } - } - if (apparel != null) - { - foreach (string item6 in apparel.ConfigErrors(this)) - { - yield return item6; - } - } - if (comps != null) - { - for (int i = 0; i < comps.Count; i++) - { - foreach (string item7 in comps[i].ConfigErrors(this)) - { - yield return item7; - } - } - } - if (race != null) - { - foreach (string item8 in race.ConfigErrors(this)) - { - yield return item8; - } - if (race.body != null && race != null && tools != null) - { - int i; - for (i = 0; i < tools.Count; i++) - { - if (tools[i].linkedBodyPartsGroup != null && !race.body.AllParts.Any((BodyPartRecord part) => part.groups.Contains(tools[i].linkedBodyPartsGroup))) - { - yield return "has tool with linkedBodyPartsGroup " + tools[i].linkedBodyPartsGroup?.ToString() + " but body " + race.body?.ToString() + " has no parts with that group."; - } - } - } - if (race.Animal && this.GetStatValueAbstract(StatDefOf.Wildness) < 0f) - { - yield return "is animal but wildness is not defined"; - } - } - if (ingestible != null) - { - foreach (string item9 in ingestible.ConfigErrors()) - { - yield return item9; - } - } - if (plant != null) - { - foreach (string item10 in plant.ConfigErrors()) - { - yield return item10; - } - } - if (tools != null) - { - Tool tool = tools.SelectMany((Tool lhs) => tools.Where((Tool rhs) => lhs != rhs && lhs.id == rhs.id)).FirstOrDefault(); - if (tool != null) - { - yield return "duplicate thingdef tool id " + tool.id; - } - foreach (Tool tool2 in tools) - { - foreach (string item11 in tool2.ConfigErrors()) - { - yield return item11; - } - } - } - if (!randomStyle.NullOrEmpty()) - { - foreach (ThingStyleChance item12 in randomStyle) - { - if (item12.Chance <= 0f) - { - yield return "style chance <= 0."; - } - } - if (!comps.Any((CompProperties c) => c.compClass == typeof(CompStyleable))) - { - yield return "random style assigned, but missing CompStyleable!"; - } - } - if (relicChance > 0f && category != ThingCategory.Item) - { - yield return "relic chance > 0 but category != item"; - } - if (hasInteractionCell && !multipleInteractionCellOffsets.NullOrEmpty()) - { - yield return "both single and multiple interaction cells are defined, it should be one or the other"; - } - if (Fillage != FillCategory.Full && passability == Traversability.Impassable && !IsDoor && base.BuildableByPlayer && !disableImpassableShotOverConfigError) - { - yield return "impassable, player-buildable building that can be shot/seen over."; - } - } - - public static ThingDef Named(string defName) - { - return DefDatabase.GetNamed(defName); - } - - public bool IsWithinCategory(ThingCategoryDef category) - { - if (thingCategories == null) - { - return false; - } - for (int i = 0; i < thingCategories.Count; i++) - { - for (ThingCategoryDef thingCategoryDef = thingCategories[i]; thingCategoryDef != null; thingCategoryDef = thingCategoryDef.parent) - { - if (thingCategoryDef == category) - { - return true; - } - } - } - return false; - } - - public void Notify_UnlockedByResearch() - { - if (comps != null) - { - for (int i = 0; i < comps.Count; i++) - { - comps[i].Notify_PostUnlockedByResearch(this); - } - } - } - - public override IEnumerable SpecialDisplayStats(StatRequest req) - { - foreach (StatDrawEntry item in base.SpecialDisplayStats(req)) - { - yield return item; - } - if (apparel != null) - { - string coveredOuterPartsString = apparel.GetCoveredOuterPartsString(BodyDefOf.Human); - yield return new StatDrawEntry(StatCategoryDefOf.Apparel, "Covers".Translate(), coveredOuterPartsString, "Stat_Thing_Apparel_Covers_Desc".Translate(), 2750); - yield return new StatDrawEntry(StatCategoryDefOf.Apparel, "Layer".Translate(), apparel.GetLayersString(), "Stat_Thing_Apparel_Layer_Desc".Translate(), 2751); - yield return new StatDrawEntry(StatCategoryDefOf.Apparel, "Stat_Thing_Apparel_CountsAsClothingNudity_Name".Translate(), apparel.countsAsClothingForNudity ? "Yes".Translate() : "No".Translate(), "Stat_Thing_Apparel_CountsAsClothingNudity_Desc".Translate(), 2753); - if (ModsConfig.BiotechActive) - { - yield return new StatDrawEntry(StatCategoryDefOf.Apparel, "Stat_Thing_Apparel_ValidLifestage".Translate(), apparel.developmentalStageFilter.ToCommaList().CapitalizeFirst(), "Stat_Thing_Apparel_ValidLifestage_Desc".Translate(), 2748); - } - if (apparel.gender != 0) - { - yield return new StatDrawEntry(StatCategoryDefOf.Apparel, "Stat_Thing_Apparel_Gender".Translate(), apparel.gender.GetLabel().CapitalizeFirst(), "Stat_Thing_Apparel_Gender_Desc".Translate(), 2749); - } - } - if (IsMedicine && MedicineTendXpGainFactor != 1f) - { - yield return new StatDrawEntry(StatCategoryDefOf.Basics, "MedicineXpGainFactor".Translate(), MedicineTendXpGainFactor.ToStringPercent(), "Stat_Thing_Drug_MedicineXpGainFactor_Desc".Translate(), 1000); - } - if (fillPercent > 0f && (category == ThingCategory.Item || category == ThingCategory.Building || category == ThingCategory.Plant)) - { - yield return new StatDrawEntry(StatCategoryDefOf.Basics, "CoverEffectiveness".Translate(), this.BaseBlockChance().ToStringPercent(), "CoverEffectivenessExplanation".Translate(), 2000); - } - if (constructionSkillPrerequisite > 0) - { - yield return new StatDrawEntry(StatCategoryDefOf.Basics, "SkillRequiredToBuild".Translate(SkillDefOf.Construction.LabelCap), constructionSkillPrerequisite.ToString(), "SkillRequiredToBuildExplanation".Translate(SkillDefOf.Construction.LabelCap), 1100); - } - if (artisticSkillPrerequisite > 0) - { - yield return new StatDrawEntry(StatCategoryDefOf.Basics, "SkillRequiredToBuild".Translate(SkillDefOf.Artistic.LabelCap), artisticSkillPrerequisite.ToString(), "SkillRequiredToBuildExplanation".Translate(SkillDefOf.Artistic.LabelCap), 1100); - } - IEnumerable recipes = DefDatabase.AllDefsListForReading.Where((RecipeDef r) => r.products.Count == 1 && r.products.Any((ThingDefCountClass p) => p.thingDef == this) && !r.IsSurgery); - if (recipes.Any()) - { - IEnumerable enumerable = (from u in recipes.Where((RecipeDef x) => x.recipeUsers != null).SelectMany((RecipeDef r) => r.recipeUsers) - select u.label).Concat(from x in DefDatabase.AllDefsListForReading - where x.recipes != null && x.recipes.Any((RecipeDef y) => y.products.Any((ThingDefCountClass z) => z.thingDef == this)) - select x.label).Distinct(); - if (enumerable.Any()) - { - yield return new StatDrawEntry(StatCategoryDefOf.Basics, "CreatedAt".Translate(), enumerable.ToCommaList().CapitalizeFirst(), "Stat_Thing_CreatedAt_Desc".Translate(), 1103); - } - RecipeDef recipeDef = recipes.FirstOrDefault(); - if (recipeDef != null && !recipeDef.ingredients.NullOrEmpty()) - { - BuildableDef.tmpCostList.Clear(); - BuildableDef.tmpHyperlinks.Clear(); - for (int j = 0; j < recipeDef.ingredients.Count; j++) - { - IngredientCount ingredientCount = recipeDef.ingredients[j]; - if (ingredientCount.filter.Summary.NullOrEmpty()) - { - continue; - } - IEnumerable allowedThingDefs = ingredientCount.filter.AllowedThingDefs; - if (allowedThingDefs.Any()) - { - foreach (ThingDef p in allowedThingDefs) - { - if (!BuildableDef.tmpHyperlinks.Any((Dialog_InfoCard.Hyperlink x) => x.def == p)) - { - BuildableDef.tmpHyperlinks.Add(new Dialog_InfoCard.Hyperlink(p)); - } - } - } - BuildableDef.tmpCostList.Add(recipeDef.IngredientValueGetter.BillRequirementsDescription(recipeDef, ingredientCount)); - } - } - if (BuildableDef.tmpCostList.Any()) - { - yield return new StatDrawEntry(StatCategoryDefOf.Basics, "Ingredients".Translate(), BuildableDef.tmpCostList.ToCommaList(), "Stat_Thing_Ingredients".Translate(), 1102, null, BuildableDef.tmpHyperlinks); - } - } - if (thingClass != null && typeof(Building_Bed).IsAssignableFrom(thingClass) && !statBases.StatListContains(StatDefOf.BedRestEffectiveness)) - { - yield return new StatDrawEntry(StatCategoryDefOf.Building, StatDefOf.BedRestEffectiveness, StatDefOf.BedRestEffectiveness.valueIfMissing, StatRequest.ForEmpty()); - } - if (!verbs.NullOrEmpty()) - { - VerbProperties verb = verbs.First((VerbProperties x) => x.isPrimary); - StatCategoryDef verbStatCategory = ((category == ThingCategory.Pawn) ? StatCategoryDefOf.PawnCombat : null); - float num = verb.warmupTime; - StringBuilder stringBuilder = new StringBuilder("Stat_Thing_Weapon_RangedWarmupTime_Desc".Translate()); - stringBuilder.AppendLine(); - stringBuilder.AppendLine(); - stringBuilder.AppendLine("StatsReport_BaseValue".Translate() + ": " + num.ToString("0.##") + " " + "LetterSecond".Translate()); - if (num > 0f) - { - if (req.HasThing) - { - float statValue = req.Thing.GetStatValue(StatDefOf.RangedWeapon_WarmupMultiplier); - num *= statValue; - if (!Mathf.Approximately(statValue, 1f)) - { - stringBuilder.AppendLine(); - stringBuilder.AppendLine("Stat_Thing_Weapon_WarmupTime_Multiplier".Translate() + ": x" + statValue.ToStringPercent()); - stringBuilder.Append(StatUtility.GetOffsetsAndFactorsFor(StatDefOf.RangedWeapon_WarmupMultiplier, req.Thing)); - } - } - stringBuilder.AppendLine(); - stringBuilder.AppendLine("StatsReport_FinalValue".Translate() + ": " + num.ToString("0.##") + " " + "LetterSecond".Translate()); - yield return new StatDrawEntry(verbStatCategory ?? StatCategoryDefOf.Weapon_Ranged, "RangedWarmupTime".Translate(), num.ToString("0.##") + " " + "LetterSecond".Translate(), stringBuilder.ToString(), 3555); - } - if (verb.defaultProjectile?.projectile.damageDef != null && verb.defaultProjectile.projectile.damageDef.harmsHealth) - { - StatCategoryDef statCat = verbStatCategory ?? StatCategoryDefOf.Weapon_Ranged; - StringBuilder stringBuilder2 = new StringBuilder(); - stringBuilder2.AppendLine("Stat_Thing_Damage_Desc".Translate()); - stringBuilder2.AppendLine(); - float num2 = verb.defaultProjectile.projectile.GetDamageAmount(req.Thing, stringBuilder2); - yield return new StatDrawEntry(statCat, "Damage".Translate(), num2.ToString(), stringBuilder2.ToString(), 5500); - if (verb.defaultProjectile.projectile.damageDef.armorCategory != null) - { - StringBuilder stringBuilder3 = new StringBuilder(); - float armorPenetration = verb.defaultProjectile.projectile.GetArmorPenetration(req.Thing, stringBuilder3); - TaggedString taggedString = "ArmorPenetrationExplanation".Translate(); - if (stringBuilder3.Length != 0) - { - taggedString += "\n\n" + stringBuilder3; - } - yield return new StatDrawEntry(statCat, "ArmorPenetration".Translate(), armorPenetration.ToStringPercent(), taggedString, 5400); - } - float buildingDamageFactor = verb.defaultProjectile.projectile.damageDef.buildingDamageFactor; - float dmgBuildingsImpassable = verb.defaultProjectile.projectile.damageDef.buildingDamageFactorImpassable; - float dmgBuildingsPassable = verb.defaultProjectile.projectile.damageDef.buildingDamageFactorPassable; - if (buildingDamageFactor != 1f) - { - yield return new StatDrawEntry(statCat, "BuildingDamageFactor".Translate(), buildingDamageFactor.ToStringPercent(), "BuildingDamageFactorExplanation".Translate(), 5410); - } - if (dmgBuildingsImpassable != 1f) - { - yield return new StatDrawEntry(statCat, "BuildingDamageFactorImpassable".Translate(), dmgBuildingsImpassable.ToStringPercent(), "BuildingDamageFactorImpassableExplanation".Translate(), 5420); - } - if (dmgBuildingsPassable != 1f) - { - yield return new StatDrawEntry(statCat, "BuildingDamageFactorPassable".Translate(), dmgBuildingsPassable.ToStringPercent(), "BuildingDamageFactorPassableExplanation".Translate(), 5430); - } - } - if (verb.defaultProjectile == null && verb.beamDamageDef != null) - { - yield return new StatDrawEntry(verbStatCategory ?? StatCategoryDefOf.Weapon_Ranged, "ArmorPenetration".Translate(), verb.beamDamageDef.defaultArmorPenetration.ToStringPercent(), "ArmorPenetrationExplanation".Translate(), 5400); - } - if (verb.Ranged) - { - float num3 = verb.burstShotCount; - float num4 = verb.ticksBetweenBurstShots; - float dmgBuildingsPassable = (verb?.defaultProjectile?.projectile?.stoppingPower).GetValueOrDefault(); - StringBuilder stringBuilder4 = new StringBuilder("Stat_Thing_Weapon_BurstShotFireRate_Desc".Translate()); - stringBuilder4.AppendLine(); - stringBuilder4.AppendLine(); - stringBuilder4.AppendLine("StatsReport_BaseValue".Translate() + ": " + verb.burstShotCount.ToString()); - stringBuilder4.AppendLine(); - StringBuilder ticksBetweenBurstShotsExplanation = new StringBuilder("Stat_Thing_Weapon_BurstShotFireRate_Desc".Translate()); - ticksBetweenBurstShotsExplanation.AppendLine(); - ticksBetweenBurstShotsExplanation.AppendLine(); - ticksBetweenBurstShotsExplanation.AppendLine("StatsReport_BaseValue".Translate() + ": " + (60f / verb.ticksBetweenBurstShots.TicksToSeconds()).ToString("0.##") + " rpm"); - ticksBetweenBurstShotsExplanation.AppendLine(); - StringBuilder stoppingPowerExplanation = new StringBuilder("StoppingPowerExplanation".Translate()); - stoppingPowerExplanation.AppendLine(); - stoppingPowerExplanation.AppendLine(); - stoppingPowerExplanation.AppendLine("StatsReport_BaseValue".Translate() + ": " + dmgBuildingsPassable.ToString("F1")); - stoppingPowerExplanation.AppendLine(); - if (req.HasThing && req.Thing.TryGetComp(out CompUniqueWeapon comp)) - { - bool flag = false; - bool flag2 = false; - bool flag3 = false; - foreach (WeaponTraitDef item2 in comp.TraitsListForReading) - { - if (!Mathf.Approximately(item2.burstShotCountMultiplier, 1f)) - { - if (!flag) - { - stringBuilder4.AppendLine("StatsReport_WeaponTraits".Translate() + ":"); - flag = true; - } - num3 *= item2.burstShotCountMultiplier; - stringBuilder4.AppendLine(" " + item2.LabelCap + ": " + item2.burstShotCountMultiplier.ToStringByStyle(ToStringStyle.PercentOne, ToStringNumberSense.Factor)); - } - if (!Mathf.Approximately(item2.burstShotSpeedMultiplier, 1f)) - { - if (!flag2) - { - ticksBetweenBurstShotsExplanation.AppendLine("StatsReport_WeaponTraits".Translate() + ":"); - flag2 = true; - } - num4 /= item2.burstShotSpeedMultiplier; - ticksBetweenBurstShotsExplanation.AppendLine(" " + item2.LabelCap + ": " + item2.burstShotSpeedMultiplier.ToStringByStyle(ToStringStyle.PercentOne, ToStringNumberSense.Factor)); - } - if (!Mathf.Approximately(item2.additionalStoppingPower, 0f)) - { - if (!flag3) - { - stoppingPowerExplanation.AppendLine("StatsReport_WeaponTraits".Translate() + ":"); - flag3 = true; - } - dmgBuildingsPassable += item2.additionalStoppingPower; - stoppingPowerExplanation.AppendLine(" " + item2.LabelCap + ": " + item2.additionalStoppingPower.ToStringByStyle(ToStringStyle.FloatOne, ToStringNumberSense.Offset)); - } - } - } - stringBuilder4.AppendLine(); - stringBuilder4.AppendLine("StatsReport_FinalValue".Translate() + ": " + Mathf.CeilToInt(num3).ToString()); - float dmgBuildingsImpassable = 60f / ((int)num4).TicksToSeconds(); - ticksBetweenBurstShotsExplanation.AppendLine(); - ticksBetweenBurstShotsExplanation.AppendLine("StatsReport_FinalValue".Translate() + ": " + dmgBuildingsImpassable.ToString("0.##") + " rpm"); - stoppingPowerExplanation.AppendLine(); - stoppingPowerExplanation.AppendLine("StatsReport_FinalValue".Translate() + ": " + dmgBuildingsPassable.ToString("F1")); - StatCategoryDef statCat = verbStatCategory ?? StatCategoryDefOf.Weapon_Ranged; - if (verb.showBurstShotStats && verb.burstShotCount > 1) - { - yield return new StatDrawEntry(statCat, "BurstShotCount".Translate(), Mathf.CeilToInt(num3).ToString(), stringBuilder4.ToString(), 5391); - yield return new StatDrawEntry(statCat, "BurstShotFireRate".Translate(), dmgBuildingsImpassable.ToString("0.##") + " rpm", ticksBetweenBurstShotsExplanation.ToString(), 5395); - } - if (dmgBuildingsPassable > 0f) - { - yield return new StatDrawEntry(statCat, "StoppingPower".Translate(), dmgBuildingsPassable.ToString("F1"), stoppingPowerExplanation.ToString(), 5402); - } - float num5 = verb.range; - StringBuilder stringBuilder5 = new StringBuilder("Stat_Thing_Weapon_Range_Desc".Translate()); - stringBuilder5.AppendLine(); - stringBuilder5.AppendLine(); - stringBuilder5.AppendLine("StatsReport_BaseValue".Translate() + ": " + num5.ToString("F0")); - if (req.HasThing) - { - float statValue2 = req.Thing.GetStatValue(StatDefOf.RangedWeapon_RangeMultiplier); - num5 *= statValue2; - if (!Mathf.Approximately(statValue2, 1f)) - { - stringBuilder5.AppendLine(); - stringBuilder5.AppendLine("Stat_Thing_Weapon_Range_Multiplier".Translate() + ": x" + statValue2.ToStringPercent()); - stringBuilder5.Append(StatUtility.GetOffsetsAndFactorsFor(StatDefOf.RangedWeapon_RangeMultiplier, req.Thing)); - } - Map obj = req.Thing.Map ?? req.Thing.MapHeld; - if (obj != null && obj.weatherManager.CurWeatherMaxRangeCap >= 0f) - { - WeatherManager weatherManager = (req.Thing.Map ?? req.Thing.MapHeld).weatherManager; - bool num6 = num5 > weatherManager.CurWeatherMaxRangeCap; - float num7 = num5; - num5 = Mathf.Min(num5, weatherManager.CurWeatherMaxRangeCap); - if (num6) - { - stringBuilder5.AppendLine(); - stringBuilder5.AppendLine(" " + "Stat_Thing_Weapon_Range_Clamped".Translate(num5.ToString("F0").Named("CAP"), num7.ToString("F0").Named("ORIGINAL"))); - } - } - } - stringBuilder5.AppendLine(); - stringBuilder5.AppendLine("StatsReport_FinalValue".Translate() + ": " + num5.ToString("F0")); - yield return new StatDrawEntry(statCat, "Range".Translate(), num5.ToString("F0"), stringBuilder5.ToString(), 5390); - } - if (verb.ForcedMissRadius > 0f) - { - StatCategoryDef statCat = verbStatCategory ?? StatCategoryDefOf.Weapon_Ranged; - yield return new StatDrawEntry(statCat, "MissRadius".Translate(), verb.ForcedMissRadius.ToString("0.#"), "Stat_Thing_Weapon_MissRadius_Desc".Translate(), 3557); - yield return new StatDrawEntry(statCat, "DirectHitChance".Translate(), (1f / (float)GenRadial.NumCellsInRadius(verb.ForcedMissRadius)).ToStringPercent(), "Stat_Thing_Weapon_DirectHitChance_Desc".Translate(), 3560); - } - } - if (plant != null) - { - foreach (StatDrawEntry item3 in plant.SpecialDisplayStats()) - { - yield return item3; - } - } - if (ingestible != null) - { - foreach (StatDrawEntry item4 in ingestible.SpecialDisplayStats()) - { - yield return item4; - } - } - if (race != null) - { - foreach (StatDrawEntry item5 in race.SpecialDisplayStats(this, req)) - { - yield return item5; - } - } - if (building != null) - { - foreach (StatDrawEntry item6 in building.SpecialDisplayStats(this, req)) - { - yield return item6; - } - } - if (isTechHediff) - { - IEnumerable enumerable2 = DefDatabase.AllDefs.Where((RecipeDef x) => x.addsHediff != null && x.IsIngredient(this)); - foreach (StatDrawEntry medicalStatsFromRecipeDef in MedicalRecipesUtility.GetMedicalStatsFromRecipeDefs(enumerable2)) - { - yield return medicalStatsFromRecipeDef; - } - } - for (int i = 0; i < comps.Count; i++) - { - foreach (StatDrawEntry item7 in comps[i].SpecialDisplayStats(req)) - { - yield return item7; - } - } - if (building != null) - { - if (building.mineableThing != null) - { - Dialog_InfoCard.Hyperlink[] hyperlinks = new Dialog_InfoCard.Hyperlink[1] - { - new Dialog_InfoCard.Hyperlink(building.mineableThing) - }; - yield return new StatDrawEntry(StatCategoryDefOf.BasicsImportant, "Stat_MineableThing_Name".Translate(), building.mineableThing.LabelCap, "Stat_MineableThing_Desc".Translate(), 2200, null, hyperlinks); - StringBuilder stringBuilder6 = new StringBuilder(); - stringBuilder6.AppendLine("Stat_MiningYield_Desc".Translate()); - stringBuilder6.AppendLine(); - stringBuilder6.AppendLine("StatsReport_DifficultyMultiplier".Translate(Find.Storyteller.difficultyDef.label) + ": " + Find.Storyteller.difficulty.mineYieldFactor.ToStringByStyle(ToStringStyle.PercentZero, ToStringNumberSense.Factor)); - yield return new StatDrawEntry(StatCategoryDefOf.Basics, "Stat_MiningYield_Name".Translate(), Mathf.CeilToInt(building.EffectiveMineableYield).ToString("F0"), stringBuilder6.ToString(), 2200, null, hyperlinks); - } - if (building.IsTurret) - { - ThingDef turret = building.turretGunDef; - yield return new StatDrawEntry(StatCategoryDefOf.BasicsImportant, "Stat_Weapon_Name".Translate(), turret.LabelCap, "Stat_Weapon_Desc".Translate(), 5389, null, new Dialog_InfoCard.Hyperlink[1] - { - new Dialog_InfoCard.Hyperlink(turret) - }); - StatRequest request = StatRequest.For(turret, null); - foreach (StatDrawEntry item8 in turret.SpecialDisplayStats(request)) - { - if (item8.category == StatCategoryDefOf.Weapon_Ranged) - { - yield return item8; - } - } - for (int i = 0; i < turret.statBases.Count; i++) - { - StatModifier statModifier = turret.statBases[i]; - if (statModifier.stat.category == StatCategoryDefOf.Weapon_Ranged) - { - yield return new StatDrawEntry(StatCategoryDefOf.Weapon_Ranged, statModifier.stat, statModifier.value, request); - } - } - } - if (ModsConfig.OdysseyActive && Fillage == FillCategory.Full) - { - bool b = building.isAirtight || (building.isStuffableAirtight && req.StuffDef.stuffProps.isAirtight); - yield return new StatDrawEntry(StatCategoryDefOf.Building, "Stat_Airtight".Translate(), b.ToStringYesNo(), "Stat_Airtight_Desc".Translate(), 6100); - } - } - if (IsMeat) - { - List list = new List(); - bool flag4 = false; - foreach (ThingDef allDef in DefDatabase.AllDefs) - { - if (allDef.race != null && allDef.race.meatDef == this && !allDef.IsCorpse) - { - if (!Find.HiddenItemsManager.Hidden(allDef)) - { - flag4 = true; - } - list.Add(allDef); - } - } - yield return new StatDrawEntry(valueString: (!flag4) ? string.Format("({0})", "NotYetDiscovered".Translate()) : string.Join(", ", (from x in list - where !Find.HiddenItemsManager.Hidden(x) - select x into p - select p.label).ToArray()).CapitalizeFirst(), category: StatCategoryDefOf.BasicsPawn, label: "Stat_SourceSpecies_Name".Translate(), reportText: "Stat_SourceSpecies_Desc".Translate(), displayPriorityWithinCategory: 1200, overrideReportTitle: null, hyperlinks: Dialog_InfoCard.DefsToHyperlinks(list)); - } - if (IsLeather) - { - List list2 = new List(); - bool flag5 = false; - foreach (ThingDef allDef2 in DefDatabase.AllDefs) - { - if (allDef2.race != null && allDef2.race.leatherDef == this && !allDef2.IsCorpse) - { - if (!Find.HiddenItemsManager.Hidden(allDef2)) - { - flag5 = true; - } - list2.Add(allDef2); - } - } - yield return new StatDrawEntry(valueString: (!flag5) ? string.Format("({0})", "NotYetDiscovered".Translate()) : string.Join(", ", (from x in list2 - where !Find.HiddenItemsManager.Hidden(x) - select x into p - select p.label).ToArray()).CapitalizeFirst(), category: StatCategoryDefOf.BasicsPawn, label: "Stat_SourceSpecies_Name".Translate(), reportText: "Stat_SourceSpecies_Desc".Translate(), displayPriorityWithinCategory: 1200, overrideReportTitle: null, hyperlinks: Dialog_InfoCard.DefsToHyperlinks(list2)); - } - if (!equippedStatOffsets.NullOrEmpty()) - { - for (int i = 0; i < equippedStatOffsets.Count; i++) - { - StatDef stat = equippedStatOffsets[i].stat; - float num8 = equippedStatOffsets[i].value; - StringBuilder stringBuilder7 = new StringBuilder(stat.description); - if (req.HasThing && stat.Worker != null) - { - stringBuilder7.AppendLine(); - stringBuilder7.AppendLine(); - stringBuilder7.AppendLine("StatsReport_BaseValue".Translate() + ": " + stat.ValueToString(num8, ToStringNumberSense.Offset, stat.finalizeEquippedStatOffset)); - num8 = StatWorker.StatOffsetFromGear(req.Thing, stat); - if (!stat.parts.NullOrEmpty()) - { - stringBuilder7.AppendLine(); - for (int k = 0; k < stat.parts.Count; k++) - { - string text = stat.parts[k].ExplanationPart(req); - if (!text.NullOrEmpty()) - { - stringBuilder7.AppendLine(text); - } - } - } - stringBuilder7.AppendLine(); - stringBuilder7.AppendLine("StatsReport_FinalValue".Translate() + ": " + stat.ValueToString(num8, ToStringNumberSense.Offset, !stat.formatString.NullOrEmpty())); - } - yield return new StatDrawEntry(StatCategoryDefOf.EquippedStatOffsets, equippedStatOffsets[i].stat, num8, StatRequest.ForEmpty(), ToStringNumberSense.Offset, null, forceUnfinalizedMode: true).SetReportText(stringBuilder7.ToString()); - } - } - if (!IsDrug) - { - yield break; - } - foreach (StatDrawEntry item9 in DrugStatsUtility.SpecialDisplayStats(this)) - { - yield return item9; - } - } -} -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\Core\Defs\ThingDefs_Races\Races_Animal_Insect.xml` -**相似度:** 0.5880 - -```xml - - insect - - 1 - 1 - 60 - 0.8 - - - Insect - InsectConstant - Insectoid - Filth_BloodInsect - (160,168,139) - 0.5 - OmnivoreAnimal, AnimalProduct - 0.50 - Insectoid_Eat - false - - - -
  • InsectMeat
  • -
    -
    - true - -
  • - -
  • Food
  • - - -
  • - true - false -
  • -
    -
    -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\Core\Defs\ThingDefs_Items\Items_Luxury.xml` -**相似度:** 0.5741 - -```xml - - Chocolate - - A delicious preparation of cocoa seeds ground together with sugar and vanilla. It fulfills the need for recreation, but it is not very nutritious. - - Things/Item/Resource/Chocolate - Graphic_StackCount - 0.88 - - Standard_Drop - Standard_Drop - true - - 60 - 3 - 0.075 - 1.0 - 8 - 0.1 - - -
  • Foods
  • -
    - - DesperateOnly - Processed - 0.10 - Gluttonous - 4 - 4 - Meal_Eat - - 80 - 10 -
    -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\CompMechGestatorTank.txt` -**相似度:** 0.5175 - -```csharp -public class CompMechGestatorTank : ThingComp, IThingGlower -{ - public enum TankState - { - Empty, - Dormant, - Proximity - } - - private TankState state; - - private float triggerRadius; - - private const int StunTicks = 180; - - private static readonly IntRange GestationFluidFilthRange = new IntRange(2, 4); - - private CompProperties_MechGestatorTank Props => (CompProperties_MechGestatorTank)props; - - public TankState State - { - get - { - return state; - } - set - { - state = value; - if (parent.Spawned) - { - parent.DirtyMapMesh(parent.Map); - parent.TryGetComp()?.UpdateLit(parent.Map); - } - } - } - - public override string CompInspectStringExtra() - { - return string.Format("{0}: {1}", "Contains".Translate(), ((state == TankState.Empty) ? "Nothing" : "Unknown").Translate().CapitalizeFirst()); - } - - public bool ShouldBeLitNow() - { - return state != TankState.Empty; - } - - public override bool DontDrawParent() - { - return true; - } - - public override void PostPostMake() - { - triggerRadius = Props.triggerRadiusRange.RandomInRange; - } - - public override void CompTick() - { - if (state == TankState.Proximity && parent.IsHashIntervalTick(250)) - { - CheckTrigger(); - } - } - - private void CheckTrigger() - { - if (!parent.Spawned) - { - return; - } - foreach (IntVec3 item in GenRadial.RadialCellsAround(parent.Position, triggerRadius, useCenter: false)) - { - if (!item.InBounds(parent.Map) || !GenSight.LineOfSight(parent.Position, item, parent.Map)) - { - continue; - } - foreach (Thing thing in item.GetThingList(parent.Map)) - { - if (thing is Pawn { IsColonist: not false }) - { - Trigger(parent.Map); - return; - } - } - } - } - - public override void PostDestroy(DestroyMode mode, Map previousMap) - { - if (mode != DestroyMode.WillReplace && state != 0) - { - Trigger(previousMap); - } - } - - private void Trigger(Map map) - { - if (state == TankState.Empty) - { - return; - } - State = TankState.Empty; - IntVec3 loc = parent.OccupiedRect().ExpandedBy(1).EdgeCells.Where(Standable).RandomElementWithFallback(IntVec3.Invalid); - ScatterDebrisUtility.ScatterFilthAroundThing(parent, map, ThingDefOf.Filth_GestationFluid, GestationFluidFilthRange); - if (loc.IsValid) - { - Pawn pawn = PawnGenerator.GeneratePawn(Props.mechKindOptions.RandomElementByWeight((PawnKindDefWeight x) => x.weight).kindDef, Faction.OfMechanoids); - GenSpawn.Spawn(pawn, loc, map); - pawn.stances?.stunner?.StunFor(180, null, addBattleLog: false); - if (!map.lordManager.TryGetLordByJob(Faction.OfMechanoids, out var lord)) - { - LordMaker.MakeNewLord(Faction.OfMechanoids, new LordJob_AssaultColony(Faction.OfMechanoids, canKidnap: false, canTimeoutOrFlee: false, sappers: false, useAvoidGridSmart: false, canSteal: false), map, new List { pawn }); - } - else - { - lord.lord.AddPawn(pawn); - } - Messages.Message(Props.triggeredMessage.Formatted(pawn), pawn, MessageTypeDefOf.NegativeEvent); - Props.triggerSound.PlayOneShot(parent); - } - bool Standable(IntVec3 c) - { - return c.Standable(map); - } - } - - public override IEnumerable CompGetGizmosExtra() - { - if (!DebugSettings.ShowDevGizmos) - { - yield break; - } - if (State == TankState.Empty) - { - Command_Action command_Action = new Command_Action(); - command_Action.defaultLabel = "DEV: Add mech"; - command_Action.action = delegate - { - State = TankState.Proximity; - }; - yield return command_Action; - } - else - { - Command_Action command_Action2 = new Command_Action(); - command_Action2.defaultLabel = "DEV: Remove mech"; - command_Action2.action = delegate - { - State = TankState.Empty; - }; - yield return command_Action2; - } - } - - public override void PostPrintOnto(SectionLayer layer) - { - ((state == TankState.Empty) ? Props.emptyGraphic.Graphic : Props.dormantGraphic.Graphic).Print(layer, parent, 0f); - } - - public override void PostExposeData() - { - Scribe_Values.Look(ref state, "state", TankState.Empty); - Scribe_Values.Look(ref triggerRadius, "triggerRadius", 0f); - } -} -``` \ No newline at end of file diff --git a/MCP/vector_cache/HumanlikeAdult-LifeStageDef.txt b/MCP/vector_cache/HumanlikeAdult-LifeStageDef.txt deleted file mode 100644 index 34ab74a1..00000000 --- a/MCP/vector_cache/HumanlikeAdult-LifeStageDef.txt +++ /dev/null @@ -1,134 +0,0 @@ -根据向量相似度分析,与 'LifeStageDef, HumanlikeAdult' 最相关的代码定义如下: - ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\LifeStageDefOf.txt` -**相似度:** 0.7850 - -```csharp -public static class LifeStageDefOf -{ - public static LifeStageDef HumanlikeBaby; - - public static LifeStageDef HumanlikeChild; - - public static LifeStageDef HumanlikeAdult; -} -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\Core\Defs\Misc\LifeStageDefs\LifeStages.xml` -**相似度:** 0.7399 - -```xml - - MechanoidFullyFormed - - false - -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\Core\Defs\Misc\LifeStageDefs\LifeStages.xml` -**相似度:** 0.7399 - -```xml - HumanlikeTeenager - - LifeStageWorker_HumanlikeAdult - teenage - true - 0.8 - 0.90 - 1.25 - 0.75 - 0.65 - 0.23 - - Things/Pawn/Humanlike/Silhouettes/Silhouette_HumanChild - Graphic_Single - 1 - - - 0.95 - - - - - HumanlikeAdult -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\LifeStageWorker_HumanlikeAdult.txt` -**相似度:** 0.7169 - -```csharp -public class LifeStageWorker_HumanlikeAdult : LifeStageWorker -{ - public const int VatGrowBackstoryTicks = 1200000; - - private static readonly List VatgrowBackstoryFilter = new List - { - new BackstoryCategoryFilter - { - categories = new List { "VatGrown" } - } - }; - - private static readonly List BackstoryFiltersTribal = new List - { - new BackstoryCategoryFilter - { - categories = new List { "AdultTribal" } - } - }; - - private static readonly List BackstoryFiltersColonist = new List - { - new BackstoryCategoryFilter - { - categories = new List { "AdultColonist" } - } - }; - - public override void Notify_LifeStageStarted(Pawn pawn, LifeStageDef previousLifeStage) - { - base.Notify_LifeStageStarted(pawn, previousLifeStage); - if (Current.ProgramState != ProgramState.Playing) - { - return; - } - if (pawn.Spawned && previousLifeStage != null && previousLifeStage.developmentalStage.Juvenile()) - { - EffecterDefOf.Birthday.SpawnAttached(pawn, pawn.Map); - } - if (pawn.story.bodyType == BodyTypeDefOf.Child || pawn.story.bodyType == BodyTypeDefOf.Baby) - { - pawn.apparel?.DropAllOrMoveAllToInventory((Apparel apparel) => !apparel.def.apparel.developmentalStageFilter.Has(DevelopmentalStage.Adult)); - BodyTypeDef bodyTypeFor = PawnGenerator.GetBodyTypeFor(pawn); - pawn.story.bodyType = bodyTypeFor; - pawn.Drawer.renderer.SetAllGraphicsDirty(); - } - if (!pawn.IsColonist) - { - return; - } - List backstoryCategories = ((Faction.OfPlayer.def == FactionDefOf.PlayerTribe) ? BackstoryFiltersTribal : BackstoryFiltersColonist); - if (previousLifeStage.developmentalStage.Juvenile()) - { - if (pawn.ageTracker.vatGrowTicks >= 1200000) - { - PawnBioAndNameGenerator.FillBackstorySlotShuffled(pawn, BackstorySlot.Childhood, VatgrowBackstoryFilter, pawn.Faction?.def); - } - else - { - BackstoryDef backstory = pawn.story.GetBackstory(BackstorySlot.Childhood); - if (backstory != null && backstory.IsPlayerColonyChildBackstory) - { - PawnBioAndNameGenerator.FillBackstorySlotShuffled(pawn, BackstorySlot.Childhood, backstoryCategories, pawn.Faction?.def); - } - } - } - if (pawn.story.GetBackstory(BackstorySlot.Adulthood) == null) - { - PawnBioAndNameGenerator.FillBackstorySlotShuffled(pawn, BackstorySlot.Adulthood, backstoryCategories, pawn.Faction?.def); - } - } -} -``` \ No newline at end of file diff --git a/MCP/vector_cache/JobDef.txt b/MCP/vector_cache/JobDef.txt deleted file mode 100644 index d78f8d6d..00000000 --- a/MCP/vector_cache/JobDef.txt +++ /dev/null @@ -1,115 +0,0 @@ -根据向量相似度分析,与 'JobDef' 最相关的代码定义如下: - ---- -**文件路径 (精确匹配):** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\Verse\JobDef.txt` - -```csharp -public class JobDef : Def -{ - public Type driverClass; - - [MustTranslate] - public string reportString = "Doing something."; - - public bool playerInterruptible = true; - - public bool forceCompleteBeforeNextJob; - - public CheckJobOverrideOnDamageMode checkOverrideOnDamage = CheckJobOverrideOnDamageMode.Always; - - public bool alwaysShowWeapon; - - public bool neverShowWeapon; - - public bool suspendable = true; - - public bool casualInterruptible = true; - - public bool allowOpportunisticPrefix; - - public bool collideWithPawns; - - public bool isIdle; - - public TaleDef taleOnCompletion; - - public bool neverFleeFromEnemies; - - public bool sleepCanInterrupt = true; - - public bool makeTargetPrisoner; - - public int waitAfterArriving; - - public bool carryThingAfterJob; - - public bool dropThingBeforeJob = true; - - public bool isCrawlingIfDowned = true; - - public bool alwaysShowReport; - - public bool abilityCasting; - - public bool tryStartFlying; - - public bool ifFlyingKeepFlying; - - public float overrideFlyChance = -1f; - - public bool displayAsAreaInFloatMenu = true; - - public int joyDuration = 4000; - - public int joyMaxParticipants = 1; - - public float joyGainRate = 1f; - - public SkillDef joySkill; - - public float joyXpPerTick; - - public JoyKindDef joyKind; - - public Rot4 faceDir = Rot4.Invalid; - - public int learningDuration = 20000; - - public ReservationLayerDef containerReservationLayer; - - public override IEnumerable ConfigErrors() - { - foreach (string item in base.ConfigErrors()) - { - yield return item; - } - if (joySkill != null && joyXpPerTick == 0f) - { - yield return "funSkill is not null but funXpPerTick is zero"; - } - } -} -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\Core\Defs\JobDefs\Jobs_Animal.xml` -**相似度:** 0.5912 - -```xml - - Nuzzle - JobDriver_Nuzzle - nuzzling TargetA. - true - -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\Ideology\Defs\JobDefs\Jobs_Gatherings.xml` -**相似度:** 0.5788 - -```xml - - Dance - JobDriver_Dance - dancing. - -``` \ No newline at end of file diff --git a/MCP/vector_cache/JobDefOf-JobDriver_TakeToBed-Rescue.txt b/MCP/vector_cache/JobDefOf-JobDriver_TakeToBed-Rescue.txt deleted file mode 100644 index c09c600b..00000000 --- a/MCP/vector_cache/JobDefOf-JobDriver_TakeToBed-Rescue.txt +++ /dev/null @@ -1,827 +0,0 @@ -根据向量相似度分析,与 'JobDriver_TakeToBed, Rescue, JobDefOf' 最相关的代码定义如下: - ---- -**文件路径 (精确匹配):** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\JobDriver_TakeToBed.txt` - -```csharp -public class JobDriver_TakeToBed : JobDriver -{ - private const TargetIndex TakeeIndex = TargetIndex.A; - - private const TargetIndex BedIndex = TargetIndex.B; - - protected Pawn Takee => (Pawn)job.GetTarget(TargetIndex.A).Thing; - - protected Building_Bed DropBed => (Building_Bed)job.GetTarget(TargetIndex.B).Thing; - - private bool TakeeRescued - { - get - { - if (Takee.RaceProps.Humanlike && job.def != JobDefOf.Arrest && !Takee.IsPrisonerOfColony) - { - if (Takee.ageTracker.CurLifeStage.alwaysDowned) - { - return HealthAIUtility.ShouldSeekMedicalRest(Takee); - } - return true; - } - return false; - } - } - - public override string GetReport() - { - if (job.def == JobDefOf.Rescue && !TakeeRescued) - { - return "TakingToBed".Translate(Takee); - } - return base.GetReport(); - } - - public override bool TryMakePreToilReservations(bool errorOnFailed) - { - Takee.ClearAllReservations(); - if (pawn.Reserve(Takee, job, 1, -1, null, errorOnFailed)) - { - return pawn.Reserve(DropBed, job, DropBed.SleepingSlotsCount, 0, null, errorOnFailed); - } - return false; - } - - protected override IEnumerable MakeNewToils() - { - this.FailOnDestroyedOrNull(TargetIndex.A); - this.FailOnDestroyedOrNull(TargetIndex.B); - this.FailOnAggroMentalStateAndHostile(TargetIndex.A); - this.FailOn(delegate - { - if (job.def.makeTargetPrisoner) - { - if (!DropBed.ForPrisoners) - { - return true; - } - } - else if (DropBed.ForPrisoners != Takee.IsPrisoner) - { - return true; - } - return false; - }); - yield return Toils_Bed.ClaimBedIfNonMedical(TargetIndex.B, TargetIndex.A); - AddFinishAction(delegate - { - if (job.def.makeTargetPrisoner && Takee.ownership.OwnedBed == DropBed && Takee.Position != RestUtility.GetBedSleepingSlotPosFor(Takee, DropBed)) - { - Takee.ownership.UnclaimBed(); - } - if (pawn.carryTracker.CarriedThing != null) - { - pawn.carryTracker.TryDropCarriedThing(pawn.Position, ThingPlaceMode.Direct, out var _); - } - }); - Toil goToTakee = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(TargetIndex.A).FailOnDespawnedNullOrForbidden(TargetIndex.B) - .FailOn(() => job.def == JobDefOf.Arrest && !Takee.CanBeArrestedBy(pawn)) - .FailOn(() => !pawn.CanReach(DropBed, PathEndMode.OnCell, Danger.Deadly)) - .FailOn(() => (job.def == JobDefOf.Rescue || job.def == JobDefOf.Capture) && !Takee.Downed) - .FailOnSomeonePhysicallyInteracting(TargetIndex.A); - Toil checkArrestResistance = ToilMaker.MakeToil("MakeNewToils"); - checkArrestResistance.initAction = delegate - { - if (job.def.makeTargetPrisoner) - { - Pawn pawn = (Pawn)job.targetA.Thing; - pawn.GetLord()?.Notify_PawnAttemptArrested(pawn); - GenClamor.DoClamor(pawn, 10f, ClamorDefOf.Harm); - if (!pawn.IsPrisoner && !pawn.IsSlave) - { - QuestUtility.SendQuestTargetSignals(pawn.questTags, "Arrested", pawn.Named("SUBJECT")); - if (pawn.Faction != null) - { - QuestUtility.SendQuestTargetSignals(pawn.Faction.questTags, "FactionMemberArrested", pawn.Faction.Named("FACTION")); - } - } - if (job.def == JobDefOf.Arrest && !pawn.CheckAcceptArrest(base.pawn)) - { - base.pawn.jobs.EndCurrentJob(JobCondition.Incompletable); - } - } - }; - yield return Toils_Jump.JumpIf(checkArrestResistance, () => pawn.IsCarryingPawn(Takee)); - yield return goToTakee; - yield return checkArrestResistance; - Toil startCarrying = Toils_Haul.StartCarryThing(TargetIndex.A); - startCarrying.FailOnBedNoLongerUsable(TargetIndex.B, TargetIndex.A); - startCarrying.AddPreInitAction(CheckMakeTakeeGuest); - startCarrying.AddFinishAction(delegate - { - if (pawn.Faction == Takee.Faction) - { - CheckMakeTakeePrisoner(); - } - }); - Toil goToBed = Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.Touch).FailOn(() => !pawn.IsCarryingPawn(Takee)); - goToBed.FailOnBedNoLongerUsable(TargetIndex.B, TargetIndex.A); - yield return Toils_Jump.JumpIf(goToBed, () => pawn.IsCarryingPawn(Takee)); - yield return startCarrying; - yield return goToBed; - Toil toil = ToilMaker.MakeToil("MakeNewToils"); - toil.initAction = delegate - { - CheckMakeTakeePrisoner(); - if (Takee.playerSettings == null) - { - Takee.playerSettings = new Pawn_PlayerSettings(Takee); - } - }; - yield return toil; - yield return Toils_Reserve.Release(TargetIndex.B); - yield return Toils_Bed.TuckIntoBed(DropBed, pawn, Takee, TakeeRescued); - yield return Toils_General.Do(delegate - { - if (!job.ritualTag.NullOrEmpty()) - { - if (Takee.GetLord()?.LordJob is LordJob_Ritual lordJob_Ritual) - { - lordJob_Ritual.AddTagForPawn(Takee, job.ritualTag); - } - if (pawn.GetLord()?.LordJob is LordJob_Ritual lordJob_Ritual2) - { - lordJob_Ritual2.AddTagForPawn(pawn, job.ritualTag); - } - } - }); - } - - private void CheckMakeTakeePrisoner() - { - if (job.def.makeTargetPrisoner) - { - if (Takee.guest.Released) - { - Takee.guest.Released = false; - Takee.guest.SetExclusiveInteraction(PrisonerInteractionModeDefOf.MaintainOnly); - GenGuest.RemoveHealthyPrisonerReleasedThoughts(Takee); - } - if (!Takee.IsPrisonerOfColony) - { - Takee.guest.CapturedBy(Faction.OfPlayer, pawn); - } - } - } - - private void CheckMakeTakeeGuest() - { - if (!job.def.makeTargetPrisoner && Takee.Faction != Faction.OfPlayer && Takee.HostFaction != Faction.OfPlayer && Takee.guest != null && !Takee.IsWildMan() && Takee.DevelopmentalStage != DevelopmentalStage.Baby) - { - Takee.guest.SetGuestStatus(Faction.OfPlayer); - QuestUtility.SendQuestTargetSignals(Takee.questTags, "Rescued", Takee.Named("SUBJECT")); - } - } -} -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\Core\Defs\JobDefs\Jobs_Work.xml` -**相似度:** 0.6607 - -```xml - Rescue - JobDriver_TakeToBed - rescuing TargetA. - false - true - false -
    - - - CarryToCryptosleepCasket -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\Core\Defs\JobDefs\Jobs_Misc.xml` -**相似度:** 0.6320 - -```xml - DeliverToBed - JobDriver_TakeToBed - delivering TargetA. - false - - - - TakeCountToInventory -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\RestUtility.txt` -**相似度:** 0.5085 - -```csharp -public static class RestUtility -{ - public const int NoSleepingDurationAfterBeingDisturbed = 400; - - private static List bedDefsBestToWorst_RestEffectiveness; - - private static List bedDefsBestToWorst_Medical; - - private static List bedDefsBestToWorst_SlabBed_RestEffectiveness; - - private static List bedDefsBestToWorst_SlabBed_Medical; - - public static List AllBedDefBestToWorst => bedDefsBestToWorst_RestEffectiveness; - - public static void Reset() - { - bedDefsBestToWorst_RestEffectiveness = (from d in DefDatabase.AllDefs - where d.IsBed - orderby d.building.bed_maxBodySize, d.GetStatValueAbstract(StatDefOf.BedRestEffectiveness) descending - select d).ToList(); - bedDefsBestToWorst_SlabBed_RestEffectiveness = (from d in DefDatabase.AllDefs - where d.IsBed - orderby (!d.building.bed_slabBed) ? 1 : 0, d.building.bed_maxBodySize, d.GetStatValueAbstract(StatDefOf.BedRestEffectiveness) descending - select d).ToList(); - bedDefsBestToWorst_Medical = (from d in DefDatabase.AllDefs - where d.IsBed - orderby d.building.bed_maxBodySize, d.GetStatValueAbstract(StatDefOf.MedicalTendQualityOffset) descending, d.GetStatValueAbstract(StatDefOf.BedRestEffectiveness) descending - select d).ToList(); - bedDefsBestToWorst_SlabBed_Medical = (from d in DefDatabase.AllDefs - where d.IsBed - orderby (!d.building.bed_slabBed) ? 1 : 0, d.building.bed_maxBodySize, d.GetStatValueAbstract(StatDefOf.MedicalTendQualityOffset) descending, d.GetStatValueAbstract(StatDefOf.BedRestEffectiveness) descending - select d).ToList(); - } - - public static bool BedOwnerWillShare(Building_Bed bed, Pawn sleeper, GuestStatus? guestStatus) - { - if (!bed.OwnersForReading.Any()) - { - return true; - } - if (sleeper.IsPrisoner || guestStatus == GuestStatus.Prisoner || sleeper.IsSlave || guestStatus == GuestStatus.Slave) - { - if (!bed.AnyUnownedSleepingSlot) - { - return false; - } - } - else - { - if (!bed.AnyUnownedSleepingSlot) - { - return false; - } - if (!IsAnyOwnerLovePartnerOf(bed, sleeper)) - { - return false; - } - } - return true; - } - - public static bool CanUseBedNow(Thing bedThing, Pawn sleeper, bool checkSocialProperness, bool allowMedBedEvenIfSetToNoCare = false, GuestStatus? guestStatusOverride = null) - { - if (!(bedThing is Building_Bed building_Bed)) - { - return false; - } - if (!building_Bed.Spawned) - { - return false; - } - if (building_Bed.Map != sleeper.MapHeld) - { - return false; - } - if (building_Bed.IsBurning()) - { - return false; - } - if (sleeper.HarmedByVacuum && building_Bed.Position.GetVacuum(bedThing.Map) >= 0.5f) - { - return false; - } - if (!CanUseBedEver(sleeper, building_Bed.def)) - { - return false; - } - if (building_Bed.CompAssignableToPawn.IdeoligionForbids(sleeper)) - { - return false; - } - int? assignedSleepingSlot; - bool flag = building_Bed.IsOwner(sleeper, out assignedSleepingSlot); - int? sleepingSlot; - bool flag2 = sleeper.CurrentBed(out sleepingSlot) == building_Bed; - if (!building_Bed.AnyUnoccupiedSleepingSlot && !flag && !flag2) - { - return false; - } - GuestStatus? obj = guestStatusOverride ?? sleeper.GuestStatus; - bool flag3 = obj == GuestStatus.Prisoner; - bool flag4 = obj == GuestStatus.Slave; - if (checkSocialProperness && !building_Bed.IsSociallyProper(sleeper, flag3)) - { - return false; - } - if (building_Bed.ForPrisoners != flag3) - { - return false; - } - if (building_Bed.ForSlaves != flag4) - { - return false; - } - if (building_Bed.ForPrisoners && !building_Bed.Position.IsInPrisonCell(building_Bed.Map)) - { - return false; - } - if (building_Bed.Medical) - { - if (!allowMedBedEvenIfSetToNoCare && !HealthAIUtility.ShouldEverReceiveMedicalCareFromPlayer(sleeper)) - { - return false; - } - if (!HealthAIUtility.ShouldSeekMedicalRest(sleeper)) - { - return false; - } - } - else - { - if (!flag && !BedOwnerWillShare(building_Bed, sleeper, guestStatusOverride)) - { - return false; - } - if (flag2 && sleepingSlot != assignedSleepingSlot) - { - return false; - } - } - if (sleeper.IsColonist && !flag3) - { - Job curJob = sleeper.CurJob; - if ((curJob == null || !curJob.ignoreForbidden) && !sleeper.Downed && building_Bed.IsForbidden(sleeper)) - { - return false; - } - } - return true; - } - - public static bool IsValidBedFor(Thing bedThing, Pawn sleeper, Pawn traveler, bool checkSocialProperness, bool allowMedBedEvenIfSetToNoCare = false, bool ignoreOtherReservations = false, GuestStatus? guestStatus = null) - { - if (!CanUseBedNow(bedThing, sleeper, checkSocialProperness, allowMedBedEvenIfSetToNoCare, guestStatus)) - { - return false; - } - Building_Bed building_Bed = (Building_Bed)bedThing; - if (!traveler.CanReach(building_Bed, PathEndMode.OnCell, Danger.Some)) - { - return false; - } - if (!sleeper.HasReserved(building_Bed) && !traveler.CanReserve(building_Bed, building_Bed.SleepingSlotsCount, 0, null, ignoreOtherReservations)) - { - return false; - } - if (traveler.HasReserved(building_Bed, sleeper)) - { - return false; - } - if (building_Bed.IsForbidden(traveler)) - { - return false; - } - bool num = guestStatus == GuestStatus.Prisoner; - bool flag = guestStatus == GuestStatus.Slave; - if (!num && !flag && building_Bed.Faction != traveler.Faction && (traveler.HostFaction == null || building_Bed.Faction != traveler.HostFaction)) - { - return false; - } - if (ModsConfig.AnomalyActive && sleeper.IsMutant && sleeper.needs.rest == null && sleeper.mutant.Def.entitledToMedicalCare && !building_Bed.Medical) - { - return false; - } - return true; - } - - public static void TuckIntoBed(Building_Bed bed, Pawn taker, Pawn takee, bool rescued) - { - IntVec3 position = bed.Position; - if (taker != takee) - { - taker.carryTracker.TryDropCarriedThing(position, ThingPlaceMode.Direct, out var _); - } - if (CanUseBedNow(bed, takee, checkSocialProperness: false)) - { - takee.jobs.Notify_TuckedIntoBed(bed); - if (taker != takee && rescued) - { - takee.relations.Notify_RescuedBy(taker); - } - takee.mindState.Notify_TuckedIntoBed(); - } - if (takee.IsPrisonerOfColony) - { - LessonAutoActivator.TeachOpportunity(ConceptDefOf.PrisonerTab, takee, OpportunityType.GoodToKnow); - } - } - - private static bool IsAnyOwnerLovePartnerOf(Building_Bed bed, Pawn sleeper) - { - for (int i = 0; i < bed.OwnersForReading.Count; i++) - { - if (LovePartnerRelationUtility.LovePartnerRelationExists(sleeper, bed.OwnersForReading[i])) - { - return true; - } - } - return false; - } - - public static Building_Bed FindBedFor(Pawn p) - { - return FindBedFor(p, p, checkSocialProperness: true, ignoreOtherReservations: false, p.GuestStatus); - } - - public static Building_Bed FindBedFor(Pawn sleeper, Pawn traveler, bool checkSocialProperness, bool ignoreOtherReservations = false, GuestStatus? guestStatus = null) - { - if (sleeper.RaceProps.IsMechanoid) - { - return null; - } - if (ModsConfig.BiotechActive && sleeper.Deathresting) - { - Building_Bed assignedDeathrestCasket = sleeper.ownership.AssignedDeathrestCasket; - if (assignedDeathrestCasket != null && IsValidBedFor(assignedDeathrestCasket, sleeper, traveler, checkSocialProperness: true)) - { - CompDeathrestBindable compDeathrestBindable = assignedDeathrestCasket.TryGetComp(); - if (compDeathrestBindable != null && (compDeathrestBindable.BoundPawn == sleeper || compDeathrestBindable.BoundPawn == null)) - { - return assignedDeathrestCasket; - } - } - } - bool flag = false; - if (sleeper.Ideo != null) - { - foreach (Precept item in sleeper.Ideo.PreceptsListForReading) - { - if (item.def.prefersSlabBed) - { - flag = true; - break; - } - } - } - List list = (flag ? bedDefsBestToWorst_SlabBed_Medical : bedDefsBestToWorst_Medical); - List list2 = (flag ? bedDefsBestToWorst_SlabBed_RestEffectiveness : bedDefsBestToWorst_RestEffectiveness); - if (HealthAIUtility.ShouldSeekMedicalRest(sleeper)) - { - if (sleeper.InBed() && sleeper.CurrentBed().Medical && IsValidBedFor(sleeper.CurrentBed(), sleeper, traveler, checkSocialProperness, allowMedBedEvenIfSetToNoCare: false, ignoreOtherReservations, guestStatus)) - { - return sleeper.CurrentBed(); - } - for (int i = 0; i < list.Count; i++) - { - ThingDef thingDef = list[i]; - if (!CanUseBedEver(sleeper, thingDef)) - { - continue; - } - for (int j = 0; j < 2; j++) - { - Danger maxDanger = ((j == 0) ? Danger.None : Danger.Deadly); - Building_Bed building_Bed = (Building_Bed)GenClosest.ClosestThingReachable(sleeper.Position, sleeper.MapHeld, ThingRequest.ForDef(thingDef), PathEndMode.OnCell, TraverseParms.For(traveler), 9999f, (Thing b) => ((Building_Bed)b).Medical && (int)b.Position.GetDangerFor(sleeper, sleeper.Map) <= (int)maxDanger && IsValidBedFor(b, sleeper, traveler, checkSocialProperness, allowMedBedEvenIfSetToNoCare: false, ignoreOtherReservations, guestStatus)); - if (building_Bed != null) - { - return building_Bed; - } - } - } - } - if (sleeper.RaceProps.Dryad) - { - return null; - } - if (sleeper.ownership != null && sleeper.ownership.OwnedBed != null && IsValidBedFor(sleeper.ownership.OwnedBed, sleeper, traveler, checkSocialProperness, allowMedBedEvenIfSetToNoCare: false, ignoreOtherReservations, guestStatus)) - { - return sleeper.ownership.OwnedBed; - } - DirectPawnRelation directPawnRelation = LovePartnerRelationUtility.ExistingMostLikedLovePartnerRel(sleeper, allowDead: false); - if (directPawnRelation != null) - { - Building_Bed ownedBed = directPawnRelation.otherPawn.ownership.OwnedBed; - if (ownedBed != null && IsValidBedFor(ownedBed, sleeper, traveler, checkSocialProperness, allowMedBedEvenIfSetToNoCare: false, ignoreOtherReservations, guestStatus)) - { - return ownedBed; - } - } - for (int dg = 0; dg < 3; dg++) - { - Danger maxDanger = ((dg <= 1) ? Danger.None : Danger.Deadly); - for (int k = 0; k < list2.Count; k++) - { - ThingDef thingDef2 = list2[k]; - if (!CanUseBedEver(sleeper, thingDef2)) - { - continue; - } - Building_Bed building_Bed2 = (Building_Bed)GenClosest.ClosestThingReachable(sleeper.PositionHeld, sleeper.MapHeld, ThingRequest.ForDef(thingDef2), PathEndMode.OnCell, TraverseParms.For(traveler), 9999f, (Thing b) => !((Building_Bed)b).Medical && (int)b.Position.GetDangerFor(sleeper, sleeper.MapHeld) <= (int)maxDanger && IsValidBedFor(b, sleeper, traveler, checkSocialProperness, allowMedBedEvenIfSetToNoCare: false, ignoreOtherReservations, guestStatus) && (dg > 0 || !b.Position.GetItems(b.Map).Any((Thing thing) => thing.def.IsCorpse))); - if (building_Bed2 != null) - { - return building_Bed2; - } - } - } - return null; - } - - public static Building_Bed FindPatientBedFor(Pawn pawn) - { - Predicate medBedValidator = delegate(Thing t) - { - if (!(t is Building_Bed building_Bed2)) - { - return false; - } - if (!building_Bed2.Medical) - { - return false; - } - return IsValidBedFor(building_Bed2, pawn, pawn, checkSocialProperness: false, allowMedBedEvenIfSetToNoCare: true, ignoreOtherReservations: false, pawn.GuestStatus) ? true : false; - }; - if (pawn.InBed() && medBedValidator(pawn.CurrentBed())) - { - return pawn.CurrentBed(); - } - for (int i = 0; i < 2; i++) - { - Danger maxDanger = ((i == 0) ? Danger.None : Danger.Deadly); - Building_Bed building_Bed = (Building_Bed)GenClosest.ClosestThingReachable(pawn.Position, pawn.Map, ThingRequest.ForGroup(ThingRequestGroup.Bed), PathEndMode.OnCell, TraverseParms.For(pawn), 9999f, (Thing b) => (int)b.Position.GetDangerFor(pawn, pawn.Map) <= (int)maxDanger && medBedValidator(b)); - if (building_Bed != null) - { - return building_Bed; - } - } - return FindBedFor(pawn); - } - - public static IntVec3 GetBedSleepingSlotPosFor(Pawn pawn, Building_Bed bed) - { - if (bed.IsOwner(pawn, out var assignedSleepingSlot)) - { - return bed.GetSleepingSlotPos(assignedSleepingSlot.Value); - } - for (int i = 0; i < bed.SleepingSlotsCount; i++) - { - Pawn curOccupant = bed.GetCurOccupant(i); - if ((i >= bed.OwnersForReading.Count || bed.OwnersForReading[i] == null) && curOccupant == pawn) - { - return bed.GetSleepingSlotPos(i); - } - } - for (int j = 0; j < bed.SleepingSlotsCount; j++) - { - Pawn curOccupant2 = bed.GetCurOccupant(j); - if ((j >= bed.OwnersForReading.Count || bed.OwnersForReading[j] == null) && curOccupant2 == null) - { - return bed.GetSleepingSlotPos(j); - } - } - Log.Error("Could not find good sleeping slot position for " + pawn?.ToString() + ". Perhaps AnyUnoccupiedSleepingSlot check is missing somewhere."); - return bed.GetSleepingSlotPos(0); - } - - public static void KickOutOfBed(Pawn pawn, Building_Bed bed) - { - if (pawn == null) - { - return; - } - if (!pawn.Spawned) - { - Log.Error("Tried to kick unspawned pawn " + pawn.ToStringSafe() + " out of bed."); - } - if (!pawn.Dead && !pawn.GetPosture().InBed()) - { - Log.Error("Tried to kick pawn " + pawn.ToStringSafe() + " out of bed when they weren't in bed."); - } - int? sleepingSlot; - Building_Bed building_Bed = pawn.CurrentBed(out sleepingSlot); - if (building_Bed != bed) - { - if (building_Bed == null) - { - bed = null; - } - else - { - Log.Error("Tried to kick pawn " + pawn.ToStringSafe() + " out of a bed they're not currently in."); - } - } - pawn.jobs.posture &= ~PawnPosture.InBedMask; - if (bed != null && (pawn.Downed || pawn.Deathresting)) - { - pawn.Position = bed.GetFootSlotPos(sleepingSlot.Value); - } - } - - public static bool CanUseBedEver(Pawn p, ThingDef bedDef) - { - if (p.RaceProps.IsMechanoid) - { - return false; - } - if (p.BodySize > bedDef.building.bed_maxBodySize) - { - return false; - } - if (p.RaceProps.Humanlike != bedDef.building.bed_humanlike) - { - return false; - } - if (ModsConfig.BiotechActive && bedDef == ThingDefOf.DeathrestCasket && !p.CanDeathrest()) - { - return false; - } - return true; - } - - public static bool TimetablePreventsLayDown(Pawn pawn) - { - if (pawn.timetable?.CurrentAssignment != null && !pawn.timetable.CurrentAssignment.allowRest && pawn.needs?.rest != null && pawn.needs.rest.CurLevel >= 0.2f) - { - return true; - } - return false; - } - - public static bool DisturbancePreventsLyingDown(Pawn pawn) - { - if (pawn.Downed) - { - return false; - } - return Find.TickManager.TicksGame - pawn.mindState.lastDisturbanceTick < 400; - } - - public static bool Awake(this Pawn p) - { - if (!p.health.capacities.CanBeAwake) - { - return false; - } - if (p.CurJob != null && p.jobs.curDriver != null) - { - return !p.jobs.curDriver.asleep; - } - return true; - } - - public static bool IsSelfShutdown(this Pawn p) - { - if (p.needs?.energy == null) - { - return false; - } - return p.needs.energy.IsSelfShutdown; - } - - public static bool IsDeactivated(this Pawn p) - { - return p.TryGetComp()?.Deactivated ?? false; - } - - public static bool IsActivityDormant(this Pawn p) - { - if (p.GetComp() == null) - { - return false; - } - return p.GetComp().IsActive; - } - - public static bool IsCharging(this Pawn p) - { - return p.needs?.energy?.currentCharger != null; - } - - public static Building_Bed CurrentBed(this Pawn p) - { - int? sleepingSlot; - return p.CurrentBed(out sleepingSlot); - } - - public static Building_Bed CurrentBed(this Pawn p, out int? sleepingSlot) - { - sleepingSlot = null; - if (!p.Spawned || p.CurJob == null || !p.GetPosture().InBed()) - { - return null; - } - Building_Bed building_Bed = null; - List thingList = p.Position.GetThingList(p.Map); - for (int i = 0; i < thingList.Count; i++) - { - building_Bed = thingList[i] as Building_Bed; - if (building_Bed != null) - { - break; - } - } - if (building_Bed == null) - { - return null; - } - for (int j = 0; j < building_Bed.SleepingSlotsCount; j++) - { - if (building_Bed.GetCurOccupant(j) == p) - { - sleepingSlot = j; - return building_Bed; - } - } - return null; - } - - public static bool InBed(this Pawn p) - { - return p.CurrentBed() != null; - } - - public static bool IsLayingForJobCleanup(Pawn p) - { - if (!p.InBed()) - { - if (p.CurJob != null && p.CurJob.def == JobDefOf.LayDown) - { - return p.GetPosture().Laying(); - } - return false; - } - return true; - } - - public static void WakeUp(Pawn p, bool startNewJob = true) - { - if (p.CurJob != null && (p.GetPosture().Laying() || p.CurJobDef == JobDefOf.LayDown) && !p.Downed) - { - p.jobs.EndCurrentJob(JobCondition.InterruptForced, startNewJob); - } - p.GetComp()?.WakeUp(); - if (p.mindState != null) - { - p.mindState.hibernationEndedTick = GenTicks.TicksGame; - } - } - - public static bool ShouldWakeUp(Pawn pawn) - { - if (pawn.Deathresting) - { - return false; - } - if (pawn.needs?.rest != null && !(pawn.needs.rest.CurLevel >= WakeThreshold(pawn))) - { - return pawn.health.hediffSet.HasHediffBlocksSleeping(); - } - return true; - } - - public static bool CanFallAsleep(Pawn pawn) - { - if (pawn.Deathresting) - { - return true; - } - Pawn_NeedsTracker needs = pawn.needs; - if (needs != null && needs.food?.Starving == true && !pawn.ageTracker.CurLifeStage.canSleepWhenStarving) - { - return false; - } - if (pawn.mindState != null && Find.TickManager.TicksGame - pawn.mindState.lastDisturbanceTick < 400) - { - return false; - } - if (pawn.needs?.rest?.CurLevel < FallAsleepMaxLevel(pawn) && !pawn.health.hediffSet.HasHediffBlocksSleeping()) - { - return pawn.CurJobDef?.sleepCanInterrupt ?? true; - } - return false; - } - - private static float WakeThreshold(Pawn p) - { - Lord lord = p.GetLord(); - if (lord != null && lord.CurLordToil != null && lord.CurLordToil.CustomWakeThreshold.HasValue) - { - return lord.CurLordToil.CustomWakeThreshold.Value; - } - return p.ageTracker.CurLifeStage?.naturalWakeThresholdOverride ?? 1f; - } - - private static float FallAsleepMaxLevel(Pawn p) - { - return Mathf.Min(p.ageTracker.CurLifeStage?.fallAsleepMaxThresholdOverride ?? 0.75f, WakeThreshold(p) - 0.01f); - } -} -``` \ No newline at end of file diff --git a/MCP/vector_cache/JobDriver_EnterCryptosleepCasket.txt b/MCP/vector_cache/JobDriver_EnterCryptosleepCasket.txt deleted file mode 100644 index 5166933a..00000000 --- a/MCP/vector_cache/JobDriver_EnterCryptosleepCasket.txt +++ /dev/null @@ -1,70 +0,0 @@ -根据向量相似度分析,与 'JobDriver_EnterCryptosleepCasket' 最相关的代码定义如下: - ---- -**文件路径 (精确匹配):** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\JobDriver_EnterCryptosleepCasket.txt` - -```csharp -public class JobDriver_EnterCryptosleepCasket : JobDriver -{ - public override bool TryMakePreToilReservations(bool errorOnFailed) - { - return pawn.Reserve(job.targetA, job, 1, -1, null, errorOnFailed); - } - - protected override IEnumerable MakeNewToils() - { - this.FailOnDespawnedOrNull(TargetIndex.A); - yield return Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell); - Toil toil = Toils_General.Wait(500); - toil.FailOnCannotTouch(TargetIndex.A, PathEndMode.InteractionCell); - toil.WithProgressBarToilDelay(TargetIndex.A); - yield return toil; - Toil enter = ToilMaker.MakeToil("MakeNewToils"); - _003C_003Ec__DisplayClass1_0 CS_0024_003C_003E8__locals0; - enter.initAction = delegate - { - Building_CryptosleepCasket pod = (Building_CryptosleepCasket)((Pawn)(object)CS_0024_003C_003E8__locals0).CurJob.targetA.Thing; - Action action = delegate - { - bool flag = ((Thing)(object)CS_0024_003C_003E8__locals0).DeSpawnOrDeselect(DestroyMode.Vanish); - if (pod.TryAcceptThing((Thing)(object)CS_0024_003C_003E8__locals0) && flag) - { - Find.Selector.Select(CS_0024_003C_003E8__locals0, playSound: false, forceDesignatorDeselect: false); - } - }; - if (!pod.def.building.isPlayerEjectable) - { - if (base.Map.mapPawns.FreeColonistsSpawnedOrInPlayerEjectablePodsCount <= 1) - { - Find.WindowStack.Add(Dialog_MessageBox.CreateConfirmation("CasketWarning".Translate(CS_0024_003C_003E8__locals0.Named("PAWN")).AdjustedFor((Pawn)(object)CS_0024_003C_003E8__locals0), action)); - } - else - { - action(); - } - } - else - { - action(); - } - }; - enter.defaultCompleteMode = ToilCompleteMode.Instant; - yield return enter; - } -} -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\Core\Defs\JobDefs\Jobs_Misc.xml` -**相似度:** 0.5540 - -```xml - EnterCryptosleepCasket - JobDriver_EnterCryptosleepCasket - entering cryptosleep casket. - EnteredCryptosleep - true - - - - UseNeurotrainer -``` \ No newline at end of file diff --git a/MCP/vector_cache/PawnKindDef-lifeStages.txt b/MCP/vector_cache/PawnKindDef-lifeStages.txt deleted file mode 100644 index 20e16166..00000000 --- a/MCP/vector_cache/PawnKindDef-lifeStages.txt +++ /dev/null @@ -1,535 +0,0 @@ -根据向量相似度分析,与 'PawnKindDef, lifeStages' 最相关的代码定义如下: - ---- -**文件路径 (精确匹配):** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\Verse\PawnKindDef.txt` - -```csharp -public class PawnKindDef : Def -{ - public ThingDef race; - - [LoadAlias("defaultFactionType")] - public FactionDef defaultFactionDef; - - [NoTranslate] - public List backstoryFilters; - - [NoTranslate] - public List backstoryFiltersOverride; - - [NoTranslate] - public List backstoryCategories; - - [MustTranslate] - public string labelPlural; - - public List lifeStages = new List(); - - public List alternateGraphics; - - [XmlInheritanceAllowDuplicateNodes] - public List forcedTraits; - - [XmlInheritanceAllowDuplicateNodes] - public List disallowedTraitsWithDegree; - - public List disallowedTraits; - - public float alternateGraphicChance; - - public MutantDef mutant; - - public XenotypeSet xenotypeSet; - - public bool useFactionXenotypes = true; - - [LoadAlias("hairTags")] - public List styleItemTags; - - public HairDef forcedHair; - - public Color? forcedHairColor; - - public List missingParts; - - public RulePackDef nameMaker; - - public RulePackDef nameMakerFemale; - - public List abilities; - - public bool preventIdeo; - - public bool studiableAsPrisoner; - - public bool isBoss; - - public Dictionary moveSpeedFactorByTerrainTag = new Dictionary(); - - public List fixedChildBackstories = new List(); - - public List fixedAdultBackstories = new List(); - - public float backstoryCryptosleepCommonality; - - public FloatRange? chronologicalAgeRange; - - public int minGenerationAge; - - public int maxGenerationAge = 999999; - - public bool factionLeader; - - public Gender? fixedGender; - - public bool allowOldAgeInjuries = true; - - public bool generateInitialNonFamilyRelations = true; - - public DevelopmentalStage? pawnGroupDevelopmentStage; - - public bool destroyGearOnDrop; - - public bool canStrip = true; - - public float defendPointRadius = -1f; - - public bool factionHostileOnKill; - - public bool factionHostileOnDeath; - - public bool hostileToAll; - - public FloatRange? initialResistanceRange; - - public FloatRange? initialWillRange; - - public bool forceNoDeathNotification; - - public bool skipResistant; - - public float controlGroupPortraitZoom = 1f; - - public float? overrideDeathOnDownedChance; - - public bool forceDeathOnDowned; - - public bool immuneToGameConditionEffects; - - public bool immuneToTraps; - - public bool collidesWithPawns = true; - - public bool ignoresPainShock; - - public bool canMeleeAttack = true; - - public float basePrisonBreakMtbDays = 60f; - - public bool useFixedRotation; - - public Rot4 fixedRotation; - - public bool showInDebugSpawner = true; - - public bool canOpenAnyDoor; - - public bool canOpenDoors = true; - - [NoTranslate] - public string overrideDebugActionCategory; - - public float royalTitleChance; - - public RoyalTitleDef titleRequired; - - public RoyalTitleDef minTitleRequired; - - public List titleSelectOne; - - public bool allowRoyalRoomRequirements = true; - - public bool allowRoyalApparelRequirements = true; - - public List meleeAttackInfectionPathways; - - public List rangedAttackInfectionPathways; - - public bool isFighter = true; - - public float combatPower = -1f; - - public bool canArriveManhunter = true; - - public bool canBeSapper; - - public bool isGoodBreacher; - - public bool allowInMechClusters = true; - - public int maxPerGroup = int.MaxValue; - - public bool isGoodPsychicRitualInvoker; - - public bool canBeScattered = true; - - public bool appearsRandomlyInCombatGroups = true; - - public bool aiAvoidCover; - - public FloatRange fleeHealthThresholdRange = new FloatRange(-0.4f, 0.4f); - - public float acceptArrestChanceFactor = 1f; - - public bool canUseAvoidGrid; - - public QualityCategory itemQuality = QualityCategory.Normal; - - public QualityCategory? forceWeaponQuality; - - public bool forceNormalGearQuality; - - public FloatRange gearHealthRange = FloatRange.One; - - public FloatRange weaponMoney = FloatRange.Zero; - - [NoTranslate] - public List weaponTags; - - public ThingDef weaponStuffOverride; - - public ThingStyleDef weaponStyleDef; - - public FloatRange apparelMoney = FloatRange.Zero; - - public List apparelRequired; - - [NoTranslate] - public List apparelTags; - - [NoTranslate] - public List apparelDisallowTags; - - public float apparelAllowHeadgearChance = 1f; - - public bool apparelIgnoreSeasons; - - public bool apparelIgnorePollution; - - public bool ignoreFactionApparelStuffRequirements; - - public Color apparelColor = Color.white; - - public Color? skinColorOverride; - - public ColorDef favoriteColor; - - public bool ignoreIdeoApparelColors; - - public List specificApparelRequirements; - - public List techHediffsRequired; - - public FloatRange techHediffsMoney = FloatRange.Zero; - - [NoTranslate] - public List techHediffsTags; - - [NoTranslate] - public List techHediffsDisallowTags; - - public float techHediffsChance; - - public int techHediffsMaxAmount = 1; - - public float biocodeWeaponChance; - - public float humanPregnancyChance = 0.03f; - - public List startingHediffs; - - public float nakedChance; - - public List existingDamage = new List(); - - public QualityCategory minApparelQuality; - - public QualityCategory maxApparelQuality = QualityCategory.Excellent; - - public List fixedInventory = new List(); - - public PawnInventoryOption inventoryOptions; - - public float invNutrition; - - public ThingDef invFoodDef; - - public float chemicalAddictionChance; - - public float combatEnhancingDrugsChance; - - public IntRange combatEnhancingDrugsCount = IntRange.Zero; - - public List forcedAddictions = new List(); - - public bool trader; - - public List skills; - - public WorkTags requiredWorkTags; - - public WorkTags disabledWorkTags; - - public int extraSkillLevels; - - public int minTotalSkillLevels; - - public int minBestSkillLevel; - - [MustTranslate] - public string labelMale; - - [MustTranslate] - public string labelMalePlural; - - [MustTranslate] - public string labelFemale; - - [MustTranslate] - public string labelFemalePlural; - - public IntRange wildGroupSize = IntRange.One; - - public float ecoSystemWeight = 1f; - - [NoTranslate] - public string flyingAnimationFramePathPrefix; - - [NoTranslate] - public string flyingAnimationFramePathPrefixFemale; - - public int flyingAnimationFrameCount; - - public int flyingAnimationTicksPerFrame = -1; - - public float flyingAnimationDrawSize = 1f; - - public bool flyingAnimationDrawSizeIsMultiplier; - - public bool flyingAnimationInheritColors; - - private const int MaxWeaponMoney = 999999; - - public RaceProperties RaceProps => race.race; - - public override void ResolveReferences() - { - base.ResolveReferences(); - for (int i = 0; i < lifeStages.Count; i++) - { - lifeStages[i].ResolveReferences(); - } - } - - public string GetLabelPlural(int count = -1) - { - if (!labelPlural.NullOrEmpty()) - { - return labelPlural; - } - return Find.ActiveLanguageWorker.Pluralize(label, count); - } - - public string GetLabelGendered(Gender gender) - { - if (gender == Gender.Female && !labelFemale.NullOrEmpty()) - { - return labelFemale; - } - if (gender == Gender.Male && !labelMale.NullOrEmpty()) - { - return labelMale; - } - return label; - } - - public RulePackDef GetNameMaker(Gender gender) - { - if (gender == Gender.Female && nameMakerFemale != null) - { - return nameMakerFemale; - } - if (nameMaker != null) - { - return nameMaker; - } - return null; - } - - public override void PostLoad() - { - if (backstoryCategories != null && backstoryCategories.Count > 0) - { - if (backstoryFilters == null) - { - backstoryFilters = new List(); - } - backstoryFilters.Add(new BackstoryCategoryFilter - { - categories = backstoryCategories - }); - } - LongEventHandler.ExecuteWhenFinished(delegate - { - foreach (PawnKindLifeStage lifeStage in lifeStages) - { - if (lifeStage.swimmingGraphicData != null && lifeStage.swimmingGraphicData.shaderType == null) - { - lifeStage.swimmingGraphicData.shaderType = ShaderTypeDefOf.Transparent; - } - if (lifeStage.femaleSwimmingGraphicData != null && lifeStage.femaleSwimmingGraphicData.shaderType == null) - { - lifeStage.femaleSwimmingGraphicData.shaderType = ShaderTypeDefOf.Transparent; - } - } - }); - } - - public float GetAnimalPointsToHuntOrSlaughter() - { - return combatPower * 5f * (1f + RaceProps.manhunterOnDamageChance * 0.5f) * (1f + RaceProps.manhunterOnTameFailChance * 0.2f) * (1f + race.GetStatValueAbstract(StatDefOf.Wildness)) + race.BaseMarketValue; - } - - public override IEnumerable ConfigErrors() - { - foreach (string item in base.ConfigErrors()) - { - yield return item; - } - if (backstoryFilters != null && backstoryFiltersOverride != null) - { - yield return "both backstoryCategories and backstoryCategoriesOverride are defined"; - } - if (race == null) - { - yield return "no race"; - } - if (combatPower < 0f) - { - yield return defName + " has no combatPower."; - } - if (weaponMoney != FloatRange.Zero) - { - if (weaponTags == null) - { - yield return "weaponMoney is set but weaponTags is not."; - } - else - { - float num = 999999f; - int i; - for (i = 0; i < weaponTags.Count; i++) - { - IEnumerable source = DefDatabase.AllDefs.Where((ThingDef d) => d.weaponTags != null && d.weaponTags.Contains(weaponTags[i])); - if (source.Any()) - { - num = Mathf.Min(num, source.Min((Func)PawnWeaponGenerator.CheapestNonDerpPriceFor)); - } - } - if (num < 999999f && num > weaponMoney.min) - { - yield return "Cheapest weapon with one of my weaponTags costs " + num + " but weaponMoney min is " + weaponMoney.min + ", so could end up weaponless."; - } - } - } - if (!RaceProps.Humanlike && lifeStages.Count != RaceProps.lifeStageAges.Count) - { - yield return "PawnKindDef defines " + lifeStages.Count + " lifeStages while race def defines " + RaceProps.lifeStageAges.Count; - } - if (apparelRequired != null) - { - for (int i = 0; i < apparelRequired.Count; i++) - { - for (int j = i + 1; j < apparelRequired.Count; j++) - { - if (!ApparelUtility.CanWearTogether(apparelRequired[i], apparelRequired[j], race.race.body)) - { - yield return "required apparel can't be worn together (" + apparelRequired[i]?.ToString() + ", " + apparelRequired[j]?.ToString() + ")"; - } - } - } - } - if (alternateGraphics != null) - { - foreach (AlternateGraphic alternateGraphic in alternateGraphics) - { - if (alternateGraphic.Weight < 0f) - { - yield return "alternate graphic has negative weight."; - } - } - } - if (RaceProps.Humanlike && !initialResistanceRange.HasValue) - { - yield return "initial resistance range is undefined for humanlike pawn kind."; - } - if (RaceProps.Humanlike && !initialWillRange.HasValue) - { - yield return "initial will range is undefined for humanlike pawn kind."; - } - if (startingHediffs == null) - { - yield break; - } - foreach (StartingHediff startingHediff in startingHediffs) - { - if (startingHediff.durationTicksRange.HasValue && startingHediff.def.CompProps() == null) - { - yield return "starting hediff " + startingHediff.def.defName + " has duration ticks set but doesn't have Disappears comp."; - } - } - } - - public static PawnKindDef Named(string defName) - { - return DefDatabase.GetNamed(defName); - } -} -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\Anomaly\Defs\PawnKinds\PawnKinds_Fleshbeasts.xml` -**相似度:** 0.5160 - -```xml - - Entities - Entity - -
  • EntityAttacked
  • -
    -
    -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\Anomaly\Defs\PawnKinds\PawnKinds_Fleshbeasts.xml` -**相似度:** 0.5160 - -```xml - Bulbfreak - - 0.9 - Bulbfreak - 360 - -
  • - - Things/Pawn/Fleshbeast/Bulbfreak/Bulbfreak - Graphic_Multi - 3 - -
  • -
    -
    - - - Fingerspike -``` \ No newline at end of file diff --git a/MCP/vector_cache/Pawn_InventoryTracker-get_FirstUnloadableThing.txt b/MCP/vector_cache/Pawn_InventoryTracker-get_FirstUnloadableThing.txt deleted file mode 100644 index 5fd164b6..00000000 --- a/MCP/vector_cache/Pawn_InventoryTracker-get_FirstUnloadableThing.txt +++ /dev/null @@ -1,4149 +0,0 @@ -根据向量相似度分析,与 'get_FirstUnloadableThing, Pawn_InventoryTracker' 最相关的代码定义如下: - ---- -**文件路径 (精确匹配):** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\Verse\Pawn_InventoryTracker.txt` - -```csharp -public class Pawn_InventoryTracker : IThingHolder, IExposable -{ - public Pawn pawn; - - public ThingOwner innerContainer; - - private bool unloadEverything; - - private List itemsNotForSale = new List(); - - private List unpackedCaravanItems = new List(); - - public static readonly Texture2D DrugTex = ContentFinder.Get("UI/Commands/TakeDrug"); - - private static List tmpItemsToKeep = new List(); - - private static readonly List tmpThingList = new List(); - - private List usableDrugsTmp = new List(); - - public bool UnloadEverything - { - get - { - if (unloadEverything) - { - return HasAnyUnloadableThing; - } - return false; - } - set - { - if (value && HasAnyUnloadableThing) - { - unloadEverything = true; - } - else - { - unloadEverything = false; - } - } - } - - public bool HasAnyUnpackedCaravanItems => unpackedCaravanItems.Count > 0; - - private bool HasAnyUnloadableThing => FirstUnloadableThing != default(ThingCount); - - public ThingCount FirstUnloadableThing - { - get - { - if (innerContainer.Count == 0) - { - return default(ThingCount); - } - if (pawn.drugs?.CurrentPolicy != null) - { - DrugPolicy currentPolicy = pawn.drugs.CurrentPolicy; - tmpItemsToKeep.Clear(); - for (int i = 0; i < currentPolicy.Count; i++) - { - if (currentPolicy[i].takeToInventory > 0) - { - tmpItemsToKeep.Add(new ThingDefCount(currentPolicy[i].drug, currentPolicy[i].takeToInventory)); - } - } - } - Pawn_InventoryStockTracker inventoryStock = pawn.inventoryStock; - if (inventoryStock != null && inventoryStock.stockEntries?.Count > 0) - { - foreach (InventoryStockEntry value in pawn.inventoryStock.stockEntries.Values) - { - tmpItemsToKeep.Add(new ThingDefCount(value.thingDef, value.count)); - } - } - foreach (Thing item in innerContainer) - { - int num = -1; - for (int j = 0; j < tmpItemsToKeep.Count; j++) - { - if (item.def == tmpItemsToKeep[j].ThingDef) - { - num = j; - break; - } - } - if (pawn.IsColonist && item.def.IsNutritionGivingIngestible && !item.def.IsDrug && JobGiver_PackFood.IsGoodPackableFoodFor(item, pawn, checkMass: false)) - { - float inventoryPackableFoodNutrition = JobGiver_PackFood.GetInventoryPackableFoodNutrition(pawn); - float maxLevel = pawn.needs.food.MaxLevel; - if (inventoryPackableFoodNutrition - item.GetStatValue(StatDefOf.Nutrition) * (float)item.stackCount <= maxLevel) - { - int k; - for (k = 0; inventoryPackableFoodNutrition - item.GetStatValue(StatDefOf.Nutrition) * (float)k > maxLevel; k++) - { - } - if (item.stackCount - k > 0) - { - tmpItemsToKeep.Add(new ThingDefCount(item.def, item.stackCount - k)); - num = tmpItemsToKeep.Count - 1; - } - } - } - if (num < 0) - { - return new ThingCount(item, item.stackCount); - } - if (item.stackCount > tmpItemsToKeep[num].Count) - { - return new ThingCount(item, item.stackCount - tmpItemsToKeep[num].Count); - } - tmpItemsToKeep[num] = new ThingDefCount(tmpItemsToKeep[num].ThingDef, tmpItemsToKeep[num].Count - item.stackCount); - } - return default(ThingCount); - } - } - - public IThingHolder ParentHolder => pawn; - - public Pawn_InventoryTracker(Pawn pawn) - { - this.pawn = pawn; - innerContainer = new ThingOwner(this, oneStackOnly: false); - } - - public void ExposeData() - { - Scribe_Collections.Look(ref itemsNotForSale, "itemsNotForSale", LookMode.Reference); - Scribe_Collections.Look(ref unpackedCaravanItems, "unpackedCaravanItems", LookMode.Reference); - Scribe_Deep.Look(ref innerContainer, "innerContainer", this); - Scribe_Values.Look(ref unloadEverything, "unloadEverything", defaultValue: false); - } - - public void InventoryTrackerTick() - { - if (unloadEverything && !HasAnyUnloadableThing) - { - unloadEverything = false; - } - } - - public void DropAllNearPawn(IntVec3 pos, bool forbid = false, bool unforbid = false) - { - DropAllNearPawnHelper(pos, forbid, unforbid); - } - - private void DropAllNearPawnHelper(IntVec3 pos, bool forbid = false, bool unforbid = false, bool caravanHaulOnly = false) - { - if (pawn.MapHeld == null) - { - Log.Error("Tried to drop all inventory near pawn but the pawn is unspawned. pawn=" + pawn); - return; - } - tmpThingList.Clear(); - if (caravanHaulOnly) - { - tmpThingList.AddRange(unpackedCaravanItems); - } - else - { - tmpThingList.AddRange(innerContainer); - } - int i; - for (i = 0; i < tmpThingList.Count; i++) - { - if (caravanHaulOnly && !innerContainer.Contains(tmpThingList[i])) - { - unpackedCaravanItems.Remove(tmpThingList[i]); - Log.Warning("Could not drop unpacked caravan item " + tmpThingList[i].Label + ", inventory no longer contains it"); - continue; - } - innerContainer.TryDrop(tmpThingList[i], pos, pawn.MapHeld, ThingPlaceMode.Near, out var _, delegate(Thing t, int unused) - { - if (forbid) - { - t.SetForbiddenIfOutsideHomeArea(); - } - if (unforbid) - { - t.SetForbidden(value: false, warnOnFail: false); - } - if (t.def.IsPleasureDrug) - { - LessonAutoActivator.TeachOpportunity(ConceptDefOf.DrugBurning, OpportunityType.Important); - } - LordJob_FormAndSendCaravan lordJob_FormAndSendCaravan = CaravanFormingUtility.GetFormAndSendCaravanLord(pawn)?.LordJob as LordJob_FormAndSendCaravan; - if (caravanHaulOnly && lordJob_FormAndSendCaravan != null && lordJob_FormAndSendCaravan.GatheringItemsNow) - { - CaravanFormingUtility.TryAddItemBackToTransferables(t, lordJob_FormAndSendCaravan.transferables, tmpThingList[i].stackCount); - } - unpackedCaravanItems.Remove(tmpThingList[i]); - }); - } - } - - public void DropCount(ThingDef def, int count, bool forbid = false, bool unforbid = false) - { - if (pawn.MapHeld == null) - { - Log.Error("Tried to drop a thing near pawn but the pawn is unspawned. pawn=" + pawn); - return; - } - tmpThingList.Clear(); - tmpThingList.AddRange(innerContainer); - int num = 0; - for (int i = 0; i < tmpThingList.Count; i++) - { - Thing thing = tmpThingList[i]; - if (thing.def != def) - { - continue; - } - int num2 = Math.Min(thing.stackCount, count); - innerContainer.TryDrop(tmpThingList[i], pawn.Position, pawn.MapHeld, ThingPlaceMode.Near, num2, out var _, delegate(Thing t, int unused) - { - if (forbid) - { - t.SetForbiddenIfOutsideHomeArea(); - } - if (unforbid) - { - t.SetForbidden(value: false, warnOnFail: false); - } - if (t.def.IsPleasureDrug) - { - LessonAutoActivator.TeachOpportunity(ConceptDefOf.DrugBurning, OpportunityType.Important); - } - }); - num += num2; - if (num >= count) - { - break; - } - } - } - - public void RemoveCount(ThingDef def, int count, bool destroy = true) - { - tmpThingList.Clear(); - tmpThingList.AddRange(innerContainer); - foreach (Thing tmpThing in tmpThingList) - { - if (tmpThing.def != def) - { - continue; - } - if (tmpThing.stackCount > count) - { - tmpThing.stackCount -= count; - break; - } - innerContainer.Remove(tmpThing); - if (destroy) - { - tmpThing.Destroy(); - } - break; - } - } - - public void DestroyAll(DestroyMode mode = DestroyMode.Vanish) - { - innerContainer.ClearAndDestroyContents(mode); - } - - public bool Contains(Thing item) - { - return innerContainer.Contains(item); - } - - public int Count(ThingDef def) - { - int num = 0; - foreach (Thing item in innerContainer) - { - if (item.def == def) - { - num += item.stackCount; - } - } - return num; - } - - public int Count(Func validator) - { - int num = 0; - foreach (Thing item in innerContainer) - { - if (validator(item)) - { - num += item.stackCount; - } - } - return num; - } - - public void AddHauledCaravanItem(Thing item) - { - if (pawn.carryTracker.innerContainer.TryTransferToContainer(item, innerContainer, item.stackCount, out var resultingTransferredItem, canMergeWithExistingStacks: false) > 0) - { - unpackedCaravanItems.Add(resultingTransferredItem); - } - CompForbiddable compForbiddable = resultingTransferredItem?.TryGetComp(); - if (compForbiddable != null) - { - compForbiddable.Forbidden = false; - } - } - - public void TryAddAndUnforbid(Thing item) - { - CompForbiddable compForbiddable = item.TryGetComp(); - if (innerContainer.TryAdd(item) && compForbiddable != null) - { - compForbiddable.Forbidden = false; - } - } - - public void TransferCaravanItemsToCarrier(Pawn_InventoryTracker carrierInventory) - { - List list = new List(); - list.AddRange(pawn.inventory.unpackedCaravanItems); - foreach (Thing item in list) - { - if (MassUtility.IsOverEncumbered(carrierInventory.pawn)) - { - break; - } - if (innerContainer.Contains(item)) - { - pawn.inventory.innerContainer.TryTransferToContainer(item, carrierInventory.innerContainer, item.stackCount); - } - unpackedCaravanItems.Remove(item); - } - } - - public void DropAllPackingCaravanThings() - { - if (pawn.Spawned) - { - DropAllNearPawnHelper(pawn.Position, forbid: false, unforbid: false, caravanHaulOnly: true); - ClearHaulingCaravanCache(); - } - } - - public void ClearHaulingCaravanCache() - { - unpackedCaravanItems.Clear(); - } - - public bool NotForSale(Thing item) - { - return itemsNotForSale.Contains(item); - } - - public void TryAddItemNotForSale(Thing item) - { - if (innerContainer.TryAdd(item, canMergeWithExistingStacks: false)) - { - itemsNotForSale.Add(item); - } - } - - public void Notify_ItemRemoved(Thing item) - { - itemsNotForSale.Remove(item); - unpackedCaravanItems.Remove(item); - if (unloadEverything && !HasAnyUnloadableThing) - { - unloadEverything = false; - } - } - - public ThingOwner GetDirectlyHeldThings() - { - return innerContainer; - } - - public void GetChildHolders(List outChildren) - { - ThingOwnerUtility.AppendThingHoldersFromThings(outChildren, GetDirectlyHeldThings()); - } - - public IEnumerable GetDrugs() - { - foreach (Thing item in innerContainer) - { - if (item.TryGetComp() != null) - { - yield return item; - } - } - } - - public IEnumerable GetCombatEnhancingDrugs() - { - foreach (Thing item in innerContainer) - { - CompDrug compDrug = item.TryGetComp(); - if (compDrug != null && compDrug.Props.isCombatEnhancingDrug) - { - yield return item; - } - } - } - - public Thing FindCombatEnhancingDrug() - { - return GetCombatEnhancingDrugs().FirstOrDefault(); - } - - public IEnumerable GetGizmos() - { - if (!pawn.IsColonistPlayerControlled || !pawn.Drafted || Find.Selector.SingleSelectedThing != pawn) - { - yield break; - } - usableDrugsTmp.Clear(); - foreach (Thing drug2 in GetDrugs()) - { - if (FoodUtility.WillIngestFromInventoryNow(pawn, drug2)) - { - usableDrugsTmp.Add(drug2); - } - } - if (usableDrugsTmp.Count == 0) - { - yield break; - } - if (usableDrugsTmp.Count == 1) - { - Thing drug = usableDrugsTmp[0]; - string defaultLabel = (drug.def.ingestible.ingestCommandString.NullOrEmpty() ? "ConsumeThing".Translate(drug.LabelNoCount, drug) : drug.def.ingestible.ingestCommandString.Formatted(drug.LabelShort)); - Command_Action command_Action = new Command_Action(); - command_Action.defaultLabel = defaultLabel; - command_Action.defaultDesc = drug.LabelCapNoCount + ": " + drug.def.description.CapitalizeFirst(); - command_Action.icon = drug.def.uiIcon; - command_Action.iconAngle = drug.def.uiIconAngle; - command_Action.iconOffset = drug.def.uiIconOffset; - command_Action.action = delegate - { - FoodUtility.IngestFromInventoryNow(pawn, drug); - }; - yield return command_Action; - yield break; - } - Command_Action command_Action2 = new Command_Action(); - command_Action2.defaultLabel = "TakeDrug".Translate(); - command_Action2.defaultDesc = "TakeDrugDesc".Translate(); - command_Action2.icon = DrugTex; - command_Action2.action = delegate - { - List list = new List(); - foreach (Thing drug in usableDrugsTmp) - { - string label = (drug.def.ingestible.ingestCommandString.NullOrEmpty() ? "ConsumeThing".Translate(drug.LabelNoCount, drug) : drug.def.ingestible.ingestCommandString.Formatted(drug.LabelShort)); - list.Add(new FloatMenuOption(label, delegate - { - FoodUtility.IngestFromInventoryNow(pawn, drug); - })); - } - Find.WindowStack.Add(new FloatMenu(list)); - }; - yield return command_Action2; - } -} -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\Verse\ThingOwnerUtility.txt` -**相似度:** 0.6304 - -```csharp -public static class ThingOwnerUtility -{ - private static readonly Stack tmpStack = new Stack(); - - private static readonly List tmpHolders = new List(); - - private static readonly List tmpThings = new List(); - - private static readonly List tmpMapChildHolders = new List(); - - public static bool ThisOrAnyCompIsThingHolder(this ThingDef thingDef) - { - if (typeof(IThingHolder).IsAssignableFrom(thingDef.thingClass)) - { - return true; - } - for (int i = 0; i < thingDef.comps.Count; i++) - { - if (typeof(IThingHolder).IsAssignableFrom(thingDef.comps[i].compClass)) - { - return true; - } - } - return false; - } - - public static ThingOwner TryGetInnerInteractableThingOwner(this Thing thing) - { - IThingHolder thingHolder = thing as IThingHolder; - ThingWithComps thingWithComps = thing as ThingWithComps; - if (thingHolder != null) - { - ThingOwner directlyHeldThings = thingHolder.GetDirectlyHeldThings(); - if (directlyHeldThings != null) - { - return directlyHeldThings; - } - } - if (thingWithComps != null) - { - List allComps = thingWithComps.AllComps; - for (int i = 0; i < allComps.Count; i++) - { - if (allComps[i] is IThingHolder thingHolder2) - { - ThingOwner directlyHeldThings2 = thingHolder2.GetDirectlyHeldThings(); - if (directlyHeldThings2 != null) - { - return directlyHeldThings2; - } - } - } - } - tmpHolders.Clear(); - if (thingHolder != null) - { - thingHolder.GetChildHolders(tmpHolders); - if (tmpHolders.Any()) - { - ThingOwner directlyHeldThings3 = tmpHolders[0].GetDirectlyHeldThings(); - if (directlyHeldThings3 != null) - { - tmpHolders.Clear(); - return directlyHeldThings3; - } - } - } - if (thingWithComps != null) - { - List allComps2 = thingWithComps.AllComps; - for (int j = 0; j < allComps2.Count; j++) - { - if (!(allComps2[j] is IThingHolder thingHolder3)) - { - continue; - } - thingHolder3.GetChildHolders(tmpHolders); - if (tmpHolders.Any()) - { - ThingOwner directlyHeldThings4 = tmpHolders[0].GetDirectlyHeldThings(); - if (directlyHeldThings4 != null) - { - tmpHolders.Clear(); - return directlyHeldThings4; - } - } - } - } - tmpHolders.Clear(); - return null; - } - - public static bool SpawnedOrAnyParentSpawned(IThingHolder holder) - { - return SpawnedParentOrMe(holder) != null; - } - - public static Thing SpawnedParentOrMe(IThingHolder holder) - { - while (holder != null) - { - if (holder is Thing { Spawned: not false } thing) - { - return thing; - } - if (holder is ThingComp thingComp && thingComp.parent.Spawned) - { - return thingComp.parent; - } - holder = holder.ParentHolder; - } - return null; - } - - public static IntVec3 GetRootPosition(IThingHolder holder) - { - IntVec3 result = IntVec3.Invalid; - while (holder != null) - { - if (holder is Thing { Position: { IsValid: not false } } thing) - { - result = thing.Position; - } - else if (holder is ThingComp thingComp && thingComp.parent.Position.IsValid) - { - result = thingComp.parent.Position; - } - holder = holder.ParentHolder; - } - return result; - } - - public static Map GetRootMap(IThingHolder holder) - { - while (holder != null) - { - if (holder is Map result) - { - return result; - } - holder = holder.ParentHolder; - } - return null; - } - - public static PlanetTile GetRootTile(IThingHolder holder) - { - while (holder != null) - { - if (holder is WorldObject { Tile: { Valid: not false } } worldObject) - { - return worldObject.Tile; - } - holder = holder.ParentHolder; - } - return PlanetTile.Invalid; - } - - public static bool ContentsSuspended(IThingHolder holder) - { - while (holder != null) - { - if (holder is Building_CryptosleepCasket || holder is ISuspendableThingHolder { IsContentsSuspended: not false }) - { - return true; - } - holder = holder.ParentHolder; - } - return false; - } - - public static bool ContentsInCryptosleep(IThingHolder holder) - { - while (holder != null) - { - if (holder is Building_CryptosleepCasket) - { - return true; - } - holder = holder.ParentHolder; - } - return false; - } - - public static bool IsEnclosingContainer(this IThingHolder holder) - { - if (holder != null && !(holder is Pawn_CarryTracker) && !(holder is Corpse) && !(holder is Map) && !(holder is Caravan) && !(holder is Settlement_TraderTracker)) - { - return !(holder is TradeShip); - } - return false; - } - - public static bool ShouldAutoRemoveDestroyedThings(IThingHolder holder) - { - if (!(holder is Corpse)) - { - return !(holder is Caravan); - } - return false; - } - - public static bool ShouldAutoExtinguishInnerThings(IThingHolder holder) - { - return !(holder is Map); - } - - public static bool ShouldRemoveDesignationsOnAddedThings(IThingHolder holder) - { - return holder.IsEnclosingContainer(); - } - - public static void AppendThingHoldersFromThings(List outThingsHolders, IList container) - { - if (container == null) - { - return; - } - int i = 0; - for (int count = container.Count; i < count; i++) - { - if (container[i] is IThingHolder item) - { - outThingsHolders.Add(item); - } - if (!(container[i] is ThingWithComps { AllComps: var allComps })) - { - continue; - } - for (int j = 0; j < allComps.Count; j++) - { - if (allComps[j] is IThingHolder item2) - { - outThingsHolders.Add(item2); - } - } - } - } - - public static bool AnyParentIs(Thing thing) where T : class, IThingHolder - { - return GetAnyParent(thing) != null; - } - - public static T GetAnyParent(Thing thing) where T : class, IThingHolder - { - if (thing is T result) - { - return result; - } - for (IThingHolder parentHolder = thing.ParentHolder; parentHolder != null; parentHolder = parentHolder.ParentHolder) - { - if (parentHolder is T result2) - { - return result2; - } - } - return null; - } - - public static Thing GetFirstParentThing(Thing thing) - { - for (IThingHolder parentHolder = thing.ParentHolder; parentHolder != null; parentHolder = parentHolder.ParentHolder) - { - if (parentHolder is Thing result) - { - return result; - } - if (parentHolder is ThingComp thingComp) - { - return thingComp.parent; - } - } - return null; - } - - public static Thing GetFirstSpawnedParentThing(Thing thing) - { - if (thing.Spawned) - { - return thing; - } - for (IThingHolder parentHolder = thing.ParentHolder; parentHolder != null; parentHolder = parentHolder.ParentHolder) - { - if (parentHolder is Thing { Spawned: not false } thing2) - { - return thing2; - } - if (parentHolder is ThingComp thingComp && thingComp.parent.Spawned) - { - return thingComp.parent; - } - } - return null; - } - - public static void GetAllThingsRecursively(IThingHolder holder, List outThings, bool allowUnreal = true, Predicate passCheck = null) - { - outThings.Clear(); - if (passCheck != null && !passCheck(holder)) - { - return; - } - tmpStack.Clear(); - tmpStack.Push(holder); - while (tmpStack.Count != 0) - { - IThingHolder thingHolder = tmpStack.Pop(); - if (allowUnreal || AreImmediateContentsReal(thingHolder)) - { - ThingOwner directlyHeldThings = thingHolder.GetDirectlyHeldThings(); - if (directlyHeldThings != null) - { - outThings.AddRange(directlyHeldThings); - } - } - tmpHolders.Clear(); - thingHolder.GetChildHolders(tmpHolders); - for (int i = 0; i < tmpHolders.Count; i++) - { - if (passCheck == null || passCheck(tmpHolders[i])) - { - tmpStack.Push(tmpHolders[i]); - } - } - } - tmpStack.Clear(); - tmpHolders.Clear(); - } - - public static void GetAllThingsRecursively(Map map, ThingRequest request, List outThings, bool allowUnreal = true, Predicate passCheck = null, bool alsoGetSpawnedThings = true) where T : Thing - { - outThings.Clear(); - if (alsoGetSpawnedThings) - { - List list = map.listerThings.ThingsMatching(request); - for (int i = 0; i < list.Count; i++) - { - if (list[i] is T item) - { - outThings.Add(item); - } - } - } - tmpMapChildHolders.Clear(); - map.GetChildHolders(tmpMapChildHolders); - for (int j = 0; j < tmpMapChildHolders.Count; j++) - { - tmpThings.Clear(); - GetAllThingsRecursively(tmpMapChildHolders[j], tmpThings, allowUnreal, passCheck); - for (int k = 0; k < tmpThings.Count; k++) - { - if (tmpThings[k] is T val && request.Accepts(val)) - { - outThings.Add(val); - } - } - } - tmpThings.Clear(); - tmpMapChildHolders.Clear(); - } - - public static List GetAllThingsRecursively(IThingHolder holder, bool allowUnreal = true) - { - List list = new List(); - GetAllThingsRecursively(holder, list, allowUnreal); - return list; - } - - public static bool AreImmediateContentsReal(IThingHolder holder) - { - if (!(holder is Corpse)) - { - return !(holder is MinifiedThing); - } - return false; - } - - public static bool TryGetFixedTemperature(IThingHolder holder, Thing forThing, out float temperature) - { - if (holder is Pawn_InventoryTracker && forThing.TryGetComp() != null) - { - temperature = 14f; - return true; - } - if (holder is CompLaunchable || holder is ActiveTransporterInfo || holder is TravellingTransporters) - { - temperature = 14f; - return true; - } - if (holder is Settlement_TraderTracker || holder is TradeShip) - { - temperature = 14f; - return true; - } - if (holder is CompTransporter) - { - temperature = 14f; - return true; - } - temperature = 21f; - return false; - } -} -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld.Planet\CaravanInventoryUtility.txt` -**相似度:** 0.6279 - -```csharp -public static class CaravanInventoryUtility -{ - private static List inventoryItems = new List(); - - private static List inventoryToMove = new List(); - - private static List tmpApparel = new List(); - - private static List tmpEquipment = new List(); - - public static List AllInventoryItems(Caravan caravan) - { - inventoryItems.Clear(); - List pawnsListForReading = caravan.PawnsListForReading; - for (int i = 0; i < pawnsListForReading.Count; i++) - { - Pawn pawn = pawnsListForReading[i]; - for (int num = pawn.inventory.innerContainer.Count - 1; num >= 0; num--) - { - Thing item = pawn.inventory.innerContainer[num]; - inventoryItems.Add(item); - } - } - return inventoryItems; - } - - public static Building_PassengerShuttle FindShuttle(Caravan caravan) - { - List list = AllInventoryItems(caravan); - for (int i = 0; i < list.Count; i++) - { - if (list[i] is Building_PassengerShuttle result) - { - return result; - } - } - return null; - } - - public static void CaravanInventoryUtilityStaticUpdate() - { - inventoryItems.Clear(); - } - - public static Pawn GetOwnerOf(Caravan caravan, Thing item) - { - IThingHolder parentHolder = item.ParentHolder; - if (parentHolder is Pawn_InventoryTracker) - { - Pawn pawn = (Pawn)parentHolder.ParentHolder; - if (caravan.ContainsPawn(pawn)) - { - return pawn; - } - } - return null; - } - - public static bool TryGetBestFood(Caravan caravan, Pawn forPawn, out Thing food, out Pawn owner) - { - List list = AllInventoryItems(caravan); - Thing thing = null; - float num = 0f; - for (int i = 0; i < list.Count; i++) - { - Thing thing2 = list[i]; - if (CaravanPawnsNeedsUtility.CanEatForNutritionNow(thing2, forPawn)) - { - float foodScore = CaravanPawnsNeedsUtility.GetFoodScore(thing2, forPawn); - if (thing == null || foodScore > num) - { - thing = thing2; - num = foodScore; - } - } - } - if (thing != null) - { - food = thing; - owner = GetOwnerOf(caravan, thing); - return true; - } - food = null; - owner = null; - return false; - } - - public static bool TryGetDrugToSatisfyChemicalNeed(Caravan caravan, Pawn forPawn, Hediff hediff, out Thing drug, out Pawn owner) - { - if (hediff == null) - { - drug = null; - owner = null; - return false; - } - List list = AllInventoryItems(caravan); - Thing thing = null; - for (int i = 0; i < list.Count; i++) - { - Thing thing2 = list[i]; - if (!thing2.IngestibleNow || !thing2.def.IsDrug) - { - continue; - } - CompDrug compDrug = thing2.TryGetComp(); - if (compDrug != null && compDrug.Props.chemical != null && (!(hediff is Hediff_ChemicalDependency hediff_ChemicalDependency) || compDrug.Props.chemical == hediff_ChemicalDependency.chemical) && (!(hediff is Hediff_Addiction hediff_Addiction) || compDrug.Props.chemical.addictionHediff == hediff_Addiction.def)) - { - DrugPolicy drugPolicy = forPawn.drugs?.CurrentPolicy; - if (drugPolicy == null || drugPolicy[thing2.def].allowedForAddiction || forPawn.story == null || forPawn.story.traits.DegreeOfTrait(TraitDefOf.DrugDesire) > 0) - { - thing = thing2; - break; - } - } - } - if (thing != null) - { - drug = thing; - owner = GetOwnerOf(caravan, thing); - return true; - } - drug = null; - owner = null; - return false; - } - - public static bool TryGetBestMedicine(Caravan caravan, Pawn patient, out Medicine medicine, out Pawn owner) - { - if (patient.playerSettings == null || (int)patient.playerSettings.medCare <= 1) - { - medicine = null; - owner = null; - return false; - } - List list = AllInventoryItems(caravan); - Medicine medicine2 = null; - float num = 0f; - for (int i = 0; i < list.Count; i++) - { - Thing thing = list[i]; - if (thing.def.IsMedicine && patient.playerSettings.medCare.AllowsMedicine(thing.def)) - { - float statValue = thing.GetStatValue(StatDefOf.MedicalPotency); - if (statValue > num || medicine2 == null) - { - num = statValue; - medicine2 = (Medicine)thing; - } - } - } - if (medicine2 != null) - { - medicine = medicine2; - owner = GetOwnerOf(caravan, medicine2); - return true; - } - medicine = null; - owner = null; - return false; - } - - public static bool TryGetThingOfDef(Caravan caravan, ThingDef thingDef, out Thing thing, out Pawn owner) - { - List list = AllInventoryItems(caravan); - for (int i = 0; i < list.Count; i++) - { - Thing thing2 = list[i]; - if (thing2.def == thingDef) - { - thing = thing2; - owner = GetOwnerOf(caravan, thing2); - return true; - } - } - thing = null; - owner = null; - return false; - } - - public static void MoveAllInventoryToSomeoneElse(Pawn from, List candidates, List ignoreCandidates = null) - { - inventoryToMove.Clear(); - inventoryToMove.AddRange(from.inventory.innerContainer); - for (int i = 0; i < inventoryToMove.Count; i++) - { - MoveInventoryToSomeoneElse(from, inventoryToMove[i], candidates, ignoreCandidates, inventoryToMove[i].stackCount); - } - inventoryToMove.Clear(); - } - - public static void MoveInventoryToSomeoneElse(Pawn itemOwner, Thing item, List candidates, List ignoreCandidates, int numToMove) - { - if (numToMove < 0 || numToMove > item.stackCount) - { - Log.Warning("Tried to move item " + item?.ToString() + " with numToMove=" + numToMove + " (item stack count = " + item.stackCount + ")"); - } - else - { - Pawn pawn = FindPawnToMoveInventoryTo(item, candidates, ignoreCandidates, itemOwner); - if (pawn != null) - { - itemOwner.inventory.innerContainer.TryTransferToContainer(item, pawn.inventory.innerContainer, numToMove); - } - } - } - - public static Pawn FindPawnToMoveInventoryTo(Thing item, List candidates, List ignoreCandidates, Pawn currentItemOwner = null) - { - if (item is Pawn) - { - Log.Error("Called FindPawnToMoveInventoryTo but the item is a pawn."); - return null; - } - if (candidates.Where((Pawn x) => CanMoveInventoryTo(x) && (ignoreCandidates == null || !ignoreCandidates.Contains(x)) && x != currentItemOwner && !MassUtility.IsOverEncumbered(x)).TryRandomElement(out var result)) - { - return result; - } - if (candidates.Where((Pawn x) => CanMoveInventoryTo(x) && (ignoreCandidates == null || !ignoreCandidates.Contains(x)) && x != currentItemOwner).TryRandomElement(out result)) - { - return result; - } - if (candidates.Where((Pawn x) => (ignoreCandidates == null || !ignoreCandidates.Contains(x)) && x != currentItemOwner).TryRandomElement(out result)) - { - return result; - } - return null; - } - - public static void MoveAllApparelToSomeonesInventory(Pawn moveFrom, List candidates, bool moveLocked = true) - { - if (moveFrom.apparel == null) - { - return; - } - tmpApparel.Clear(); - if (moveLocked) - { - tmpApparel.AddRange(moveFrom.apparel.WornApparel); - } - else - { - for (int i = 0; i < moveFrom.apparel.WornApparel.Count; i++) - { - Apparel apparel = moveFrom.apparel.WornApparel[i]; - if (!moveFrom.apparel.IsLocked(apparel)) - { - tmpApparel.Add(apparel); - } - } - } - for (int j = 0; j < tmpApparel.Count; j++) - { - moveFrom.apparel.Remove(tmpApparel[j]); - FindPawnToMoveInventoryTo(tmpApparel[j], candidates, null, moveFrom)?.inventory.innerContainer.TryAdd(tmpApparel[j]); - } - tmpApparel.Clear(); - } - - public static void MoveAllEquipmentToSomeonesInventory(Pawn moveFrom, List candidates) - { - if (moveFrom.equipment != null) - { - tmpEquipment.Clear(); - tmpEquipment.AddRange(moveFrom.equipment.AllEquipmentListForReading); - for (int i = 0; i < tmpEquipment.Count; i++) - { - moveFrom.equipment.Remove(tmpEquipment[i]); - FindPawnToMoveInventoryTo(tmpEquipment[i], candidates, null, moveFrom)?.inventory.innerContainer.TryAdd(tmpEquipment[i]); - } - tmpEquipment.Clear(); - } - } - - private static bool CanMoveInventoryTo(Pawn pawn) - { - return MassUtility.CanEverCarryAnything(pawn); - } - - public static List TakeThings(Caravan caravan, Func takeQuantity) - { - List list = new List(); - foreach (Thing item in AllInventoryItems(caravan).ToList()) - { - int num = takeQuantity(item); - if (num > 0) - { - list.Add(item.holdingOwner.Take(item, num)); - } - } - return list; - } - - public static void GiveThing(Caravan caravan, Thing thing) - { - if (AllInventoryItems(caravan).Contains(thing)) - { - Log.Error("Tried to give the same item twice (" + thing?.ToString() + ") to a caravan (" + caravan?.ToString() + ")."); - return; - } - Pawn pawn = FindPawnToMoveInventoryTo(thing, caravan.PawnsListForReading, null); - if (pawn == null) - { - Log.Error($"Failed to give item {thing} to caravan {caravan}; item was lost"); - thing.Destroy(); - } - else if (!pawn.inventory.innerContainer.TryAdd(thing)) - { - Log.Error($"Failed to give item {thing} to caravan {caravan}; item was lost"); - thing.Destroy(); - } - } - - public static bool HasThings(Caravan caravan, ThingDef thingDef, int count, Func validator = null) - { - int num = 0; - List list = AllInventoryItems(caravan); - for (int i = 0; i < list.Count; i++) - { - Thing thing = list[i]; - if (thing.def == thingDef && (validator == null || validator(thing))) - { - num += thing.stackCount; - } - } - return num >= count; - } - - public static IEnumerable GetAllDissolvingThings(Caravan caravan) - { - ThingRequest group = ThingRequest.ForGroup(ThingRequestGroup.Dissolving); - List items = AllInventoryItems(caravan); - for (int i = 0; i < items.Count; i++) - { - if (group.Accepts(items[i])) - { - yield return items[i]; - } - } - } -} -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\Verse\ThingOwner.txt` -**相似度:** 0.6188 - -```csharp -public abstract class ThingOwner : IExposable, IList, ICollection, IEnumerable, IEnumerable -{ - protected IThingHolder owner; - - protected int maxStacks = 999999; - - public LookMode contentsLookMode = LookMode.Deep; - - public bool removeContentsIfDestroyed = true; - - private const int InfMaxStacks = 999999; - - public IThingHolder Owner => owner; - - public abstract int Count { get; } - - public Thing this[int index] => GetAt(index); - - public bool Any => Count > 0; - - public int TotalStackCount - { - get - { - int num = 0; - int count = Count; - for (int i = 0; i < count; i++) - { - num += GetAt(i).stackCount; - } - return num; - } - } - - public string ContentsString - { - get - { - if (Any) - { - return GenThing.ThingsToCommaList(this); - } - return "NothingLower".Translate(); - } - } - - Thing IList.this[int index] - { - get - { - return GetAt(index); - } - set - { - throw new InvalidOperationException("ThingOwner doesn't allow setting individual elements."); - } - } - - bool ICollection.IsReadOnly => true; - - public event Action OnContentsChanged; - - public ThingOwner() - { - } - - public ThingOwner(IThingHolder owner) - { - this.owner = owner; - } - - public ThingOwner(IThingHolder owner, LookMode contentsLookMode = LookMode.Deep, bool removeContentsIfDestroyed = true) - { - this.owner = owner; - this.contentsLookMode = contentsLookMode; - this.removeContentsIfDestroyed = removeContentsIfDestroyed; - } - - public ThingOwner(IThingHolder owner, bool oneStackOnly, LookMode contentsLookMode = LookMode.Deep, bool removeContentsIfDestroyed = true) - : this(owner) - { - maxStacks = (oneStackOnly ? 1 : 999999); - this.contentsLookMode = contentsLookMode; - this.removeContentsIfDestroyed = removeContentsIfDestroyed; - } - - public virtual void ExposeData() - { - Scribe_Values.Look(ref maxStacks, "maxStacks", 999999); - Scribe_Values.Look(ref contentsLookMode, "contentsLookMode", LookMode.Deep); - Scribe_Values.Look(ref removeContentsIfDestroyed, "removeContentsIfDestroyed", defaultValue: true); - } - - public void DoTick() - { - for (int num = Count - 1; num >= 0; num--) - { - Thing at = GetAt(num); - int offset = ((owner is Thing t) ? t.HashOffset() : 0); - at.DoTick(); - if (at.def.tickerType == TickerType.Rare && GenTicks.IsTickInterval(offset, 250)) - { - at.TickRare(); - } - else if (at.def.tickerType == TickerType.Long && GenTicks.IsTickInterval(offset, 2000)) - { - at.TickLong(); - } - if (at.Destroyed && removeContentsIfDestroyed) - { - Remove(at); - } - } - } - - public void Clear() - { - for (int num = Count - 1; num >= 0; num--) - { - Remove(GetAt(num)); - } - } - - public void ClearAndDestroyContents(DestroyMode mode = DestroyMode.Vanish) - { - while (Any) - { - for (int num = Count - 1; num >= 0; num--) - { - Thing at = GetAt(num); - at.Destroy(mode); - Remove(at); - } - } - } - - public void ClearAndDestroyContentsOrPassToWorld(DestroyMode mode = DestroyMode.Vanish) - { - while (Any) - { - for (int num = Count - 1; num >= 0; num--) - { - Thing at = GetAt(num); - at.DestroyOrPassToWorld(mode); - Remove(at); - } - } - } - - public bool CanAcceptAnyOf(Thing item, bool canMergeWithExistingStacks = true) - { - return GetCountCanAccept(item, canMergeWithExistingStacks) > 0; - } - - public virtual int GetCountCanAccept(Thing item, bool canMergeWithExistingStacks = true) - { - if (item == null || item.stackCount <= 0) - { - return 0; - } - if (maxStacks == 999999) - { - return item.stackCount; - } - int num = 0; - if (Count < maxStacks) - { - num += (maxStacks - Count) * item.def.stackLimit; - } - if (num >= item.stackCount) - { - return Mathf.Min(num, item.stackCount); - } - if (canMergeWithExistingStacks) - { - int i = 0; - for (int count = Count; i < count; i++) - { - Thing at = GetAt(i); - if (at.stackCount < at.def.stackLimit && at.CanStackWith(item)) - { - num += at.def.stackLimit - at.stackCount; - if (num >= item.stackCount) - { - return Mathf.Min(num, item.stackCount); - } - } - } - } - return Mathf.Min(num, item.stackCount); - } - - public abstract int TryAdd(Thing item, int count, bool canMergeWithExistingStacks = true); - - public abstract bool TryAdd(Thing item, bool canMergeWithExistingStacks = true); - - public abstract int IndexOf(Thing item); - - public abstract bool Remove(Thing item); - - protected abstract Thing GetAt(int index); - - public bool Contains(Thing item) - { - if (item == null) - { - return false; - } - return item.holdingOwner == this; - } - - public void RemoveAt(int index) - { - if (index < 0 || index >= Count) - { - throw new ArgumentOutOfRangeException("index"); - } - Remove(GetAt(index)); - } - - public int TryAddOrTransfer(Thing item, int count, bool canMergeWithExistingStacks = true) - { - if (item == null) - { - Log.Warning("Tried to add or transfer null item to ThingOwner."); - return 0; - } - if (item.holdingOwner != null) - { - return item.holdingOwner.TryTransferToContainer(item, this, count, canMergeWithExistingStacks); - } - return TryAdd(item, count, canMergeWithExistingStacks); - } - - public bool TryAddOrTransfer(Thing item, bool canMergeWithExistingStacks = true) - { - if (item == null) - { - Log.Warning("Tried to add or transfer null item to ThingOwner."); - return false; - } - if (item.holdingOwner != null) - { - return item.holdingOwner.TryTransferToContainer(item, this, canMergeWithExistingStacks); - } - return TryAdd(item, canMergeWithExistingStacks); - } - - public void TryAddRangeOrTransfer(IEnumerable things, bool canMergeWithExistingStacks = true, bool destroyLeftover = false) - { - if (things == this) - { - return; - } - if (things is ThingOwner thingOwner) - { - thingOwner.TryTransferAllToContainer(this, canMergeWithExistingStacks); - if (destroyLeftover) - { - thingOwner.ClearAndDestroyContents(); - } - return; - } - if (things is IList list) - { - for (int i = 0; i < list.Count; i++) - { - if (!TryAddOrTransfer(list[i], canMergeWithExistingStacks) && destroyLeftover) - { - list[i].Destroy(); - } - } - return; - } - foreach (Thing thing in things) - { - if (!TryAddOrTransfer(thing, canMergeWithExistingStacks) && destroyLeftover) - { - thing.Destroy(); - } - } - } - - public int RemoveAll(Predicate predicate) - { - int num = 0; - for (int num2 = Count - 1; num2 >= 0; num2--) - { - if (predicate(GetAt(num2))) - { - Remove(GetAt(num2)); - num++; - } - } - return num; - } - - public bool TryTransferToContainer(Thing item, ThingOwner otherContainer, bool canMergeWithExistingStacks = true) - { - return TryTransferToContainer(item, otherContainer, item.stackCount, canMergeWithExistingStacks) == item.stackCount; - } - - public int TryTransferToContainer(Thing item, ThingOwner otherContainer, int count, bool canMergeWithExistingStacks = true) - { - Thing resultingTransferredItem; - return TryTransferToContainer(item, otherContainer, count, out resultingTransferredItem, canMergeWithExistingStacks); - } - - public int TryTransferToContainer(Thing item, ThingOwner otherContainer, int count, out Thing resultingTransferredItem, bool canMergeWithExistingStacks = true) - { - if (!Contains(item)) - { - Log.Error("Can't transfer item " + item?.ToString() + " because it's not here. owner=" + owner.ToStringSafe()); - resultingTransferredItem = null; - return 0; - } - if (otherContainer == this && count > 0) - { - resultingTransferredItem = item; - return item.stackCount; - } - if (!otherContainer.CanAcceptAnyOf(item, canMergeWithExistingStacks)) - { - resultingTransferredItem = null; - return 0; - } - if (count <= 0) - { - resultingTransferredItem = null; - return 0; - } - if (owner is Map || otherContainer.owner is Map) - { - Log.Warning("Can't transfer items to or from Maps directly. They must be spawned or despawned manually. Use TryAdd(item.SplitOff(count))"); - resultingTransferredItem = null; - return 0; - } - int num = Mathf.Min(item.stackCount, count); - Thing thing = item.SplitOff(num); - if (Contains(thing)) - { - Remove(thing); - } - if (otherContainer.TryAdd(thing, canMergeWithExistingStacks)) - { - resultingTransferredItem = thing; - item.MapHeld?.resourceCounter?.CheckUpdateResource(thing); - return thing.stackCount; - } - resultingTransferredItem = null; - if (!otherContainer.Contains(thing) && thing.stackCount > 0 && !thing.Destroyed) - { - int result = num - thing.stackCount; - if (item != thing) - { - item.TryAbsorbStack(thing, respectStackLimit: false); - } - else - { - TryAdd(thing, canMergeWithExistingStacks: false); - } - Map mapHeld = item.MapHeld; - if (mapHeld != null) - { - ResourceCounter resourceCounter = mapHeld.resourceCounter; - if (resourceCounter != null) - { - resourceCounter.CheckUpdateResource(thing); - return result; - } - return result; - } - return result; - } - return thing.stackCount; - } - - public void TryTransferAllToContainer(ThingOwner other, bool canMergeWithExistingStacks = true) - { - for (int num = Count - 1; num >= 0; num--) - { - TryTransferToContainer(GetAt(num), other, canMergeWithExistingStacks); - } - } - - public Thing Take(Thing thing, int count) - { - if (!Contains(thing)) - { - Log.Error("Tried to take " + thing.ToStringSafe() + " but it's not here."); - return null; - } - if (count > thing.stackCount) - { - Log.Error("Tried to get " + count + " of " + thing.ToStringSafe() + " while only having " + thing.stackCount); - count = thing.stackCount; - } - if (count == thing.stackCount) - { - Remove(thing); - return thing; - } - Thing thing2 = thing.SplitOff(count); - thing2.holdingOwner = null; - return thing2; - } - - public Thing Take(Thing thing) - { - return Take(thing, thing.stackCount); - } - - public bool TryDrop(Thing thing, ThingPlaceMode mode, int count, out Thing lastResultingThing, Action placedAction = null, Predicate nearPlaceValidator = null) - { - Map rootMap = ThingOwnerUtility.GetRootMap(owner); - IntVec3 rootPosition = ThingOwnerUtility.GetRootPosition(owner); - if (rootMap == null || !rootPosition.IsValid) - { - Log.Error("Cannot drop " + thing?.ToString() + " without a dropLoc and with an owner whose map is null."); - lastResultingThing = null; - return false; - } - return TryDrop(thing, rootPosition, rootMap, mode, count, out lastResultingThing, placedAction, nearPlaceValidator); - } - - public bool TryDrop(Thing thing, IntVec3 dropLoc, Map map, ThingPlaceMode mode, int count, out Thing resultingThing, Action placedAction = null, Predicate nearPlaceValidator = null) - { - if (!Contains(thing)) - { - Log.Error("Tried to drop " + thing.ToStringSafe() + " but it's not here."); - resultingThing = null; - return false; - } - if (thing.stackCount < count) - { - Log.Error("Tried to drop " + count + " of " + thing?.ToString() + " while only having " + thing.stackCount); - count = thing.stackCount; - } - if (count == thing.stackCount) - { - if (GenDrop.TryDropSpawn(thing, dropLoc, map, mode, out resultingThing, placedAction, nearPlaceValidator)) - { - Remove(thing); - return true; - } - return false; - } - Thing thing2 = thing.SplitOff(count); - if (GenDrop.TryDropSpawn(thing2, dropLoc, map, mode, out resultingThing, placedAction, nearPlaceValidator)) - { - return true; - } - thing.TryAbsorbStack(thing2, respectStackLimit: false); - return false; - } - - public bool TryDrop(Thing thing, ThingPlaceMode mode, out Thing lastResultingThing, Action placedAction = null, Predicate nearPlaceValidator = null) - { - Map rootMap = ThingOwnerUtility.GetRootMap(owner); - IntVec3 rootPosition = ThingOwnerUtility.GetRootPosition(owner); - if (rootMap == null || !rootPosition.IsValid) - { - Log.Error("Cannot drop " + thing?.ToString() + " without a dropLoc and with an owner whose map is null."); - lastResultingThing = null; - return false; - } - return TryDrop(thing, rootPosition, rootMap, mode, out lastResultingThing, placedAction, nearPlaceValidator); - } - - public bool TryDrop(Thing thing, IntVec3 dropLoc, Map map, ThingPlaceMode mode, out Thing lastResultingThing, Action placedAction = null, Predicate nearPlaceValidator = null, bool playDropSound = true) - { - if (!Contains(thing)) - { - Log.Error(owner.ToStringSafe() + " container tried to drop " + thing.ToStringSafe() + " which it didn't contain."); - lastResultingThing = null; - return false; - } - if (GenDrop.TryDropSpawn(thing, dropLoc, map, mode, out lastResultingThing, placedAction, nearPlaceValidator, playDropSound)) - { - Remove(thing); - return true; - } - return false; - } - - public bool TryDropAll(IntVec3 dropLoc, Map map, ThingPlaceMode mode, Action placeAction = null, Predicate nearPlaceValidator = null, bool playDropSound = true) - { - bool result = true; - for (int num = Count - 1; num >= 0; num--) - { - if (!TryDrop(GetAt(num), dropLoc, map, mode, out var _, placeAction, nearPlaceValidator, playDropSound)) - { - result = false; - } - } - return result; - } - - public bool Contains(ThingDef def) - { - return Contains(def, 1); - } - - public bool Contains(ThingDef def, int minCount) - { - if (minCount <= 0) - { - return true; - } - int num = 0; - int count = Count; - for (int i = 0; i < count; i++) - { - if (GetAt(i).def == def) - { - num += GetAt(i).stackCount; - } - if (num >= minCount) - { - return true; - } - } - return false; - } - - public int TotalStackCountOfDef(ThingDef def) - { - int num = 0; - int count = Count; - for (int i = 0; i < count; i++) - { - if (GetAt(i).def == def) - { - num += GetAt(i).stackCount; - } - } - return num; - } - - public void Notify_ContainedItemDestroyed(Thing t) - { - if (ThingOwnerUtility.ShouldAutoRemoveDestroyedThings(owner)) - { - Remove(t); - } - } - - protected virtual void NotifyAdded(Thing item) - { - if (ThingOwnerUtility.ShouldAutoExtinguishInnerThings(owner) && item.HasAttachment(ThingDefOf.Fire)) - { - item.GetAttachment(ThingDefOf.Fire).Destroy(); - } - if (ThingOwnerUtility.ShouldRemoveDesignationsOnAddedThings(owner)) - { - List maps = Find.Maps; - for (int i = 0; i < maps.Count; i++) - { - maps[i].designationManager.RemoveAllDesignationsOn(item); - } - } - if ((owner is Thing thing && thing.Faction.IsPlayerSafe()) || (owner is WorldObject worldObject && worldObject.Faction.IsPlayerSafe()) || (owner is Pawn_InventoryTracker pawn_InventoryTracker && pawn_InventoryTracker.pawn.Faction.IsPlayerSafe())) - { - item.EverSeenByPlayer = true; - } - if (owner is CompTransporter compTransporter) - { - compTransporter.Notify_ThingAdded(item); - } - if (owner is Caravan caravan) - { - caravan.Notify_PawnAdded((Pawn)item); - } - if (owner is Pawn_ApparelTracker pawn_ApparelTracker) - { - pawn_ApparelTracker.Notify_ApparelAdded((Apparel)item); - if (pawn_ApparelTracker.pawn.Faction.IsPlayerSafe()) - { - item.EverSeenByPlayer = true; - } - } - if (owner is Pawn_EquipmentTracker pawn_EquipmentTracker) - { - pawn_EquipmentTracker.Notify_EquipmentAdded((ThingWithComps)item); - if (pawn_EquipmentTracker.pawn.Faction.IsPlayerSafe()) - { - item.EverSeenByPlayer = true; - } - } - NotifyColonistBarIfColonistCorpse(item); - this.OnContentsChanged?.Invoke(); - } - - protected void NotifyAddedAndMergedWith(Thing item, int mergedCount) - { - if (owner is CompTransporter compTransporter) - { - compTransporter.Notify_ThingAddedAndMergedWith(item, mergedCount); - } - } - - protected virtual void NotifyRemoved(Thing item) - { - if (owner is Pawn_InventoryTracker pawn_InventoryTracker) - { - pawn_InventoryTracker.Notify_ItemRemoved(item); - } - if (owner is Pawn_ApparelTracker pawn_ApparelTracker) - { - pawn_ApparelTracker.Notify_ApparelRemoved((Apparel)item); - } - if (owner is Pawn_EquipmentTracker pawn_EquipmentTracker) - { - pawn_EquipmentTracker.Notify_EquipmentRemoved((ThingWithComps)item); - } - if (owner is Caravan caravan) - { - caravan.Notify_PawnRemoved((Pawn)item); - } - NotifyColonistBarIfColonistCorpse(item); - this.OnContentsChanged?.Invoke(); - } - - private void NotifyColonistBarIfColonistCorpse(Thing thing) - { - if (thing is Corpse { Bugged: false } corpse && corpse.InnerPawn.Faction != null && corpse.InnerPawn.Faction.IsPlayer && Current.ProgramState == ProgramState.Playing) - { - Find.ColonistBar.MarkColonistsDirty(); - } - } - - void IList.Insert(int index, Thing item) - { - throw new InvalidOperationException("ThingOwner doesn't allow inserting individual elements at any position."); - } - - void ICollection.Add(Thing item) - { - TryAdd(item); - } - - void ICollection.CopyTo(Thing[] array, int arrayIndex) - { - for (int i = 0; i < Count; i++) - { - array[i + arrayIndex] = GetAt(i); - } - } - - IEnumerator IEnumerable.GetEnumerator() - { - for (int i = 0; i < Count; i++) - { - yield return GetAt(i); - } - } - - IEnumerator IEnumerable.GetEnumerator() - { - for (int i = 0; i < Count; i++) - { - yield return GetAt(i); - } - } -} -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\Verse.AI\Toils_Haul.txt` -**相似度:** 0.6124 - -```csharp -public class Toils_Haul -{ - public static bool ErrorCheckForCarry(Pawn pawn, Thing haulThing, bool canTakeFromInventory = false) - { - if (!haulThing.SpawnedOrAnyParentSpawned || (!canTakeFromInventory && !haulThing.Spawned)) - { - Log.Message(pawn?.ToString() + " tried to start carry " + haulThing?.ToString() + " which isn't spawned."); - pawn.jobs.EndCurrentJob(JobCondition.Incompletable); - return true; - } - if (haulThing.stackCount == 0) - { - Log.Message(pawn?.ToString() + " tried to start carry " + haulThing?.ToString() + " which had stackcount 0."); - pawn.jobs.EndCurrentJob(JobCondition.Incompletable); - return true; - } - if (pawn.jobs.curJob.count <= 0) - { - Log.Error("Invalid count: " + pawn.jobs.curJob.count + ", setting to 1. Job was " + pawn.jobs.curJob); - pawn.jobs.curJob.count = 1; - } - return false; - } - - public static Toil StartCarryThing(TargetIndex haulableInd, bool putRemainderInQueue = false, bool subtractNumTakenFromJobCount = false, bool failIfStackCountLessThanJobCount = false, bool reserve = true, bool canTakeFromInventory = false) - { - Toil toil = ToilMaker.MakeToil("StartCarryThing"); - toil.initAction = delegate - { - Pawn actor = toil.actor; - Job curJob = actor.jobs.curJob; - Thing thing = curJob.GetTarget(haulableInd).Thing; - if (!ErrorCheckForCarry(actor, thing, canTakeFromInventory)) - { - if (curJob.count == 0) - { - throw new Exception($"StartCarryThing job had count = {curJob.count}. Job: {curJob}"); - } - int num = actor.carryTracker.AvailableStackSpace(thing.def); - if (num <= 0) - { - int num2 = actor.carryTracker.MaxStackSpaceEver(thing.def); - int num3 = 0; - if (actor.carryTracker.CarriedThing != null) - { - num3 = actor.carryTracker.CarriedThing.stackCount; - } - throw new Exception($"StartCarryThing got availableStackSpace {num} (haulTarg {thing}, Job: {curJob}, maximum: {num2}, carrying: {num3})"); - } - if (failIfStackCountLessThanJobCount && thing.stackCount < curJob.count) - { - actor.jobs.curDriver.EndJobWith(JobCondition.Incompletable); - } - else - { - int num4 = Mathf.Min(curJob.count, num, thing.stackCount); - if (num4 <= 0) - { - int num5 = actor.carryTracker.MaxStackSpaceEver(thing.def); - int num6 = 0; - if (actor.carryTracker.CarriedThing != null) - { - num6 = actor.carryTracker.CarriedThing.stackCount; - } - throw new Exception($"StartCarryThing zero or negative desiredNumToTake ({num4}), curJob.count: {curJob.count}, availableStackSpace: {num} (maximum: {num5}, carrying: {num6}), haulTarg.stackCount: {thing.stackCount}"); - } - int stackCount = thing.stackCount; - int num7 = actor.carryTracker.TryStartCarry(thing, num4, reserve); - if (num7 == 0) - { - actor.jobs.EndCurrentJob(JobCondition.Incompletable); - } - if (num7 < stackCount) - { - int num8 = curJob.count - num7; - if (putRemainderInQueue && num8 > 0) - { - curJob.GetTargetQueue(haulableInd).Insert(0, thing); - Job job = curJob; - if (job.countQueue == null) - { - job.countQueue = new List(); - } - curJob.countQueue.Insert(0, num8); - } - else if (actor.Map.reservationManager.ReservedBy(thing, actor, curJob)) - { - actor.Map.reservationManager.Release(thing, actor, curJob); - } - } - if (subtractNumTakenFromJobCount) - { - curJob.count -= num7; - } - curJob.SetTarget(haulableInd, actor.carryTracker.CarriedThing); - actor.records.Increment(RecordDefOf.ThingsHauled); - } - } - }; - return toil; - } - - public static Toil StoreThingJob(TargetIndex thingIndex) - { - Toil toil = ToilMaker.MakeToil("StoreThingJob"); - toil.initAction = delegate - { - Pawn actor = toil.actor; - Job curJob = actor.CurJob; - Thing thing = curJob.GetTarget(thingIndex).Thing; - Job job = HaulAIUtility.HaulToStorageJob(actor, thing, curJob.playerForced); - if (job != null) - { - actor.jobs.TryTakeOrderedJob(job, JobTag.Misc); - } - }; - return toil; - } - - public static Toil DropCarriedThing() - { - Toil toil = ToilMaker.MakeToil("DropCarriedThing"); - toil.initAction = delegate - { - Pawn actor = toil.actor; - Thing resultingThing; - if (actor.carryTracker.CarriedThing == null) - { - Log.Error(actor?.ToString() + " tried to drop carried thing but is not carrying anything."); - } - else if (!actor.carryTracker.TryDropCarriedThing(actor.Position, ThingPlaceMode.Direct, out resultingThing)) - { - actor.jobs.EndCurrentJob(JobCondition.Incompletable); - } - }; - return toil; - } - - public static Toil JumpIfAlsoCollectingNextTargetInQueue(Toil gotoGetTargetToil, TargetIndex ind) - { - Toil toil = ToilMaker.MakeToil("JumpIfAlsoCollectingNextTargetInQueue"); - toil.initAction = delegate - { - Pawn actor = toil.actor; - Job curJob = actor.jobs.curJob; - List targetQueue = curJob.GetTargetQueue(ind); - if (!targetQueue.NullOrEmpty() && curJob.count > 0) - { - if (actor.carryTracker.CarriedThing == null) - { - Log.Error("JumpToAlsoCollectTargetInQueue run on " + actor?.ToString() + " who is not carrying something."); - } - else if (actor.carryTracker.AvailableStackSpace(actor.carryTracker.CarriedThing.def) > 0) - { - for (int i = 0; i < targetQueue.Count; i++) - { - if (!GenAI.CanUseItemForWork(actor, targetQueue[i].Thing)) - { - actor.jobs.EndCurrentJob(JobCondition.Incompletable); - break; - } - if (targetQueue[i].Thing.def == actor.carryTracker.CarriedThing.def) - { - curJob.SetTarget(ind, targetQueue[i].Thing); - targetQueue.RemoveAt(i); - actor.jobs.curDriver.JumpToToil(gotoGetTargetToil); - break; - } - } - } - } - }; - return toil; - } - - public static Toil CheckForGetOpportunityDuplicate(Toil getHaulTargetToil, TargetIndex haulableInd, TargetIndex storeCellInd, bool takeFromValidStorage = false, Predicate extraValidator = null) - { - Toil toil = ToilMaker.MakeToil("CheckForGetOpportunityDuplicate"); - toil.initAction = delegate - { - Pawn actor = toil.actor; - Job curJob = actor.jobs.curJob; - if (actor.carryTracker.CarriedThing.def.stackLimit != 1 && !actor.carryTracker.Full && curJob.count > 0) - { - Thing thing = GenClosest.ClosestThingReachable(actor.Position, actor.Map, ThingRequest.ForGroup(ThingRequestGroup.HaulableAlways), PathEndMode.ClosestTouch, TraverseParms.For(actor), 8f, DupeValidator); - if (thing != null) - { - curJob.SetTarget(haulableInd, thing); - actor.jobs.curDriver.JumpToToil(getHaulTargetToil); - } - } - bool DupeValidator(Thing t) - { - if (!t.Spawned) - { - return false; - } - if (t.def != actor.carryTracker.CarriedThing.def) - { - return false; - } - if (!t.CanStackWith(actor.carryTracker.CarriedThing)) - { - return false; - } - if (t.IsForbidden(actor)) - { - return false; - } - if (!t.IsSociallyProper(actor, forPrisoner: false, animalsCare: true)) - { - return false; - } - if (takeFromValidStorage && storeCellInd != 0 && curJob.GetTarget(storeCellInd).Cell.TryGetSlotGroup(actor.Map, out var group) && t.TryGetValidStoragePriority(out var priority) && (int)priority >= (int)group.Settings.Priority) - { - return false; - } - if (storeCellInd != 0 && !curJob.GetTarget(storeCellInd).Cell.IsValidStorageFor(actor.Map, t)) - { - return false; - } - if (!actor.CanReserve(t)) - { - return false; - } - if (extraValidator != null && !extraValidator(t)) - { - return false; - } - return true; - } - }; - return toil; - } - - public static Toil CarryHauledThingToCell(TargetIndex squareIndex, PathEndMode pathEndMode = PathEndMode.ClosestTouch) - { - Toil toil = ToilMaker.MakeToil("CarryHauledThingToCell"); - toil.initAction = delegate - { - IntVec3 cell3 = toil.actor.jobs.curJob.GetTarget(squareIndex).Cell; - toil.actor.pather.StartPath(cell3, pathEndMode); - }; - toil.defaultCompleteMode = ToilCompleteMode.PatherArrival; - toil.AddEndCondition(delegate - { - Pawn actor2 = toil.actor; - IntVec3 cell2 = actor2.jobs.curJob.GetTarget(squareIndex).Cell; - CompPushable compPushable2 = actor2.carryTracker.CarriedThing.TryGetComp(); - if (compPushable2 != null) - { - Vector3 v = actor2.Position.ToVector3() + compPushable2.drawPos; - if (new IntVec3(v) == cell2) - { - return JobCondition.Succeeded; - } - } - return JobCondition.Ongoing; - }); - toil.AddFailCondition(delegate - { - Pawn actor = toil.actor; - IntVec3 cell = actor.jobs.curJob.GetTarget(squareIndex).Cell; - if (actor.carryTracker.CarriedThing == null) - { - return true; - } - if (actor.jobs.curJob.haulMode == HaulMode.ToCellStorage && !cell.IsValidStorageFor(actor.Map, actor.carryTracker.CarriedThing)) - { - return true; - } - CompPushable compPushable = actor.carryTracker.CarriedThing.TryGetComp(); - return (compPushable != null && !compPushable.canBePushed) ? true : false; - }); - return toil; - } - - public static Toil PlaceCarriedThingInCellFacing(TargetIndex facingTargetInd) - { - Toil toil = ToilMaker.MakeToil("PlaceCarriedThingInCellFacing"); - toil.initAction = delegate - { - Pawn actor = toil.actor; - if (actor.carryTracker.CarriedThing == null) - { - Log.Error(actor?.ToString() + " tried to place hauled thing in facing cell but is not hauling anything."); - } - else - { - LocalTargetInfo target = actor.CurJob.GetTarget(facingTargetInd); - IntVec3 intVec = ((!target.HasThing) ? target.Cell : target.Thing.OccupiedRect().ClosestCellTo(actor.Position)); - IntVec3 dropLoc = actor.Position + Pawn_RotationTracker.RotFromAngleBiased((actor.Position - intVec).AngleFlat).FacingCell; - if (!actor.carryTracker.TryDropCarriedThing(dropLoc, ThingPlaceMode.Direct, out var _)) - { - actor.jobs.EndCurrentJob(JobCondition.Incompletable); - } - } - }; - return toil; - } - - public static Toil PlaceHauledThingInCell(TargetIndex cellInd, Toil nextToilOnPlaceFailOrIncomplete, bool storageMode, bool tryStoreInSameStorageIfSpotCantHoldWholeStack = false) - { - Toil toil = ToilMaker.MakeToil("PlaceHauledThingInCell"); - toil.initAction = delegate - { - Pawn actor = toil.actor; - Job curJob = actor.jobs.curJob; - IntVec3 cell = curJob.GetTarget(cellInd).Cell; - if (actor.carryTracker.CarriedThing == null) - { - Log.Error(actor?.ToString() + " tried to place hauled thing in cell but is not hauling anything."); - } - else - { - SlotGroup slotGroup = actor.Map.haulDestinationManager.SlotGroupAt(cell); - if (slotGroup != null && slotGroup.Settings.AllowedToAccept(actor.carryTracker.CarriedThing)) - { - actor.Map.designationManager.TryRemoveDesignationOn(actor.carryTracker.CarriedThing, DesignationDefOf.Haul); - } - Action placedAction = null; - if (curJob.def == JobDefOf.DoBill || curJob.def == JobDefOf.RecolorApparel || curJob.def == JobDefOf.RefuelAtomic || curJob.def == JobDefOf.RearmTurretAtomic) - { - placedAction = delegate(Thing th, int added) - { - HaulAIUtility.UpdateJobWithPlacedThings(curJob, th, added); - }; - } - if (!actor.carryTracker.TryDropCarriedThing(cell, ThingPlaceMode.Direct, out var _, placedAction)) - { - if (storageMode) - { - IntVec3 storeCell; - if (nextToilOnPlaceFailOrIncomplete != null && ((tryStoreInSameStorageIfSpotCantHoldWholeStack && StoreUtility.TryFindBestBetterStoreCellForIn(actor.carryTracker.CarriedThing, actor, actor.Map, StoragePriority.Unstored, actor.Faction, curJob.bill.GetSlotGroup(), out var foundCell)) || StoreUtility.TryFindBestBetterStoreCellFor(actor.carryTracker.CarriedThing, actor, actor.Map, StoragePriority.Unstored, actor.Faction, out foundCell))) - { - if (actor.CanReserve(foundCell)) - { - actor.Reserve(foundCell, actor.CurJob); - } - actor.CurJob.SetTarget(cellInd, foundCell); - actor.jobs.curDriver.JumpToToil(nextToilOnPlaceFailOrIncomplete); - } - else if (HaulAIUtility.CanHaulAside(actor, actor.carryTracker.CarriedThing, out storeCell)) - { - curJob.SetTarget(cellInd, storeCell); - curJob.count = int.MaxValue; - curJob.haulOpportunisticDuplicates = false; - curJob.haulMode = HaulMode.ToCellNonStorage; - if (nextToilOnPlaceFailOrIncomplete != null) - { - actor.jobs.curDriver.JumpToToil(nextToilOnPlaceFailOrIncomplete); - } - } - else - { - Log.Warning($"Incomplete haul for {actor}: Could not find anywhere to put {actor.carryTracker.CarriedThing} near {actor.Position}. Destroying. This should be very uncommon!"); - actor.carryTracker.CarriedThing.Destroy(); - } - } - else if (nextToilOnPlaceFailOrIncomplete != null) - { - actor.jobs.curDriver.JumpToToil(nextToilOnPlaceFailOrIncomplete); - } - } - } - }; - return toil; - } - - public static Toil CarryHauledThingToContainer() - { - Toil gotoDest = ToilMaker.MakeToil("CarryHauledThingToContainer"); - gotoDest.initAction = delegate - { - gotoDest.actor.pather.StartPath(gotoDest.actor.jobs.curJob.targetB.Thing, PathEndMode.Touch); - }; - gotoDest.AddFailCondition(delegate - { - Thing thing = gotoDest.actor.jobs.curJob.targetB.Thing; - if (thing.Destroyed || (!gotoDest.actor.jobs.curJob.ignoreForbidden && thing.IsForbidden(gotoDest.actor))) - { - return true; - } - ThingOwner thingOwner = thing.TryGetInnerInteractableThingOwner(); - return (thingOwner != null && !thingOwner.CanAcceptAnyOf(gotoDest.actor.carryTracker.CarriedThing)) ? true : false; - }); - gotoDest.defaultCompleteMode = ToilCompleteMode.PatherArrival; - return gotoDest; - } - - public static Toil DepositHauledThingInContainer(TargetIndex containerInd, TargetIndex reserveForContainerInd, Action onDeposited = null) - { - Toil toil = ToilMaker.MakeToil("DepositHauledThingInContainer"); - toil.initAction = delegate - { - Pawn actor = toil.actor; - Job curJob = actor.jobs.curJob; - if (actor.carryTracker.CarriedThing == null) - { - Log.Error(actor?.ToString() + " tried to place hauled thing in container but is not hauling anything."); - } - else - { - Thing thing = curJob.GetTarget(containerInd).Thing; - ThingOwner thingOwner = thing.TryGetInnerInteractableThingOwner(); - if (thingOwner != null) - { - int num = actor.carryTracker.CarriedThing.stackCount; - if (thing is IHaulEnroute haulEnroute) - { - ThingDef def = actor.carryTracker.CarriedThing.def; - num = Mathf.Min(haulEnroute.GetSpaceRemainingWithEnroute(def, actor), num); - if (reserveForContainerInd != 0) - { - Thing thing2 = curJob.GetTarget(reserveForContainerInd).Thing; - if (!thing2.DestroyedOrNull() && thing2 != haulEnroute && thing2 is IHaulEnroute enroute) - { - int spaceRemainingWithEnroute = enroute.GetSpaceRemainingWithEnroute(def, actor); - num = Mathf.Min(num, actor.carryTracker.CarriedThing.stackCount - spaceRemainingWithEnroute); - } - } - } - Thing carriedThing = actor.carryTracker.CarriedThing; - int num2 = actor.carryTracker.innerContainer.TryTransferToContainer(carriedThing, thingOwner, num); - if (num2 != 0) - { - if (thing is IHaulEnroute container) - { - thing.Map.enrouteManager.ReleaseFor(container, actor); - } - if (thing is INotifyHauledTo notifyHauledTo) - { - notifyHauledTo.Notify_HauledTo(actor, carriedThing, num2); - } - if (thing is ThingWithComps thingWithComps) - { - foreach (ThingComp allComp in thingWithComps.AllComps) - { - if (allComp is INotifyHauledTo notifyHauledTo2) - { - notifyHauledTo2.Notify_HauledTo(actor, carriedThing, num2); - } - } - } - if (curJob.def == JobDefOf.DoBill) - { - HaulAIUtility.UpdateJobWithPlacedThings(curJob, carriedThing, num2); - } - onDeposited?.Invoke(); - } - } - else if (curJob.GetTarget(containerInd).Thing.def.Minifiable) - { - actor.carryTracker.innerContainer.ClearAndDestroyContents(); - } - else - { - Log.Error("Could not deposit hauled thing in container: " + curJob.GetTarget(containerInd).Thing); - } - } - }; - return toil; - } - - public static Toil JumpToCarryToNextContainerIfPossible(Toil carryToContainerToil, TargetIndex primaryTargetInd) - { - Toil toil = ToilMaker.MakeToil("JumpToCarryToNextContainerIfPossible"); - toil.debugName = "Jump carry if possible"; - toil.initAction = delegate - { - Pawn actor = toil.actor; - Job curJob = actor.jobs.curJob; - if (actor.carryTracker.CarriedThing != null && curJob.targetQueueB != null && curJob.targetQueueB.Count > 0) - { - if (TryGetNextDestinationFromQueue(primaryTargetInd, TargetIndex.B, actor.carryTracker.CarriedThing.def, curJob, actor, out var nextTarget)) - { - curJob.targetQueueB.RemoveAll((LocalTargetInfo target) => target.Thing == nextTarget); - curJob.targetB = nextTarget; - curJob.targetC = nextTarget; - actor.jobs.curDriver.JumpToToil(carryToContainerToil); - } - } - }; - return toil; - } - - public static bool TryGetNextDestinationFromQueue(TargetIndex primaryIndex, TargetIndex destIndex, ThingDef stuff, Job job, Pawn actor, out Thing target) - { - Thing primaryTarget = job.GetTarget(primaryIndex).Thing; - target = null; - if (actor.carryTracker?.CarriedThing == null) - { - return false; - } - bool hasSpareItems = actor.carryTracker.CarriedThing.stackCount > 0; - if (primaryTarget != null && primaryTarget.Spawned && primaryTarget is IHaulEnroute enroute) - { - int spaceRemainingWithEnroute = enroute.GetSpaceRemainingWithEnroute(stuff, actor); - hasSpareItems = actor.carryTracker.CarriedThing.stackCount > spaceRemainingWithEnroute; - } - target = GenClosest.ClosestThing_Global_Reachable(actor.Position, actor.Map, from x in job.GetTargetQueue(destIndex) - select x.Thing, PathEndMode.Touch, TraverseParms.For(actor), 99999f, Validator); - return target != null; - bool Validator(Thing th) - { - if (!(th is IHaulEnroute enroute2)) - { - return false; - } - if (enroute2.GetSpaceRemainingWithEnroute(stuff, actor) <= 0) - { - return false; - } - if (th != primaryTarget && !hasSpareItems) - { - return false; - } - return true; - } - } - - public static Toil TakeToInventory(TargetIndex ind, int count) - { - return TakeToInventory(ind, count, null, null); - } - - private static Toil TakeToInventory(TargetIndex ind, int? count, Func countGetter, Func countGetterPassingThing) - { - Toil takeThing = ToilMaker.MakeToil("TakeToInventory"); - takeThing.initAction = delegate - { - Pawn actor = takeThing.actor; - Thing thing = actor.CurJob.GetTarget(ind).Thing; - if (!ErrorCheckForCarry(actor, thing)) - { - int num = Mathf.Min(count ?? countGetterPassingThing?.Invoke(thing) ?? countGetter(), thing.stackCount); - if (actor.CurJob.checkEncumbrance) - { - num = Math.Min(num, MassUtility.CountToPickUpUntilOverEncumbered(actor, thing)); - } - if (num <= 0) - { - actor.jobs.curDriver.ReadyForNextToil(); - } - else - { - actor.inventory.GetDirectlyHeldThings().TryAdd(thing.SplitOff(num)); - if (thing.def.ingestible != null && (int)thing.def.ingestible.preferability <= 5) - { - actor.mindState.lastInventoryRawFoodUseTick = Find.TickManager.TicksGame; - } - thing.def.soundPickup.PlayOneShot(new TargetInfo(actor.Position, actor.Map)); - } - } - }; - return takeThing; - } - - public static Toil TakeToInventory(TargetIndex ind, Func countGetter) - { - return TakeToInventory(ind, null, countGetter, null); - } - - public static Toil TakeToInventory(TargetIndex ind, Func countGetter) - { - return TakeToInventory(ind, null, null, countGetter); - } - - public static Toil TakeFromOtherInventory(Thing item, ThingOwner taker, ThingOwner holder, int count = -1, TargetIndex indexToSet = TargetIndex.None) - { - Toil toil = ToilMaker.MakeToil("TakeFromOtherInventory"); - toil.initAction = delegate - { - if (!holder.Contains(item)) - { - toil.actor.jobs.EndCurrentJob(JobCondition.Incompletable); - } - else - { - count = ((count < 0) ? toil.actor.jobs.curJob.count : count); - holder.TryTransferToContainer(item, taker, Mathf.Min(item.stackCount, count), out var resultingTransferredItem); - if (resultingTransferredItem == null) - { - Log.Warning($"Taker {toil.actor.Label} unable to take count {count} of thing {item.Label} from holder's inventory"); - toil.actor.jobs.EndCurrentJob(JobCondition.Incompletable); - } - else if (indexToSet != 0) - { - toil.actor.jobs.curJob.SetTarget(indexToSet, resultingTransferredItem); - } - } - }; - return toil; - } - - public static Toil CheckItemCarriedByOtherPawn(Thing item, TargetIndex targetPawnIfCarried = TargetIndex.None, Toil jumpIfCarriedByOther = null) - { - Toil toil = ToilMaker.MakeToil("CheckItemCarriedByOtherPawn"); - toil.initAction = delegate - { - Pawn pawn = (item?.ParentHolder as Pawn_InventoryTracker)?.pawn; - if (pawn != null && pawn != toil.actor) - { - if (targetPawnIfCarried != 0) - { - toil.actor.jobs.curJob.SetTarget(targetPawnIfCarried, pawn); - } - if (jumpIfCarriedByOther != null) - { - toil.actor.jobs.curDriver.JumpToToil(jumpIfCarriedByOther); - } - } - }; - toil.defaultCompleteMode = ToilCompleteMode.Instant; - toil.atomicWithPrevious = true; - return toil; - } -} -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\PawnUtility.txt` -**相似度:** 0.5783 - -```csharp -public static class PawnUtility -{ - private static List tmpPawns = new List(); - - private static List tmpPawnKindsStr = new List(); - - private static HashSet tmpAddedPawnKinds = new HashSet(); - - private static List tmpPawnKinds = new List(); - - private static List tmpThings = new List(); - - public static Faction GetFactionLeaderFaction(Pawn pawn) - { - List allFactionsListForReading = Find.FactionManager.AllFactionsListForReading; - for (int i = 0; i < allFactionsListForReading.Count; i++) - { - if (allFactionsListForReading[i].leader == pawn) - { - return allFactionsListForReading[i]; - } - } - return null; - } - - public static bool IsFactionLeader(Pawn pawn) - { - return GetFactionLeaderFaction(pawn) != null; - } - - public static bool IsInteractionBlocked(this Pawn pawn, InteractionDef interaction, bool isInitiator, bool isRandom) - { - MentalStateDef mentalStateDef = pawn.MentalStateDef; - if (mentalStateDef != null) - { - if (isRandom) - { - return mentalStateDef.blockRandomInteraction; - } - if (interaction == null) - { - return false; - } - List list = (isInitiator ? mentalStateDef.blockInteractionInitiationExcept : mentalStateDef.blockInteractionRecipientExcept); - if (list != null) - { - return !list.Contains(interaction); - } - return false; - } - List hediffs = pawn.health.hediffSet.hediffs; - for (int i = 0; i < hediffs.Count; i++) - { - if (hediffs[i].def.blocksSocialInteraction) - { - return true; - } - } - Lord lord = pawn.GetLord(); - if (lord != null && lord.BlocksSocialInteraction(pawn)) - { - return true; - } - return false; - } - - public static bool IsKidnappedPawn(Pawn pawn) - { - List allFactionsListForReading = Find.FactionManager.AllFactionsListForReading; - for (int i = 0; i < allFactionsListForReading.Count; i++) - { - if (allFactionsListForReading[i].kidnapped.KidnappedPawnsListForReading.Contains(pawn)) - { - return true; - } - } - return false; - } - - public static bool IsTravelingInTransportPodWorldObject(Pawn pawn) - { - if (!pawn.IsWorldPawn() || !ThingOwnerUtility.AnyParentIs(pawn)) - { - return ThingOwnerUtility.AnyParentIs(pawn); - } - return true; - } - - public static bool ForSaleBySettlement(Pawn pawn) - { - return pawn.ParentHolder is Settlement_TraderTracker; - } - - public static bool IsCarrying(this Pawn pawn) - { - if (!pawn.Destroyed && pawn.carryTracker != null) - { - return pawn.carryTracker.CarriedThing != null; - } - return false; - } - - public static bool IsCarryingPawn(this Pawn pawn, Pawn carryPawn = null) - { - if (pawn.carryTracker != null && pawn.carryTracker.CarriedThing is Pawn) - { - if (carryPawn != null) - { - return pawn.carryTracker.CarriedThing == carryPawn; - } - return true; - } - return false; - } - - public static bool IsCarryingThing(this Pawn pawn, Thing carriedThing) - { - if (pawn.carryTracker != null && pawn.carryTracker.CarriedThing != null) - { - return pawn.carryTracker.CarriedThing == carriedThing; - } - return false; - } - - public static void TryDestroyStartingColonistFamily(Pawn pawn) - { - if (!pawn.relations.RelatedPawns.Any((Pawn x) => Find.GameInitData.startingAndOptionalPawns.Contains(x))) - { - DestroyStartingColonistFamily(pawn); - } - } - - public static void DestroyStartingColonistFamily(Pawn pawn) - { - foreach (Pawn item in pawn.relations.RelatedPawns.ToList()) - { - if (!Find.GameInitData.startingAndOptionalPawns.Contains(item)) - { - WorldPawnSituation situation = Find.WorldPawns.GetSituation(item); - if (situation == WorldPawnSituation.Free || situation == WorldPawnSituation.Dead) - { - Find.WorldPawns.RemovePawn(item); - Find.WorldPawns.PassToWorld(item, PawnDiscardDecideMode.Discard); - } - } - } - } - - public static bool EnemiesAreNearby(Pawn pawn, int regionsToScan = 9, bool passDoors = false, float maxDistance = -1f, int maxCount = 1, bool invisible = false) - { - TraverseParms tp = (passDoors ? TraverseParms.For(TraverseMode.PassDoors) : TraverseParms.For(pawn)); - int count = 0; - RegionTraverser.BreadthFirstTraverse(pawn.Position, pawn.Map, (Region from, Region to) => to.Allows(tp, isDestination: false), delegate(Region r) - { - List list = r.ListerThings.ThingsInGroup(ThingRequestGroup.AttackTarget); - for (int i = 0; i < list.Count; i++) - { - Thing thing = list[i]; - if ((maxDistance <= 0f || thing.Position.InHorDistOf(pawn.Position, maxDistance)) && thing.HostileTo(pawn) && (invisible || !(thing is Pawn pawn2) || !pawn2.IsPsychologicallyInvisible())) - { - count++; - } - } - return count >= maxCount; - }, regionsToScan); - return count >= maxCount; - } - - public static bool WillSoonHaveBasicNeed(Pawn p, float thresholdOffset = 0.05f) - { - if (p.needs == null) - { - return false; - } - if (p.needs.rest != null && p.needs.rest.CurLevel < 0.28f + thresholdOffset) - { - return true; - } - if (p.needs.food != null && p.needs.food.CurLevelPercentage < p.needs.food.PercentageThreshHungry + thresholdOffset) - { - return true; - } - return false; - } - - public static bool CanCasuallyInteractNow(this Pawn p, bool twoWayInteraction = false, bool canInteractWhileSleeping = false, bool canInteractWhileRoaming = false, bool canInteractWhileDrafted = false) - { - if (p.Drafted && !canInteractWhileDrafted) - { - return false; - } - if (p.IsPsychologicallyInvisible()) - { - return false; - } - if (ThinkNode_ConditionalShouldFollowMaster.ShouldFollowMaster(p)) - { - return false; - } - if (p.InAggroMentalState) - { - return false; - } - if (p.InMentalState && p.MentalStateDef == MentalStateDefOf.Roaming && !canInteractWhileRoaming) - { - return false; - } - if (!p.Awake() && !canInteractWhileSleeping) - { - return false; - } - if (p.IsFormingCaravan()) - { - return false; - } - Job curJob = p.CurJob; - if (curJob != null && twoWayInteraction && (!curJob.def.casualInterruptible || !curJob.playerForced)) - { - return false; - } - return true; - } - - public static IEnumerable SpawnedMasteredPawns(Pawn master) - { - if (Current.ProgramState != ProgramState.Playing || master.Faction == null || !master.RaceProps.Humanlike || !master.Spawned) - { - yield break; - } - List pawns = master.Map.mapPawns.SpawnedPawnsInFaction(master.Faction); - for (int i = 0; i < pawns.Count; i++) - { - if (pawns[i].playerSettings != null && pawns[i].playerSettings.Master == master) - { - yield return pawns[i]; - } - } - } - - public static bool InValidState(Pawn p) - { - if (p.health == null) - { - return false; - } - if (!p.Dead && (p.stances == null || p.mindState == null || p.needs == null || p.ageTracker == null)) - { - return false; - } - return true; - } - - public static PawnPosture GetPosture(this Pawn p) - { - PawnPosture pawnPosture = (p.Dead ? PawnPosture.LayingOnGroundNormal : ((!ModsConfig.BiotechActive || !p.IsCharging()) ? ((!(p.ParentHolder is IThingHolderWithDrawnPawn thingHolderWithDrawnPawn)) ? (p.Downed ? ((p.jobs == null || !p.jobs.posture.Laying()) ? PawnPosture.LayingOnGroundNormal : p.jobs.posture) : ((p.jobs != null) ? p.jobs.posture : PawnPosture.Standing)) : thingHolderWithDrawnPawn.HeldPawnPosture) : PawnPosture.Standing)); - Pawn_MindState mindState = p.mindState; - if (mindState != null && mindState.duty?.def?.forceFaceUpPosture == true && pawnPosture != 0) - { - pawnPosture |= PawnPosture.FaceUpMask; - } - return pawnPosture; - } - - public static void ForceWait(Pawn pawn, int ticks, Thing faceTarget = null, bool maintainPosture = false, bool maintainSleep = false) - { - if (ticks <= 0) - { - Log.ErrorOnce("Forcing a wait for zero ticks", 47045639); - } - JobDef def = (maintainPosture ? JobDefOf.Wait_MaintainPosture : JobDefOf.Wait); - if (pawn.IsDeactivated()) - { - def = JobDefOf.Deactivated; - } - if (pawn.IsSelfShutdown()) - { - def = JobDefOf.SelfShutdown; - } - else if (pawn.InBed()) - { - def = (pawn.Awake() ? JobDefOf.LayDownAwake : JobDefOf.LayDown); - } - else if (!pawn.health.capacities.CanBeAwake) - { - def = JobDefOf.Wait_Downed; - } - else if (maintainSleep && !pawn.Awake()) - { - def = JobDefOf.Wait_Asleep; - } - Job job = JobMaker.MakeJob(def, faceTarget); - if (maintainSleep && !pawn.Awake()) - { - job.forceSleep = true; - job.targetA = pawn.Position; - } - if (pawn.InBed()) - { - job.targetA = pawn.CurrentBed(); - } - job.expiryInterval = ticks; - pawn.jobs.StartJob(job, JobCondition.InterruptForced, null, resumeCurJobAfterwards: true); - } - - public static void GainComfortFromCellIfPossible(this Pawn p, int delta, bool chairsOnly = false) - { - if (p.Spawned && p.IsHashIntervalTick(15, delta)) - { - Building edifice = p.Position.GetEdifice(p.Map); - if (edifice != null && (!chairsOnly || (edifice.def.category == ThingCategory.Building && edifice.def.building.isSittable))) - { - GainComfortFromThingIfPossible(p, edifice, delta); - } - } - } - - public static void GainComfortFromThingIfPossible(Pawn p, Thing from, int delta) - { - if (p.IsHashIntervalTick(15, delta)) - { - float statValue = from.GetStatValue(StatDefOf.Comfort, applyPostProcess: true, 100); - if (statValue >= 0f && p.needs != null && p.needs.comfort != null) - { - p.needs.comfort.ComfortUsed(statValue); - } - } - } - - public static float BodyResourceGrowthSpeed(Pawn pawn) - { - return pawn.needs?.food?.CurCategory.HungerMultiplier() ?? 1f; - } - - public static bool FertileMateTarget(Pawn male, Pawn female) - { - if (female.gender != Gender.Female || female.Sterile()) - { - return false; - } - CompEggLayer compEggLayer = female.TryGetComp(); - if (compEggLayer != null) - { - return !compEggLayer.FullyFertilized; - } - return true; - } - - public static void Mated(Pawn male, Pawn female) - { - if (!female.Sterile() && !male.Sterile()) - { - CompEggLayer compEggLayer = female.TryGetComp(); - if (compEggLayer != null) - { - compEggLayer.Fertilize(male); - } - else if (Rand.Value < 0.5f) - { - Hediff_Pregnant hediff_Pregnant = (Hediff_Pregnant)HediffMaker.MakeHediff(HediffDefOf.Pregnant, female); - hediff_Pregnant.SetParents(null, male, null); - female.health.AddHediff(hediff_Pregnant); - } - } - } - - public static bool PlayerForcedJobNowOrSoon(Pawn pawn) - { - if (pawn.jobs == null) - { - return false; - } - Job curJob = pawn.CurJob; - if (curJob != null) - { - return curJob.playerForced; - } - if (pawn.jobs.jobQueue.Count > 0) - { - return pawn.jobs.jobQueue.Peek().job.playerForced; - } - return false; - } - - public static bool TrySpawnHatchedOrBornPawn(Pawn pawn, Thing motherOrEgg, IntVec3? positionOverride = null) - { - if (motherOrEgg.SpawnedOrAnyParentSpawned) - { - return GenSpawn.Spawn(pawn, positionOverride ?? motherOrEgg.PositionHeld, motherOrEgg.MapHeld) != null; - } - if (motherOrEgg is Pawn pawn2) - { - if (pawn2.IsCaravanMember()) - { - pawn2.GetCaravan().AddPawn(pawn, addCarriedPawnToWorldPawnsIfAny: true); - Find.WorldPawns.PassToWorld(pawn); - return true; - } - if (pawn2.IsWorldPawn()) - { - Find.WorldPawns.PassToWorld(pawn); - return true; - } - } - else if (motherOrEgg.ParentHolder != null && motherOrEgg.ParentHolder is Pawn_InventoryTracker pawn_InventoryTracker) - { - if (pawn_InventoryTracker.pawn.IsCaravanMember()) - { - pawn_InventoryTracker.pawn.GetCaravan().AddPawn(pawn, addCarriedPawnToWorldPawnsIfAny: true); - Find.WorldPawns.PassToWorld(pawn); - return true; - } - if (pawn_InventoryTracker.pawn.IsWorldPawn()) - { - Find.WorldPawns.PassToWorld(pawn); - return true; - } - } - return false; - } - - public static bool TryGetAvoidGrid(this Pawn p, out AvoidGrid grid, bool onlyIfLordAllows = true) - { - grid = null; - if (!p.Spawned) - { - return false; - } - if (p.Faction == null) - { - return false; - } - if (!p.Faction.def.canUseAvoidGrid) - { - return false; - } - if (p.Faction == Faction.OfPlayer || !p.Faction.HostileTo(Faction.OfPlayer)) - { - return false; - } - if (p.kindDef.canUseAvoidGrid) - { - grid = p.Map.avoidGrid; - return true; - } - if (onlyIfLordAllows) - { - Lord lord = p.GetLord(); - LordToil lordToil = lord?.CurLordToil; - if (lordToil != null && lordToil.useAvoidGrid) - { - grid = lord.Map.avoidGrid; - return true; - } - return false; - } - grid = p.Map.avoidGrid; - return true; - } - - public static bool ShouldCollideWithPawns(Pawn p) - { - if (p == null || p.Downed || p.Dead) - { - return false; - } - if (p.IsShambler) - { - return true; - } - if (!p.mindState.anyCloseHostilesRecently) - { - return false; - } - if (p.IsPsychologicallyInvisible()) - { - return false; - } - if (!p.kindDef.collidesWithPawns) - { - return false; - } - return true; - } - - public static bool AnyPawnBlockingPathAt(IntVec3 c, Pawn forPawn, bool actAsIfHadCollideWithPawnsJob = false, bool collideOnlyWithStandingPawns = false, bool forPathFinder = false, bool useId = false) - { - return PawnBlockingPathAt(c, forPawn, actAsIfHadCollideWithPawnsJob, collideOnlyWithStandingPawns, forPathFinder, useId) != null; - } - - public static Pawn PawnBlockingPathAt(IntVec3 c, Pawn forPawn, bool actAsIfHadCollideWithPawnsJob = false, bool collideOnlyWithStandingPawns = false, bool forPathFinder = false, bool useId = false) - { - List thingList = c.GetThingList(forPawn.Map); - if (thingList.Count == 0) - { - return null; - } - bool collideWithNonHostile = false; - if (actAsIfHadCollideWithPawnsJob) - { - collideWithNonHostile = true; - } - else - { - Job curJob = forPawn.CurJob; - if (curJob != null && (curJob.collideWithPawns || curJob.def.collideWithPawns || forPawn.jobs.curDriver.collideWithPawns)) - { - collideWithNonHostile = true; - } - } - for (int i = 0; i < thingList.Count; i++) - { - Pawn pawn = thingList[i] as Pawn; - if (PawnBlockedBy(forPawn, pawn, collideOnlyWithStandingPawns, collideWithNonHostile, forPathFinder, useId)) - { - return pawn; - } - } - return null; - } - - public static bool PawnBlockedBy(Pawn forPawn, Pawn other, bool collideOnlyWithStandingPawns = false, bool collideWithNonHostile = false, bool forPathFinder = false, bool useId = false) - { - if (!ShouldCollideWithPawns(other)) - { - return false; - } - if (useId && forPawn.thingIDNumber < other.thingIDNumber && !other.stances.FullBodyBusyRecently) - { - return false; - } - if (other == forPawn) - { - return false; - } - if (collideOnlyWithStandingPawns) - { - if (other.pather.MovingNow) - { - return false; - } - if (other.pather.Moving && other.pather.MovedRecently(60)) - { - return false; - } - } - if (PawnsCanShareCellBecauseOfBodySize(other, forPawn)) - { - return false; - } - if (other.IsPsychologicallyInvisible()) - { - return false; - } - if (!other.kindDef.collidesWithPawns) - { - return false; - } - if (other.HostileTo(forPawn)) - { - return true; - } - if (forPawn.IsShambler && !MutantUtility.ShamblerShouldCollideWith(forPawn, other)) - { - return false; - } - if (collideWithNonHostile) - { - if (!forPathFinder && forPawn.Drafted && other.RaceProps.Animal) - { - return false; - } - Job curJob = other.CurJob; - if (curJob != null && (curJob.collideWithPawns || curJob.def.collideWithPawns || other.jobs.curDriver.collideWithPawns)) - { - return true; - } - } - return false; - } - - private static bool PawnsCanShareCellBecauseOfBodySize(Pawn p1, Pawn p2) - { - float bodySize = p1.BodySize; - float bodySize2 = p2.BodySize; - if (bodySize >= 1.5f || bodySize2 >= 1.5f) - { - return false; - } - float num = bodySize / bodySize2; - if (num < 1f) - { - num = 1f / num; - } - return num > 3.57f; - } - - public static bool KnownDangerAt(IntVec3 c, Map map, Pawn forPawn) - { - return c.GetEdifice(map)?.IsDangerousFor(forPawn) ?? false; - } - - [Obsolete("Lord and job report display validation is now checked separately.")] - public static bool ShouldDisplayActionInInspectString(Pawn p) - { - if (p.Faction != Faction.OfPlayer && p.HostFaction != Faction.OfPlayer) - { - return false; - } - if (p.InMentalState) - { - return false; - } - if (p.IsMutant && p.mutant.Def.overrideInspectString) - { - return false; - } - return true; - } - - public static bool ShouldDisplayLordReport(Pawn pawn) - { - if (ShouldShowCultistLordReport(pawn)) - { - return true; - } - return ShouldShowActionReportToPlayer(pawn); - } - - public static bool ShouldDisplayJobReport(Pawn pawn) - { - if (pawn.IsMutant && pawn.mutant.Def.overrideInspectString) - { - return false; - } - if (pawn.CurJobDef != null && pawn.CurJobDef.alwaysShowReport) - { - return true; - } - if (ModsConfig.AnomalyActive && pawn.Faction == Faction.OfHoraxCult && pawn.CurJobDef == JobDefOf.HateChanting) - { - return true; - } - if (ShouldShowCultistLordReport(pawn)) - { - return true; - } - return ShouldShowActionReportToPlayer(pawn); - } - - private static bool ShouldShowActionReportToPlayer(Pawn p) - { - if (p.Faction != Faction.OfPlayer && p.HostFaction != Faction.OfPlayer) - { - return false; - } - if (p.InMentalState) - { - return false; - } - if (p.IsMutant && p.mutant.Def.overrideInspectString) - { - return false; - } - return true; - } - - public static bool ShouldDisplayFactionInInspectString(Pawn p) - { - if (p.IsMutant && p.mutant.Def.overrideInspectString) - { - return false; - } - return true; - } - - private static bool ShouldShowCultistLordReport(Pawn pawn) - { - if (ModsConfig.AnomalyActive && pawn.Faction == Faction.OfHoraxCult && pawn.mindState.duty?.def == DutyDefOf.Invoke) - { - return true; - } - return false; - } - - public static bool ShouldSendNotificationAbout(Pawn p) - { - if (Current.ProgramState != ProgramState.Playing) - { - return false; - } - if (p == null) - { - return false; - } - if (PawnGenerator.IsBeingGenerated(p)) - { - return false; - } - if (p.IsWorldPawn() && (!p.IsCaravanMember() || !p.GetCaravan().IsPlayerControlled) && !IsTravelingInTransportPodWorldObject(p) && !p.IsBorrowedByAnyFaction() && p.Corpse.DestroyedOrNull()) - { - return false; - } - if (p.IsSubhuman) - { - return false; - } - if (ModsConfig.AnomalyActive && p.Corpse is UnnaturalCorpse) - { - return false; - } - if (p.Faction != Faction.OfPlayer) - { - if (p.HostFaction != Faction.OfPlayer) - { - return false; - } - if (p.RaceProps.Humanlike && p.guest.Released && !p.Downed && !p.InBed()) - { - return false; - } - if (p.CurJob != null && p.CurJob.exitMapOnArrival && !PrisonBreakUtility.IsPrisonBreaking(p)) - { - return false; - } - if (IsExitingMap(p)) - { - return false; - } - } - return true; - } - - public static bool ShouldGetThoughtAbout(Pawn pawn, Pawn subject) - { - if (pawn.IsSubhuman || subject.IsSubhuman) - { - return false; - } - if (pawn.Faction != subject.Faction) - { - if (!subject.IsWorldPawn()) - { - return !pawn.IsWorldPawn(); - } - return false; - } - return true; - } - - public static bool IsTeetotaler(this Pawn pawn) - { - if (!new HistoryEvent(HistoryEventDefOf.IngestedDrug, pawn.Named(HistoryEventArgsNames.Doer)).DoerWillingToDo()) - { - return true; - } - if (!new HistoryEvent(HistoryEventDefOf.IngestedRecreationalDrug, pawn.Named(HistoryEventArgsNames.Doer)).DoerWillingToDo()) - { - return true; - } - if (pawn.story != null) - { - return pawn.story.traits.DegreeOfTrait(TraitDefOf.DrugDesire) < 0; - } - return false; - } - - public static bool CanTakeDrug(this Pawn pawn, ThingDef drug) - { - CompProperties_Drug compProperties = drug.GetCompProperties(); - if (compProperties == null) - { - return true; - } - if (CanTakeDrugForDependency(pawn, drug)) - { - return true; - } - if (!compProperties.teetotalerCanConsume && pawn.IsTeetotaler()) - { - return false; - } - if (ModsConfig.IdeologyActive) - { - if (!IdeoUtility.DoerWillingToDo(HistoryEventDefOf.IngestedDrug, pawn)) - { - return false; - } - if (drug.IsNonMedicalDrug && !IdeoUtility.DoerWillingToDo(HistoryEventDefOf.IngestedRecreationalDrug, pawn)) - { - return false; - } - if (drug.ingestible != null && drug.ingestible.drugCategory == DrugCategory.Hard && !IdeoUtility.DoerWillingToDo(HistoryEventDefOf.IngestedHardDrug, pawn)) - { - return false; - } - } - return true; - } - - public static bool CanTakeDrugForDependency(Pawn pawn, ThingDef drug) - { - if (!ModsConfig.BiotechActive || pawn.genes == null) - { - return false; - } - CompProperties_Drug compProperties = drug.GetCompProperties(); - if (compProperties == null) - { - return true; - } - foreach (Gene item in pawn.genes.GenesListForReading) - { - if (item is Gene_ChemicalDependency gene_ChemicalDependency && item.Active && gene_ChemicalDependency.def.chemical == compProperties.chemical) - { - return true; - } - } - return false; - } - - public static bool TryGetChemicalDependencyGene(Pawn pawn, out Gene_ChemicalDependency gene) - { - gene = null; - if (!ModsConfig.BiotechActive || pawn.genes == null) - { - return false; - } - foreach (Gene item in pawn.genes.GenesListForReading) - { - if (item is Gene_ChemicalDependency gene_ChemicalDependency) - { - gene = gene_ChemicalDependency; - return true; - } - } - return false; - } - - public static bool PawnWouldBeUnhappyTakingDrug(this Pawn pawn, ThingDef drug) - { - if (pawn.IsTeetotaler()) - { - return drug.GetCompProperties() != null; - } - return false; - } - - public static bool IsProsthophobe(this Pawn pawn) - { - if (pawn.story != null) - { - return pawn.story.traits.HasTrait(TraitDefOf.BodyPurist); - } - return false; - } - - public static bool IsPrisonerInPrisonCell(this Pawn pawn) - { - if (pawn.IsPrisoner && pawn.Spawned) - { - return pawn.Position.IsInPrisonCell(pawn.Map); - } - return false; - } - - public static bool IsBeingArrested(Pawn pawn) - { - if (pawn.Map == null) - { - return false; - } - foreach (Pawn item in pawn.Map.mapPawns.AllPawnsSpawned) - { - if (item != pawn && item.CurJobDef == JobDefOf.Arrest && item.CurJob.AnyTargetIs(pawn)) - { - return true; - } - } - return false; - } - - public static string PawnKindsToCommaList(IEnumerable pawns, bool useAnd = false) - { - tmpPawns.Clear(); - tmpPawns.AddRange(pawns); - if (tmpPawns.Count >= 2) - { - tmpPawns.SortBy((Pawn x) => !x.RaceProps.Humanlike, (Pawn x) => x.GetKindLabelPlural()); - } - tmpAddedPawnKinds.Clear(); - tmpPawnKindsStr.Clear(); - for (int i = 0; i < tmpPawns.Count; i++) - { - if (tmpAddedPawnKinds.Contains(tmpPawns[i].kindDef)) - { - continue; - } - tmpAddedPawnKinds.Add(tmpPawns[i].kindDef); - int num = 0; - for (int j = 0; j < tmpPawns.Count; j++) - { - if (tmpPawns[j].kindDef == tmpPawns[i].kindDef) - { - num++; - } - } - if (num == 1) - { - tmpPawnKindsStr.Add("1 " + tmpPawns[i].KindLabel); - } - else - { - tmpPawnKindsStr.Add(num + " " + tmpPawns[i].GetKindLabelPlural(num)); - } - } - tmpPawns.Clear(); - return tmpPawnKindsStr.ToCommaList(useAnd); - } - - public static List PawnKindsToList(IEnumerable pawnKinds) - { - tmpPawnKinds.Clear(); - tmpPawnKinds.AddRange(pawnKinds); - if (tmpPawnKinds.Count >= 2) - { - tmpPawnKinds.SortBy((PawnKindDef x) => !x.RaceProps.Humanlike, (PawnKindDef x) => GenLabel.BestKindLabel(x, Gender.None, plural: true)); - } - tmpAddedPawnKinds.Clear(); - tmpPawnKindsStr.Clear(); - for (int i = 0; i < tmpPawnKinds.Count; i++) - { - if (tmpAddedPawnKinds.Contains(tmpPawnKinds[i])) - { - continue; - } - tmpAddedPawnKinds.Add(tmpPawnKinds[i]); - int num = 0; - for (int j = 0; j < tmpPawnKinds.Count; j++) - { - if (tmpPawnKinds[j] == tmpPawnKinds[i]) - { - num++; - } - } - if (num == 1) - { - tmpPawnKindsStr.Add("1 " + GenLabel.BestKindLabel(tmpPawnKinds[i], Gender.None)); - } - else - { - tmpPawnKindsStr.Add(num + " " + GenLabel.BestKindLabel(tmpPawnKinds[i], Gender.None, plural: true, num)); - } - } - return tmpPawnKindsStr; - } - - public static string PawnKindsToLineList(IEnumerable pawnKinds, string prefix) - { - PawnKindsToList(pawnKinds); - return tmpPawnKindsStr.ToLineList(prefix); - } - - public static string PawnKindsToLineList(IEnumerable pawnKinds, string prefix, Color color) - { - PawnKindsToList(pawnKinds); - for (int i = 0; i < tmpPawnKindsStr.Count; i++) - { - tmpPawnKindsStr[i] = tmpPawnKindsStr[i].Colorize(color); - } - return tmpPawnKindsStr.ToLineList(prefix); - } - - public static string PawnKindsToCommaList(IEnumerable pawnKinds, bool useAnd = false) - { - PawnKindsToList(pawnKinds); - return tmpPawnKindsStr.ToCommaList(useAnd); - } - - public static LocomotionUrgency ResolveLocomotion(Pawn pawn, LocomotionUrgency secondPriority) - { - if (!pawn.Dead && pawn.mindState.duty != null && pawn.mindState.duty.locomotion != 0) - { - return pawn.mindState.duty.locomotion; - } - return secondPriority; - } - - public static LocomotionUrgency ResolveLocomotion(Pawn pawn, LocomotionUrgency secondPriority, LocomotionUrgency thirdPriority) - { - LocomotionUrgency locomotionUrgency = ResolveLocomotion(pawn, secondPriority); - if (locomotionUrgency != 0) - { - return locomotionUrgency; - } - return thirdPriority; - } - - public static Danger ResolveMaxDanger(Pawn pawn, Danger secondPriority) - { - if (!pawn.Dead && pawn.mindState.duty != null && pawn.mindState.duty.maxDanger != 0) - { - return pawn.mindState.duty.maxDanger; - } - return secondPriority; - } - - public static Danger ResolveMaxDanger(Pawn pawn, Danger secondPriority, Danger thirdPriority) - { - Danger danger = ResolveMaxDanger(pawn, secondPriority); - if (danger != 0) - { - return danger; - } - return thirdPriority; - } - - public static bool IsPermanentCombatant(this Pawn pawn) - { - if (pawn?.mindState == null) - { - return true; - } - if (pawn.IsAnimal && pawn.Faction != null) - { - return false; - } - if (pawn.DevelopmentalStage.Juvenile()) - { - return false; - } - return true; - } - - public static bool IsCombatant(this Pawn pawn) - { - if (pawn.IsPermanentCombatant()) - { - return true; - } - return pawn.mindState.CombatantRecently; - } - - public static bool IsFighting(this Pawn pawn) - { - if (pawn.CurJob != null) - { - if (pawn.CurJob.def != JobDefOf.AttackMelee && pawn.CurJob.def != JobDefOf.AttackStatic && pawn.CurJob.def != JobDefOf.Wait_Combat && pawn.CurJob.def != JobDefOf.PredatorHunt) - { - return pawn.CurJob.def == JobDefOf.ManTurret; - } - return true; - } - return false; - } - - public static bool IsAttacking(this Pawn pawn) - { - if (pawn.CurJobDef == JobDefOf.AttackMelee || pawn.CurJobDef == JobDefOf.AttackStatic) - { - return true; - } - if (pawn.CurJobDef == JobDefOf.Wait_Combat && pawn.stances.curStance is Stance_Busy stance_Busy && stance_Busy.focusTarg.IsValid) - { - return true; - } - return false; - } - - public static Hediff_Psylink GetMainPsylinkSource(this Pawn pawn) - { - return (Hediff_Psylink)pawn.health.hediffSet.GetFirstHediffOfDef(HediffDefOf.PsychicAmplifier); - } - - public static int GetPsylinkLevel(this Pawn pawn) - { - int num = 0; - foreach (Hediff hediff in pawn.health.hediffSet.hediffs) - { - if (hediff is Hediff_Psylink hediff_Psylink) - { - num += hediff_Psylink.level; - } - } - return num; - } - - public static int GetMaxPsylinkLevel(this Pawn pawn) - { - return (int)HediffDefOf.PsychicAmplifier.maxSeverity; - } - - public static RoyalTitle GetMaxPsylinkLevelTitle(this Pawn pawn) - { - if (pawn.royalty == null) - { - return null; - } - int num = 0; - RoyalTitle result = null; - foreach (RoyalTitle item in pawn.royalty.AllTitlesInEffectForReading) - { - if (num < item.def.maxPsylinkLevel) - { - num = item.def.maxPsylinkLevel; - result = item; - } - } - return result; - } - - public static int GetMaxPsylinkLevelByTitle(this Pawn pawn) - { - return pawn.GetMaxPsylinkLevelTitle()?.def.maxPsylinkLevel ?? 0; - } - - public static void ChangePsylinkLevel(this Pawn pawn, int levelOffset, bool sendLetter = true) - { - Hediff_Psylink mainPsylinkSource = pawn.GetMainPsylinkSource(); - if (mainPsylinkSource == null) - { - mainPsylinkSource = (Hediff_Psylink)HediffMaker.MakeHediff(HediffDefOf.PsychicAmplifier, pawn); - try - { - mainPsylinkSource.suppressPostAddLetter = !sendLetter; - pawn.health.AddHediff(mainPsylinkSource, pawn.health.hediffSet.GetBrain()); - return; - } - finally - { - mainPsylinkSource.suppressPostAddLetter = false; - } - } - mainPsylinkSource.ChangeLevel(levelOffset, sendLetter); - } - - public static void GiveAllStartingPlayerPawnsThought(ThoughtDef thought) - { - foreach (Pawn startingAndOptionalPawn in Find.GameInitData.startingAndOptionalPawns) - { - if (startingAndOptionalPawn.needs.mood == null) - { - continue; - } - if (thought.IsSocial) - { - foreach (Pawn startingAndOptionalPawn2 in Find.GameInitData.startingAndOptionalPawns) - { - if (startingAndOptionalPawn2 != startingAndOptionalPawn) - { - startingAndOptionalPawn.needs.mood.thoughts.memories.TryGainMemory(thought, startingAndOptionalPawn2); - } - } - } - else - { - startingAndOptionalPawn.needs.mood.thoughts.memories.TryGainMemory(thought); - } - } - } - - public static IntVec3 DutyLocation(this Pawn pawn) - { - Pawn_RopeTracker roping = pawn.roping; - if (roping != null && roping.IsRopedToSpot) - { - return pawn.roping.RopedToSpot; - } - if (pawn.mindState.duty != null && pawn.mindState.duty.focus.IsValid) - { - return pawn.mindState.duty.focus.Cell; - } - return pawn.Position; - } - - public static bool EverBeenColonistOrTameAnimal(Pawn pawn) - { - return pawn.records.GetAsInt(RecordDefOf.TimeAsColonistOrColonyAnimal) > 0; - } - - public static bool EverBeenPrisoner(Pawn pawn) - { - return pawn.records.GetAsInt(RecordDefOf.TimeAsPrisoner) > 0; - } - - public static bool EverBeenQuestLodger(Pawn pawn) - { - return pawn.records.GetAsInt(RecordDefOf.TimeAsQuestLodger) > 0; - } - - public static void RecoverFromUnwalkablePositionOrKill(IntVec3 c, Map map) - { - if (!c.InBounds(map) || c.Walkable(map)) - { - return; - } - tmpThings.Clear(); - tmpThings.AddRange(c.GetThingList(map)); - for (int i = 0; i < tmpThings.Count; i++) - { - if (!(tmpThings[i] is Pawn pawn)) - { - continue; - } - if (CellFinder.TryFindBestPawnStandCell(pawn, out var cell)) - { - pawn.Position = cell; - pawn.Notify_Teleported(endCurrentJob: true, resetTweenedPos: false); - continue; - } - DamageInfo damageInfo = new DamageInfo(DamageDefOf.Crush, 99999f, 999f, -1f, null, pawn.health.hediffSet.GetBrain(), null, DamageInfo.SourceCategory.Collapse); - damageInfo.SetIgnoreInstantKillProtection(ignore: true); - pawn.TakeDamage(damageInfo); - if (!pawn.Dead) - { - pawn.Kill(damageInfo); - } - } - } - - public static float GetManhunterOnDamageChance(Pawn pawn, Thing instigator = null, float distance = -1f) - { - float num = GetManhunterOnDamageChance(pawn.def); - if (pawn.health.hediffSet.HasHediff(HediffDefOf.Scaria)) - { - num += 0.5f; - } - if (instigator != null) - { - num *= GenMath.LerpDoubleClamped(1f, 30f, 3f, 1f, distance); - num *= 1f - instigator.GetStatValue(StatDefOf.HuntingStealth); - if (instigator is Pawn instigator2) - { - num *= GetManhunterChanceFactorForInstigator(instigator2); - } - } - return Mathf.Clamp01(num); - } - - public static float GetManhunterOnDamageChance(ThingDef def) - { - return def.race.manhunterOnDamageChance * Find.Storyteller.difficulty.manhunterChanceOnDamageFactor; - } - - public static string GetManhunterOnDamageChanceExplanation(ThingDef def, Pawn pawn) - { - StringBuilder stringBuilder = new StringBuilder(); - stringBuilder.AppendLine("HarmedRevengeChanceExplanation".Translate()); - stringBuilder.AppendLine(); - stringBuilder.AppendLine(def.LabelCap + ": " + def.race.manhunterOnDamageChance.ToStringPercent()); - stringBuilder.AppendLine("StatsReport_DifficultyMultiplier".Translate(Find.Storyteller.difficultyDef.label) + ": " + Find.Storyteller.difficulty.manhunterChanceOnDamageFactor.ToStringPercent()); - if (pawn != null && pawn.health.hediffSet.HasHediff(HediffDefOf.Scaria)) - { - stringBuilder.AppendLine(HediffDefOf.Scaria.LabelCap + ": " + 0.5f.ToStringPercentSigned()); - } - stringBuilder.AppendLine(); - float f = ((pawn == null) ? GetManhunterOnDamageChance(def) : GetManhunterOnDamageChance(pawn)); - stringBuilder.AppendLine("StatsReport_FinalValue".Translate() + ": " + f.ToStringPercent()); - return stringBuilder.ToString(); - } - - public static float GetManhunterChanceFactorForInstigator(Pawn instigator) - { - if (ModsConfig.AnomalyActive && instigator?.Faction == Faction.OfEntities) - { - return 0f; - } - float num = 1f; - if (ModsConfig.IdeologyActive && instigator?.Ideo != null) - { - RoleEffect roleEffect = instigator.Ideo.GetRole(instigator)?.def.roleEffects?.FirstOrDefault((RoleEffect eff) => eff is RoleEffect_HuntingRevengeChanceFactor); - if (roleEffect != null) - { - num *= ((RoleEffect_HuntingRevengeChanceFactor)roleEffect).factor; - } - } - return num; - } - - public static float GetManhunterOnTameFailChance(Pawn pawn) - { - return Mathf.Clamp01(GetManhunterOnTameFailChance(pawn.def)); - } - - public static float GetManhunterOnTameFailChance(ThingDef def) - { - return def.race.manhunterOnTameFailChance; - } - - public static string GetManhunterOnTameFailChanceExplanation(ThingDef def, Pawn pawn) - { - StringBuilder stringBuilder = new StringBuilder(); - stringBuilder.AppendLine("Stat_Race_Animal_TameFailedRevengeChance_Desc".Translate()); - stringBuilder.AppendLine(); - stringBuilder.AppendLine(def.LabelCap + ": " + def.race.manhunterOnTameFailChance.ToStringPercent()); - stringBuilder.AppendLine(); - float f = ((pawn == null) ? GetManhunterOnTameFailChance(def) : GetManhunterOnTameFailChance(pawn)); - stringBuilder.AppendLine("StatsReport_FinalValue".Translate() + ": " + f.ToStringPercent()); - return stringBuilder.ToString(); - } - - public static MentalStateDef ManhunterStateFor(Pawn pawn) - { - if (pawn.health.hediffSet.HasHediff(HediffDefOf.Scaria)) - { - return MentalStateDefOf.ManhunterPermanent; - } - return MentalStateDefOf.Manhunter; - } - - public static bool PlayerHasReproductivePair(PawnKindDef pawnKindDef) - { - if (!pawnKindDef.RaceProps.Animal) - { - return false; - } - List allMapsCaravansAndTravellingTransporters_Alive_OfPlayerFaction = PawnsFinder.AllMapsCaravansAndTravellingTransporters_Alive_OfPlayerFaction; - bool flag = false; - bool flag2 = false; - for (int i = 0; i < allMapsCaravansAndTravellingTransporters_Alive_OfPlayerFaction.Count; i++) - { - Pawn pawn = allMapsCaravansAndTravellingTransporters_Alive_OfPlayerFaction[i]; - if (pawn.kindDef == pawnKindDef && pawn.ageTracker.CurLifeStage.reproductive) - { - if (pawn.gender == Gender.Male) - { - flag = true; - } - else if (pawn.gender == Gender.Female) - { - flag2 = true; - } - if (flag && flag2) - { - return true; - } - } - } - return false; - } - - public static float PlayerAnimalBodySizePerCapita() - { - float num = 0f; - int num2 = 0; - List allMapsCaravansAndTravellingTransporters_Alive_OfPlayerFaction = PawnsFinder.AllMapsCaravansAndTravellingTransporters_Alive_OfPlayerFaction; - for (int i = 0; i < allMapsCaravansAndTravellingTransporters_Alive_OfPlayerFaction.Count; i++) - { - Pawn pawn = allMapsCaravansAndTravellingTransporters_Alive_OfPlayerFaction[i]; - if (pawn.IsFreeColonist && !pawn.IsQuestLodger()) - { - num2++; - } - if (pawn.IsAnimal) - { - num += pawn.BodySize; - } - } - if (num2 <= 0) - { - return 0f; - } - return num / (float)num2; - } - - private static List PawnsOfFactionOnMapOrInCaravan(Pawn pawn) - { - if (pawn.Spawned) - { - return pawn.Map.mapPawns.SpawnedPawnsInFaction(pawn.Faction); - } - return pawn.GetCaravan()?.PawnsListForReading; - } - - public static float PlayerVeneratedAnimalBodySizePerCapitaOnMapOrCaravan(Pawn pawn) - { - if (pawn.Ideo == null || pawn.Faction == null) - { - return 0f; - } - float num = 0f; - int num2 = 0; - List list = PawnsOfFactionOnMapOrInCaravan(pawn); - for (int i = 0; i < list.Count; i++) - { - if (list[i].Faction == pawn.Faction && !pawn.IsQuestLodger()) - { - if (list[i].IsAnimal && pawn.Ideo.IsVeneratedAnimal(list[i])) - { - num += list[i].BodySize; - } - else if (list[i].RaceProps.Humanlike) - { - num2++; - } - } - } - return Mathf.Round(((num2 > 0) ? (num / (float)num2) : 0f) * 100f) / 100f; - } - - public static Pawn FirstVeneratedAnimalOnMapOrCaravan(Pawn pawn) - { - if (pawn.Ideo == null || pawn.Faction == null) - { - return null; - } - List list = PawnsOfFactionOnMapOrInCaravan(pawn); - for (int i = 0; i < list.Count; i++) - { - if (pawn.Faction == list[i].Faction && pawn.Ideo.IsVeneratedAnimal(list[i])) - { - return list[i]; - } - } - return null; - } - - public static bool HasClothingNotRequiredByKind(Pawn p) - { - if (p.apparel == null) - { - return false; - } - List wornApparel = p.apparel.WornApparel; - if (wornApparel.Count > 0 && p.kindDef.apparelRequired.NullOrEmpty()) - { - return true; - } - for (int i = 0; i < wornApparel.Count; i++) - { - Apparel apparel = wornApparel[i]; - if (apparel.def.apparel.countsAsClothingForNudity && !p.kindDef.apparelRequired.Contains(apparel.def)) - { - return true; - } - } - return false; - } - - public static IEnumerable GetCombatPawnKindsForPoints(Func selector, float points, Func selectionWeight = null) - { - IEnumerable allKinds = DefDatabase.AllDefsListForReading.Where(selector); - if (selectionWeight == null) - { - selectionWeight = (PawnKindDef _) => 1f; - } - PawnKindDef result; - while (points > 0f && allKinds.Where((PawnKindDef def) => def.combatPower > 0f && def.combatPower <= points && def.appearsRandomlyInCombatGroups).TryRandomElementByWeight(selectionWeight, out result)) - { - points -= result.combatPower; - yield return result; - } - } - - public static int GetMaxAllowedToPickUp(Pawn pawn, ThingDef thingDef) - { - int maxAllowedToPickUp = GetMaxAllowedToPickUp(thingDef, pawn.Map); - if (maxAllowedToPickUp <= 0) - { - return 0; - } - int num = pawn.inventory.Count((Thing t) => t.def.orderedTakeGroup == thingDef.orderedTakeGroup); - return Math.Max(maxAllowedToPickUp - num, 0); - } - - public static int GetMaxAllowedToPickUp(ThingDef thingDef, Map map = null) - { - if (map != null && !map.IsPlayerHome) - { - return int.MaxValue; - } - if (thingDef.orderedTakeGroup == null) - { - return 0; - } - return thingDef.orderedTakeGroup.max; - } - - public static bool CanPickUp(Pawn pawn, ThingDef thingDef) - { - if (!pawn.Map.IsPlayerHome) - { - return true; - } - if (pawn.inventory != null && thingDef.orderedTakeGroup != null) - { - return thingDef.orderedTakeGroup.max > 0; - } - return false; - } - - public static bool ShouldBeSlaughtered(this Pawn pawn) - { - if (!pawn.Spawned || !pawn.IsAnimal) - { - return false; - } - if (pawn.Map.designationManager.DesignationOn(pawn, DesignationDefOf.Slaughter) != null || pawn.Map.autoSlaughterManager.AnimalsToSlaughter.Contains(pawn)) - { - return pawn.Map.designationManager.DesignationOn(pawn, DesignationDefOf.ReleaseAnimalToWild) == null; - } - return false; - } - - public static bool CanBeBuried(this Thing t) - { - if (t is Corpse { MapHeld: not null } corpse) - { - return corpse.MapHeld.designationManager.DesignationOn(corpse, DesignationDefOf.ExtractSkull) == null; - } - return true; - } - - public static bool PawnHadFuneral(Pawn pawn) - { - Precept_Ritual precept_Ritual = (Precept_Ritual)(pawn.ideo?.Ideo?.GetPrecept(PreceptDefOf.Funeral)); - if (precept_Ritual != null && !precept_Ritual.completedObligations.NullOrEmpty()) - { - return precept_Ritual.completedObligations.Any((RitualObligation o) => o.FirstValidTarget.Thing == pawn); - } - return false; - } - - public static bool IsBiologicallyOrArtificiallyBlind(Pawn pawn) - { - if (!IsBiologicallyBlind(pawn)) - { - return IsArtificiallyBlind(pawn); - } - return true; - } - - public static bool IsBiologicallyBlind(Pawn pawn) - { - return !pawn.health.capacities.CapableOf(PawnCapacityDefOf.Sight); - } - - public static bool IsArtificiallyBlind(Pawn p) - { - if (IsBiologicallyBlind(p)) - { - return false; - } - if (p.apparel != null) - { - foreach (Apparel item in p.apparel.WornApparel) - { - if (item.def.apparel.blocksVision) - { - return true; - } - } - } - return false; - } - - public static bool IsWorkTypeDisabledByAge(this Pawn pawn, WorkTypeDef workType, out int minAgeRequired) - { - for (int i = 0; i < pawn.RaceProps.lifeStageWorkSettings.Count; i++) - { - LifeStageWorkSettings lifeStageWorkSettings = pawn.RaceProps.lifeStageWorkSettings[i]; - if (lifeStageWorkSettings.workType == workType && lifeStageWorkSettings.IsDisabled(pawn)) - { - minAgeRequired = lifeStageWorkSettings.minAge; - return true; - } - } - minAgeRequired = 0; - return false; - } - - public static bool DutyActiveWhenDown(this Pawn pawn, bool onlyInBed = false) - { - if (onlyInBed && !pawn.InBed()) - { - return false; - } - return (pawn.GetLord()?.LordJob?.DutyActiveWhenDown(pawn)).GetValueOrDefault(); - } - - public static bool IsExitingMap(Pawn pawn) - { - Lord lord = pawn.GetLord(); - if (lord == null) - { - return false; - } - if (!(lord.LordJob is LordJob_ExitMapBest) && !(lord.LordJob is LordJob_ExitMapNear) && !(lord.LordJob is LordJob_ExitOnShuttle)) - { - return lord.LordJob is LordJob_TravelAndExit; - } - return true; - } - - public static void ForceEjectFromContainer(Pawn pawn) - { - Thing resultingThing; - if (pawn.ParentHolder is Pawn_CarryTracker pawn_CarryTracker) - { - pawn_CarryTracker.TryDropCarriedThing(pawn_CarryTracker.pawn.Position, ThingPlaceMode.Near, out resultingThing); - pawn_CarryTracker.pawn.jobs.EndCurrentJob(JobCondition.InterruptForced); - } - if (pawn.ParentHolder is Building_Enterable building_Enterable) - { - building_Enterable.innerContainer.TryDrop(pawn, building_Enterable.InteractionCell, building_Enterable.Map, ThingPlaceMode.Near, out resultingThing); - } - if (pawn.ParentHolder is Building_Casket building_Casket) - { - building_Casket.EjectContents(); - } - if (pawn.ParentHolder is Building_HoldingPlatform building_HoldingPlatform) - { - building_HoldingPlatform.EjectContents(); - } - if (pawn.ParentHolder is CompBiosculpterPod compBiosculpterPod) - { - compBiosculpterPod.EjectContents(interrupted: true, playSounds: true); - } - } -} -``` \ No newline at end of file diff --git a/MCP/vector_cache/Projectile-TickInterval-Verse.txt b/MCP/vector_cache/Projectile-TickInterval-Verse.txt deleted file mode 100644 index d02770d8..00000000 --- a/MCP/vector_cache/Projectile-TickInterval-Verse.txt +++ /dev/null @@ -1,655 +0,0 @@ -根据向量相似度分析,与 'TickInterval, Projectile, Verse' 最相关的代码定义如下: - ---- -**文件路径 (精确匹配):** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\Verse\Projectile.txt` - -```csharp -public abstract class Projectile : ThingWithComps -{ - private static readonly Material shadowMaterial = MaterialPool.MatFrom("Things/Skyfaller/SkyfallerShadowCircle", ShaderDatabase.Transparent); - - protected Vector3 origin; - - protected Vector3 destination; - - public LocalTargetInfo usedTarget; - - public LocalTargetInfo intendedTarget; - - protected Thing equipment; - - protected ThingDef equipmentDef; - - protected Thing launcher; - - protected ThingDef targetCoverDef; - - private ProjectileHitFlags desiredHitFlags = ProjectileHitFlags.All; - - protected bool preventFriendlyFire; - - protected int lifetime; - - protected QualityCategory equipmentQuality = QualityCategory.Normal; - - public float stoppingPower; - - public DamageDef damageDefOverride; - - public List extraDamages = new List(); - - protected bool landed; - - protected int ticksToImpact; - - private Sustainer ambientSustainer; - - private static List checkedCells = new List(); - - public DamageDef DamageDef => damageDefOverride ?? def.projectile.damageDef; - - public IEnumerable ExtraDamages - { - get - { - List first = extraDamages; - IEnumerable enumerable = def.projectile.extraDamages; - return first.Concat(enumerable ?? Enumerable.Empty()); - } - } - - public ProjectileHitFlags HitFlags - { - get - { - if (def.projectile.alwaysFreeIntercept) - { - return ProjectileHitFlags.All; - } - if (def.projectile.flyOverhead) - { - return ProjectileHitFlags.None; - } - return desiredHitFlags; - } - set - { - desiredHitFlags = value; - } - } - - protected float StartingTicksToImpact - { - get - { - float num = (origin - destination).magnitude / def.projectile.SpeedTilesPerTick; - if (num <= 0f) - { - num = 0.001f; - } - return num; - } - } - - protected IntVec3 DestinationCell => new IntVec3(destination); - - public virtual Vector3 ExactPosition - { - get - { - Vector3 vector = (destination - origin).Yto0() * DistanceCoveredFraction; - return origin.Yto0() + vector + Vector3.up * def.Altitude; - } - } - - protected float DistanceCoveredFraction => Mathf.Clamp01(1f - (float)ticksToImpact / StartingTicksToImpact); - - protected float DistanceCoveredFractionArc => Mathf.Clamp01(1f - (float)(landed ? lifetime : ticksToImpact) / StartingTicksToImpact); - - public virtual Quaternion ExactRotation => Quaternion.LookRotation((destination - origin).Yto0()); - - public virtual bool AnimalsFleeImpact => false; - - public override Vector3 DrawPos => ExactPosition; - - public virtual Material DrawMat => def.graphic.MatSingleFor(this); - - public virtual int DamageAmount => def.projectile.GetDamageAmount(equipment); - - public virtual float ArmorPenetration => def.projectile.GetArmorPenetration(equipment); - - public ThingDef EquipmentDef => equipmentDef; - - public Thing Launcher => launcher; - - public override int UpdateRateTicks - { - get - { - if (base.Spawned && Find.CurrentMap == base.Map && Find.CameraDriver.InViewOf(this)) - { - return 1; - } - return 15; - } - } - - private float ArcHeightFactor - { - get - { - float num = def.projectile.arcHeightFactor; - float num2 = (destination - origin).MagnitudeHorizontalSquared(); - if (num * num > num2 * 0.2f * 0.2f) - { - num = Mathf.Sqrt(num2) * 0.2f; - } - return num; - } - } - - public override void ExposeData() - { - base.ExposeData(); - Scribe_Values.Look(ref origin, "origin"); - Scribe_Values.Look(ref destination, "destination"); - Scribe_Values.Look(ref ticksToImpact, "ticksToImpact", 0); - Scribe_TargetInfo.Look(ref usedTarget, "usedTarget"); - Scribe_TargetInfo.Look(ref intendedTarget, "intendedTarget"); - Scribe_References.Look(ref launcher, "launcher"); - Scribe_References.Look(ref equipment, "equipment"); - Scribe_Defs.Look(ref equipmentDef, "equipmentDef"); - Scribe_Defs.Look(ref targetCoverDef, "targetCoverDef"); - Scribe_Values.Look(ref desiredHitFlags, "desiredHitFlags", ProjectileHitFlags.All); - Scribe_Values.Look(ref preventFriendlyFire, "preventFriendlyFire", defaultValue: false); - Scribe_Values.Look(ref landed, "landed", defaultValue: false); - Scribe_Values.Look(ref lifetime, "lifetime", 0); - Scribe_Values.Look(ref equipmentQuality, "equipmentQuality", QualityCategory.Normal); - } - - public void Launch(Thing launcher, LocalTargetInfo usedTarget, LocalTargetInfo intendedTarget, ProjectileHitFlags hitFlags, bool preventFriendlyFire = false, Thing equipment = null) - { - Launch(launcher, base.Position.ToVector3Shifted(), usedTarget, intendedTarget, hitFlags, preventFriendlyFire, equipment); - } - - public virtual void Launch(Thing launcher, Vector3 origin, LocalTargetInfo usedTarget, LocalTargetInfo intendedTarget, ProjectileHitFlags hitFlags, bool preventFriendlyFire = false, Thing equipment = null, ThingDef targetCoverDef = null) - { - this.launcher = launcher; - this.origin = origin; - this.usedTarget = usedTarget; - this.intendedTarget = intendedTarget; - this.targetCoverDef = targetCoverDef; - this.preventFriendlyFire = preventFriendlyFire; - HitFlags = hitFlags; - stoppingPower = def.projectile.stoppingPower; - if (stoppingPower == 0f && def.projectile.damageDef != null) - { - stoppingPower = def.projectile.damageDef.defaultStoppingPower; - } - if (equipment != null) - { - this.equipment = equipment; - equipmentDef = equipment.def; - equipment.TryGetQuality(out equipmentQuality); - if (equipment.TryGetComp(out CompUniqueWeapon comp)) - { - foreach (WeaponTraitDef item in comp.TraitsListForReading) - { - if (!Mathf.Approximately(item.additionalStoppingPower, 0f)) - { - stoppingPower += item.additionalStoppingPower; - } - } - } - } - else - { - equipmentDef = null; - } - destination = usedTarget.Cell.ToVector3Shifted() + Gen.RandomHorizontalVector(0.3f); - ticksToImpact = Mathf.CeilToInt(StartingTicksToImpact); - if (ticksToImpact < 1) - { - ticksToImpact = 1; - } - lifetime = ticksToImpact; - if (!def.projectile.soundAmbient.NullOrUndefined()) - { - ambientSustainer = def.projectile.soundAmbient.TrySpawnSustainer(SoundInfo.InMap(this, MaintenanceType.PerTick)); - } - } - - protected override void Tick() - { - base.Tick(); - if (ticksToImpact == 60 && Find.TickManager.CurTimeSpeed == TimeSpeed.Normal && def.projectile.soundImpactAnticipate != null) - { - def.projectile.soundImpactAnticipate.PlayOneShot(this); - } - if (ambientSustainer != null) - { - ambientSustainer.Maintain(); - } - } - - protected override void TickInterval(int delta) - { - base.TickInterval(delta); - lifetime -= delta; - if (landed) - { - return; - } - Vector3 exactPosition = ExactPosition; - ticksToImpact -= delta; - if (!ExactPosition.InBounds(base.Map)) - { - ticksToImpact += delta; - base.Position = ExactPosition.ToIntVec3(); - Destroy(); - return; - } - Vector3 exactPosition2 = ExactPosition; - if (CheckForFreeInterceptBetween(exactPosition, exactPosition2)) - { - return; - } - base.Position = ExactPosition.ToIntVec3(); - if (ticksToImpact <= 0) - { - if (DestinationCell.InBounds(base.Map)) - { - base.Position = DestinationCell; - } - ImpactSomething(); - } - } - - private bool CheckForFreeInterceptBetween(Vector3 lastExactPos, Vector3 newExactPos) - { - if (lastExactPos == newExactPos) - { - return false; - } - List list = base.Map.listerThings.ThingsInGroup(ThingRequestGroup.ProjectileInterceptor); - for (int i = 0; i < list.Count; i++) - { - if (list[i].TryGetComp().CheckIntercept(this, lastExactPos, newExactPos)) - { - Impact(null, blockedByShield: true); - return true; - } - } - IntVec3 intVec = lastExactPos.ToIntVec3(); - IntVec3 intVec2 = newExactPos.ToIntVec3(); - if (intVec2 == intVec) - { - return false; - } - if (!intVec.InBounds(base.Map) || !intVec2.InBounds(base.Map)) - { - return false; - } - if (intVec2.AdjacentToCardinal(intVec)) - { - return CheckForFreeIntercept(intVec2); - } - if (VerbUtility.InterceptChanceFactorFromDistance(origin, intVec2) <= 0f) - { - return false; - } - Vector3 vect = lastExactPos; - Vector3 v = newExactPos - lastExactPos; - Vector3 vector = v.normalized * 0.2f; - int num = (int)(v.MagnitudeHorizontal() / 0.2f); - checkedCells.Clear(); - int num2 = 0; - IntVec3 intVec3; - do - { - vect += vector; - intVec3 = vect.ToIntVec3(); - if (!checkedCells.Contains(intVec3)) - { - if (CheckForFreeIntercept(intVec3)) - { - return true; - } - checkedCells.Add(intVec3); - } - num2++; - if (num2 > num) - { - return false; - } - } - while (!(intVec3 == intVec2)); - return false; - } - - private bool CheckForFreeIntercept(IntVec3 c) - { - if (destination.ToIntVec3() == c) - { - return false; - } - float num = VerbUtility.InterceptChanceFactorFromDistance(origin, c); - if (num <= 0f) - { - return false; - } - bool flag = false; - List thingList = c.GetThingList(base.Map); - for (int i = 0; i < thingList.Count; i++) - { - Thing thing = thingList[i]; - if (!CanHit(thing)) - { - continue; - } - bool flag2 = false; - if (thing.def.Fillage == FillCategory.Full) - { - if (!(thing is Building_Door { Open: not false })) - { - ThrowDebugText("int-wall", c); - Impact(thing); - return true; - } - flag2 = true; - } - float num2 = 0f; - if (thing is Pawn pawn) - { - num2 = 0.4f * Mathf.Clamp(pawn.BodySize, 0.1f, 2f); - if (pawn.GetPosture() != 0) - { - num2 *= 0.1f; - } - if (launcher != null && pawn.Faction != null && launcher.Faction != null && !pawn.Faction.HostileTo(launcher.Faction)) - { - if (preventFriendlyFire) - { - num2 = 0f; - ThrowDebugText("ff-miss", c); - } - else - { - num2 *= Find.Storyteller.difficulty.friendlyFireChanceFactor; - } - } - } - else if (thing.def.fillPercent > 0.2f) - { - num2 = (flag2 ? 0.05f : ((!DestinationCell.AdjacentTo8Way(c)) ? (thing.def.fillPercent * 0.15f) : (thing.def.fillPercent * 1f))); - } - num2 *= num; - if (num2 > 1E-05f) - { - if (Rand.Chance(num2)) - { - ThrowDebugText("int-" + num2.ToStringPercent(), c); - Impact(thing); - return true; - } - flag = true; - ThrowDebugText(num2.ToStringPercent(), c); - } - } - if (!flag) - { - ThrowDebugText("o", c); - } - return false; - } - - private void ThrowDebugText(string text, IntVec3 c) - { - if (DebugViewSettings.drawShooting) - { - MoteMaker.ThrowText(c.ToVector3Shifted(), base.Map, text); - } - } - - protected override void DrawAt(Vector3 drawLoc, bool flip = false) - { - float num = ArcHeightFactor * GenMath.InverseParabola(DistanceCoveredFractionArc); - Vector3 vector = drawLoc + new Vector3(0f, 0f, 1f) * num; - if (def.projectile.shadowSize > 0f) - { - DrawShadow(drawLoc, num); - } - Quaternion rotation = ExactRotation; - if (def.projectile.spinRate != 0f) - { - float num2 = 60f / def.projectile.spinRate; - rotation = Quaternion.AngleAxis((float)Find.TickManager.TicksGame % num2 / num2 * 360f, Vector3.up); - } - if (def.projectile.useGraphicClass) - { - Graphic.Draw(vector, base.Rotation, this, rotation.eulerAngles.y); - } - else - { - Graphics.DrawMesh(MeshPool.GridPlane(def.graphicData.drawSize), vector, rotation, DrawMat, 0); - } - Comps_PostDraw(); - } - - protected bool CanHit(Thing thing) - { - if (!thing.Spawned) - { - return false; - } - if (thing == launcher) - { - return false; - } - ProjectileHitFlags hitFlags = HitFlags; - if (hitFlags == ProjectileHitFlags.None) - { - return false; - } - if (thing.Map != base.Map) - { - return false; - } - if (CoverUtility.ThingCovered(thing, base.Map)) - { - return false; - } - if (thing == intendedTarget && (hitFlags & ProjectileHitFlags.IntendedTarget) != 0) - { - return true; - } - if (thing != intendedTarget) - { - if (thing is Pawn) - { - if ((hitFlags & ProjectileHitFlags.NonTargetPawns) != 0) - { - return true; - } - } - else if ((hitFlags & ProjectileHitFlags.NonTargetWorld) != 0) - { - return true; - } - } - if (thing == intendedTarget && thing.def.Fillage == FillCategory.Full) - { - return true; - } - return false; - } - - protected virtual void ImpactSomething() - { - if (def.projectile.flyOverhead) - { - RoofDef roofDef = base.Map.roofGrid.RoofAt(base.Position); - if (roofDef != null) - { - if (roofDef.isThickRoof) - { - ThrowDebugText("hit-thick-roof", base.Position); - if (!def.projectile.soundHitThickRoof.NullOrUndefined()) - { - def.projectile.soundHitThickRoof.PlayOneShot(new TargetInfo(base.Position, base.Map)); - } - Destroy(); - return; - } - if (base.Position.GetEdifice(base.Map) == null || base.Position.GetEdifice(base.Map).def.Fillage != FillCategory.Full) - { - RoofCollapserImmediate.DropRoofInCells(base.Position, base.Map); - } - } - } - if (usedTarget.HasThing && CanHit(usedTarget.Thing)) - { - if (usedTarget.Thing is Pawn p && p.GetPosture() != 0 && (origin - destination).MagnitudeHorizontalSquared() >= 20.25f && !Rand.Chance(0.5f)) - { - ThrowDebugText("miss-laying", base.Position); - Impact(null); - } - else - { - Impact(usedTarget.Thing); - } - return; - } - List list = VerbUtility.ThingsToHit(base.Position, base.Map, CanHit); - list.Shuffle(); - for (int i = 0; i < list.Count; i++) - { - Thing thing = list[i]; - float num; - if (thing is Pawn pawn) - { - num = 0.5f * Mathf.Clamp(pawn.BodySize, 0.1f, 2f); - if (pawn.GetPosture() != 0 && (origin - destination).MagnitudeHorizontalSquared() >= 20.25f) - { - num *= 0.5f; - } - if (launcher != null && pawn.Faction != null && launcher.Faction != null && !pawn.Faction.HostileTo(launcher.Faction)) - { - num *= VerbUtility.InterceptChanceFactorFromDistance(origin, base.Position); - } - } - else - { - num = 1.5f * thing.def.fillPercent; - } - if (Rand.Chance(num)) - { - ThrowDebugText("hit-" + num.ToStringPercent(), base.Position); - Impact(list.RandomElement()); - return; - } - ThrowDebugText("miss-" + num.ToStringPercent(), base.Position); - } - Impact(null); - } - - protected virtual void Impact(Thing hitThing, bool blockedByShield = false) - { - GenClamor.DoClamor(this, 12f, ClamorDefOf.Impact); - if (!blockedByShield && def.projectile.landedEffecter != null) - { - def.projectile.landedEffecter.Spawn(base.Position, base.Map).Cleanup(); - } - Destroy(); - } - - private void DrawShadow(Vector3 drawLoc, float height) - { - if (!(shadowMaterial == null)) - { - float num = def.projectile.shadowSize * Mathf.Lerp(1f, 0.6f, height); - Vector3 s = new Vector3(num, 1f, num); - Vector3 vector = new Vector3(0f, -0.01f, 0f); - Matrix4x4 matrix = default(Matrix4x4); - matrix.SetTRS(drawLoc + vector, Quaternion.identity, s); - Graphics.DrawMesh(MeshPool.plane10, matrix, shadowMaterial, 0); - } - } -} -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\CompRitualEffect_IntervalSpawn.txt` -**相似度:** 0.5662 - -```csharp -public abstract class CompRitualEffect_IntervalSpawn : RitualVisualEffectComp -{ - public int lastSpawnTick = -1; - - public int ticksPassed; - - protected int burstsDone; - - protected CompProperties_RitualEffectIntervalSpawn Props => (CompProperties_RitualEffectIntervalSpawn)props; - - public override bool ShouldSpawnNow(LordJob_Ritual ritual) - { - if (Props.delay > 0 && ticksPassed < Props.delay) - { - return false; - } - if (Props.maxBursts > 0 && burstsDone >= Props.maxBursts) - { - return false; - } - if (lastSpawnTick != -1) - { - return GenTicks.TicksGame - lastSpawnTick >= Props.spawnIntervalTicks; - } - return true; - } - - public override void TickInterval(int delta) - { - base.TickInterval(delta); - ticksPassed += delta; - } - - public override void ExposeData() - { - base.ExposeData(); - Scribe_Values.Look(ref lastSpawnTick, "lastSpawnTick", -1); - Scribe_Values.Look(ref burstsDone, "burstsDone", 0); - Scribe_Values.Look(ref ticksPassed, "ticksPassed", 0); - } -} -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\Verse\Gene_Clotting.txt` -**相似度:** 0.5078 - -```csharp -public class Gene_Clotting : Gene -{ - private const int ClotCheckInterval = 360; - - private static readonly FloatRange TendingQualityRange = new FloatRange(0.2f, 0.7f); - - public override void TickInterval(int delta) - { - base.TickInterval(delta); - if (!pawn.IsHashIntervalTick(360, delta)) - { - return; - } - List hediffs = pawn.health.hediffSet.hediffs; - for (int num = hediffs.Count - 1; num >= 0; num--) - { - if (hediffs[num].Bleeding) - { - hediffs[num].Tended(TendingQualityRange.RandomInRange, TendingQualityRange.TrueMax, 1); - } - } - } -} -``` \ No newline at end of file diff --git a/MCP/vector_cache/PsychicRitualDef.txt b/MCP/vector_cache/PsychicRitualDef.txt deleted file mode 100644 index 1cb31bc6..00000000 --- a/MCP/vector_cache/PsychicRitualDef.txt +++ /dev/null @@ -1,871 +0,0 @@ -根据向量相似度分析,与 'PsychicRitualDef' 最相关的代码定义如下: - ---- -**文件路径 (精确匹配):** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\PsychicRitualDef.txt` - -```csharp -public class PsychicRitualDef : Def -{ - public ResearchProjectDef researchPrerequisite; - - public bool allowsDrafting; - - public bool allowsFloatMenu; - - public int cooldownHours; - - public bool nonRequiredPawnsMayLeave; - - public float rolePowerFactor = 0.2f; - - public bool aiCastable; - - public bool playerCastable = true; - - public float minThreatPoints; - - public bool castableOnPocketMaps = true; - - public List layerWhitelist = new List(); - - [MustTranslate] - public string letterAICompleteLabel; - - [MustTranslate] - public string letterAICompleteText; - - [MustTranslate] - public string letterAIArrivedText; - - [NoTranslate] - public string iconPath; - - public Texture2D uiIcon = BaseContent.BadTex; - - private List rolesBackingList = new List(8); - - private static readonly List tmpPawnsIterationList = new List(16); - - public virtual List Roles - { - get - { - rolesBackingList.Clear(); - return rolesBackingList; - } - } - - public bool Visible - { - get - { - if (!playerCastable) - { - return false; - } - if (DebugSettings.godMode) - { - return true; - } - if (researchPrerequisite == null) - { - return true; - } - if (!researchPrerequisite.IsFinished) - { - return false; - } - return true; - } - } - - public override void PostLoad() - { - if (!string.IsNullOrEmpty(iconPath)) - { - LongEventHandler.ExecuteWhenFinished(delegate - { - uiIcon = ContentFinder.Get(iconPath); - }); - } - } - - public virtual AcceptanceReport AllowsDrafting(Pawn pawn) - { - if (allowsDrafting) - { - return true; - } - return new AcceptanceReport("ParticipatingInPsychicRitual".Translate(pawn, label)); - } - - public virtual AcceptanceReport AllowsFloatMenu(Pawn pawn) - { - if (allowsFloatMenu) - { - return true; - } - return new AcceptanceReport("ParticipatingInPsychicRitual".Translate(pawn, label)); - } - - public virtual bool BlocksSocialInteraction(Pawn pawn) - { - return true; - } - - public virtual AcceptanceReport AbilityAllowed(Ability ability) - { - return new AcceptanceReport("AbilityDisabledInPsychicRitual".Translate(ability.pawn, label)); - } - - public virtual PsychicRitualGraph CreateGraph() - { - return new PsychicRitualGraph(); - } - - public virtual List CreateToils(PsychicRitual psychicRitual, PsychicRitualGraph parent) - { - throw new NotImplementedException("You must subclass PsychicRitualDef and override CreateToils() to return a list of toils."); - } - - public virtual PsychicRitualCandidatePool FindCandidatePool() - { - return new PsychicRitualCandidatePool(new List(Find.CurrentMap.mapPawns.FreeColonistsAndPrisonersSpawned.Where((Pawn p) => !p.IsSubhuman)), new List()); - } - - public virtual PsychicRitualRoleAssignments BuildRoleAssignments(TargetInfo target) - { - return new PsychicRitualRoleAssignments(Roles, target); - } - - public static bool OfferingReachable(Map map, List pawns, IngredientCount offering, out int reachableCount) - { - using (new ProfilerBlock("Offering reachable")) - { - reachableCount = 0; - float num = offering.GetBaseCount(); - if (num <= 0f) - { - return true; - } - List list; - using (new ProfilerBlock("ThingsMatchingFilter")) - { - list = map.listerThings.ThingsMatchingFilter(offering.filter); - } - foreach (Thing item in list) - { - if (num <= 0f) - { - break; - } - foreach (Pawn pawn in pawns) - { - if (pawn.CanReserveAndReach(item, PathEndMode.Touch, pawn.NormalMaxDanger()) && !item.IsForbidden(pawn) && !item.Fogged()) - { - num -= (float)item.stackCount; - reachableCount += item.stackCount; - break; - } - } - } - return num <= 0f; - } - } - - public virtual IEnumerable BlockingIssues(PsychicRitualRoleAssignments assignments, Map map) - { - return Enumerable.Empty(); - } - - public virtual TaggedString PsychicRitualBegunMessage(PsychicRitualRoleAssignments assignments) - { - return "PsychicRitualBegun".Translate(label); - } - - public virtual TaggedString PsychicRitualCompletedMessage() - { - return "PsychicRitualCompleted".Translate(label); - } - - public virtual TaggedString PsychicRitualCanceledMessage(TaggedString reason) - { - if (reason.NullOrEmpty()) - { - return "PsychicRitualCanceled".Translate(label); - } - return "PsychicRitualCanceledBecause".Translate(label, reason); - } - - public virtual TaggedString LeftPsychicRitualMessage(Pawn pawn, TaggedString reason) - { - if (reason.NullOrEmpty()) - { - return "PsychicRitualLeft".Translate(pawn, label); - } - return "PsychicRitualLeftBecause".Translate(pawn, label, reason); - } - - public virtual string GetPawnReport(PsychicRitual psychicRitual, Pawn pawn) - { - return "PsychicRitualAttending".Translate(label.Named("RITUALNAME")); - } - - public virtual Lord MakeNewLord(PsychicRitualRoleAssignments assignments) - { - Lord lord = LordMaker.MakeNewLord(Faction.OfPlayer, new LordJob_PsychicRitual(this, assignments), Find.CurrentMap, assignments.AllAssignedPawns); - if (assignments.Target.Thing is Building b) - { - lord.AddBuilding(b); - } - return lord; - } - - public virtual bool IsValidTarget(TargetInfo target, out AnyEnum reason) - { - reason = AnyEnum.None; - return true; - } - - public virtual TaggedString InvalidTargetReason(AnyEnum reason) - { - if (reason == AnyEnum.None) - { - return TaggedString.Empty; - } - throw new InvalidOperationException("Unknown enum type " + reason.enumType.ToStringSafe() + "; did you forget to override `InvalidTargetReason` in a child class?"); - } - - public virtual void CalculateMaxPower(PsychicRitualRoleAssignments assignments, List powerFactorsOut, out float power) - { - power = 0f; - int num = 0; - IReadOnlyDictionary> roleAssignments = assignments.RoleAssignments; - PsychicRitualRoleDef key; - List value; - foreach (KeyValuePair> item in roleAssignments) - { - item.Deconstruct(out key, out value); - PsychicRitualRoleDef psychicRitualRoleDef = key; - List list = value; - if (psychicRitualRoleDef.applyPowerOffset) - { - num += list.Count; - } - if (psychicRitualRoleDef.MaxCount != psychicRitualRoleDef.MinCount) - { - float num2 = (float)(list.Count - psychicRitualRoleDef.MinCount) / (float)(psychicRitualRoleDef.MaxCount - psychicRitualRoleDef.MinCount); - power += rolePowerFactor * num2; - powerFactorsOut?.Add(new QualityFactor - { - count = $"{list.Count} / {psychicRitualRoleDef.MaxCount}", - label = Find.ActiveLanguageWorker.Pluralize(psychicRitualRoleDef.LabelCap), - positive = (list.Count >= psychicRitualRoleDef.MinCount), - quality = rolePowerFactor * num2, - toolTip = psychicRitualRoleDef.description.CapitalizeFirst().EndWithPeriod() - }); - } - } - if (num > 0) - { - float num3 = 0f; - foreach (KeyValuePair> item2 in roleAssignments) - { - item2.Deconstruct(out key, out value); - PsychicRitualRoleDef psychicRitualRoleDef2 = key; - List list2 = value; - if (!psychicRitualRoleDef2.applyPowerOffset) - { - continue; - } - foreach (Pawn item3 in list2) - { - num3 += item3.GetStatValue(StatDefOf.PsychicRitualQualityOffset) / (float)num; - } - } - if (!Mathf.Approximately(num3, 0f)) - { - power += num3; - powerFactorsOut?.Add(new QualityFactor - { - label = "PsychicRitualDef_InvocationCircle_QualityFactor_Ideoligion".Translate(), - positive = (num3 > 0f), - count = num3.ToStringPercent(), - quality = num3, - toolTip = "PsychicRitualDef_InvocationCircle_QualityFactor_Ideoligion_Tooltip".Translate() - }); - } - } - power = Mathf.Clamp01(power); - } - - public virtual void RemoveIncapablePawns(PsychicRitual psychicRitual) - { - foreach (var (psychicRitualRoleDef2, collection) in psychicRitual.assignments.RoleAssignments) - { - tmpPawnsIterationList.Clear(); - tmpPawnsIterationList.AddRange(collection); - foreach (Pawn tmpPawnsIteration in tmpPawnsIterationList) - { - if (!psychicRitualRoleDef2.PawnCanDo(PsychicRitualRoleDef.Context.Runtime, tmpPawnsIteration, psychicRitual.assignments.Target, out var reason) && psychicRitual.LeaveOrCancelPsychicRitual(psychicRitualRoleDef2, tmpPawnsIteration, reason.ToPlayerReadable()) == PsychicRitual.LeftOrCanceled.Canceled) - { - return; - } - } - } - } - - public virtual void CheckPsychicRitualCancelConditions(PsychicRitual psychicRitual) - { - TargetInfo target = psychicRitual.assignments.Target; - if (target.ThingDestroyed) - { - psychicRitual.CancelPsychicRitual("PsychicRitualDef_TargetDestroyed".Translate(target.Thing.Named("TARGET"))); - } - } - - public virtual TaggedString OutcomeDescription(FloatRange qualityRange, string qualityNumber, PsychicRitualRoleAssignments assignments) - { - return TaggedString.Empty; - } - - public virtual IEnumerable OutcomeWarnings(PsychicRitualRoleAssignments assignments) - { - return Enumerable.Empty(); - } - - public virtual TaggedString TimeAndOfferingLabel() - { - return TaggedString.Empty; - } - - public virtual void InitializeCast(Map map) - { - } - - public virtual IntVec3 GetBestStandableRolePosition(bool playerRitual, IntVec3 origin, IntVec3 ritualPosition, Map map, float radius = 8f) - { - if (playerRitual) - { - return origin; - } - IntVec3 result = CellFinder.StandableCellNear(origin, map, radius, (IntVec3 c) => map.reachability.CanReach(ritualPosition, c, PathEndMode.OnCell, TraverseMode.NoPassClosedDoorsOrWater)); - if (result.IsValid) - { - return result; - } - return origin; - } - - public virtual IEnumerable GetPawnTooltipExtras(Pawn pawn) - { - yield break; - } -} -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\PsychicRitualDef_NeurosisPulse.txt` -**相似度:** 0.7397 - -```csharp -public class PsychicRitualDef_NeurosisPulse : PsychicRitualDef_InvocationCircle -{ - public SimpleCurve durationDaysFromQualityCurve; - - public override List CreateToils(PsychicRitual psychicRitual, PsychicRitualGraph graph) - { - List list = base.CreateToils(psychicRitual, graph); - list.Add(new PsychicRitualToil_NeurosisPulse(InvokerRole)); - return list; - } - - public override TaggedString OutcomeDescription(FloatRange qualityRange, string qualityNumber, PsychicRitualRoleAssignments assignments) - { - return outcomeDescription.Formatted(Mathf.FloorToInt(durationDaysFromQualityCurve.Evaluate(qualityRange.min) * 60000f).ToStringTicksToDays()); - } -} -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\PsychicRitualDef_Psychophagy.txt` -**相似度:** 0.7324 - -```csharp -public class PsychicRitualDef_Psychophagy : PsychicRitualDef_InvocationCircle -{ - public FloatRange brainDamageRange; - - public SimpleCurve effectDurationDaysFromQualityCurve; - - public override List CreateToils(PsychicRitual psychicRitual, PsychicRitualGraph parent) - { - List list = base.CreateToils(psychicRitual, parent); - list.Add(new PsychicRitualToil_Psychophagy(InvokerRole, TargetRole, brainDamageRange)); - list.Add(new PsychicRitualToil_TargetCleanup(InvokerRole, TargetRole)); - return list; - } - - public override TaggedString OutcomeDescription(FloatRange qualityRange, string qualityNumber, PsychicRitualRoleAssignments assignments) - { - string text = Mathf.FloorToInt(effectDurationDaysFromQualityCurve.Evaluate(qualityRange.min) * 60000f).ToStringTicksToDays(); - IntRange disappearsAfterTicks = HediffDefOf.DarkPsychicShock.CompProps().disappearsAfterTicks; - FloatRange floatRange = new FloatRange(Mathf.FloorToInt(disappearsAfterTicks.min.TicksToDays()), Mathf.FloorToInt(disappearsAfterTicks.max.TicksToDays())); - return outcomeDescription.Formatted(text, floatRange.ToString(), brainDamageRange.ToString()); - } -} -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\Verse.AI.Group\PsychicRitualToil_PleasurePulse.txt` -**相似度:** 0.7237 - -```csharp -public class PsychicRitualToil_PleasurePulse : PsychicRitualToil -{ - private PsychicRitualRoleDef invokerRole; - - protected PsychicRitualToil_PleasurePulse() - { - } - - public PsychicRitualToil_PleasurePulse(PsychicRitualRoleDef invokerRole) - { - this.invokerRole = invokerRole; - } - - public override void Start(PsychicRitual psychicRitual, PsychicRitualGraph parent) - { - base.Start(psychicRitual, parent); - Pawn pawn = psychicRitual.assignments.FirstAssignedPawn(invokerRole); - float duration = ((PsychicRitualDef_PleasurePulse)psychicRitual.def).durationDaysFromQualityCurve.Evaluate(psychicRitual.PowerPercent); - psychicRitual.ReleaseAllPawnsAndBuildings(); - if (pawn != null) - { - ApplyOutcome(psychicRitual, pawn, duration); - } - } - - private void ApplyOutcome(PsychicRitual psychicRitual, Pawn invoker, float duration) - { - foreach (Pawn item in invoker.Map.mapPawns.AllHumanlikeSpawned) - { - if (!(item.GetStatValue(StatDefOf.PsychicSensitivity) <= 0f)) - { - Hediff firstHediffOfDef = item.health.hediffSet.GetFirstHediffOfDef(HediffDefOf.NeurosisPulse); - if (firstHediffOfDef != null) - { - item.health.RemoveHediff(firstHediffOfDef); - } - Hediff hediff = HediffMaker.MakeHediff(HediffDefOf.PleasurePulse, item); - HediffComp_Disappears hediffComp_Disappears = hediff.TryGetComp(); - if (hediffComp_Disappears != null) - { - hediffComp_Disappears.ticksToDisappear = Mathf.RoundToInt(duration * 60000f); - } - item.health.AddHediff(hediff); - } - } - Find.LetterStack.ReceiveLetter("PsychicRitualCompleteLabel".Translate(psychicRitual.def.label), "PleasurePulseCompleteText".Translate(invoker, Mathf.FloorToInt(duration * 60000f).ToStringTicksToDays(), psychicRitual.def.Named("RITUAL")), LetterDefOf.NeutralEvent); - } - - public override void ExposeData() - { - base.ExposeData(); - Scribe_Defs.Look(ref invokerRole, "invokerRole"); - } -} -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\PsychicRitualDef_InvocationCircle.txt` -**相似度:** 0.7220 - -```csharp -public class PsychicRitualDef_InvocationCircle : PsychicRitualDef -{ - public enum InvalidTargetReasonEnum - { - None, - AreaNotClear - } - - private class RitualQualityOffsetCount - { - public float offset; - - public int count; - - public RitualQualityOffsetCount(int count, float offset) - { - this.count = count; - this.offset = offset; - } - } - - public FloatRange hoursUntilHoraxEffect; - - public FloatRange hoursUntilOutcome; - - public float invocationCircleRadius = 3.9f; - - [MustTranslate] - public string outcomeDescription; - - public float psychicSensitivityPowerFactor = 0.25f; - - protected PsychicRitualRoleDef invokerRole; - - protected PsychicRitualRoleDef chanterRole; - - protected PsychicRitualRoleDef targetRole; - - protected PsychicRitualRoleDef defenderRole; - - protected IngredientCount requiredOffering; - - protected string timeAndOfferingLabelCached; - - public static readonly SimpleCurve PsychicSensitivityToPowerFactor = new SimpleCurve - { - new CurvePoint(0f, 0f), - new CurvePoint(1f, 0.5f), - new CurvePoint(2f, 0.9f), - new CurvePoint(3f, 1f) - }; - - protected const int DurationTicksWaitPostEffect = 120; - - private static Dictionary> tmpParticipants = new Dictionary>(8); - - private List tmpGatheringPawns = new List(8); - - public virtual PsychicRitualRoleDef InvokerRole => invokerRole; - - public virtual PsychicRitualRoleDef ChanterRole => chanterRole; - - public virtual PsychicRitualRoleDef TargetRole => targetRole; - - public virtual PsychicRitualRoleDef DefenderRole => defenderRole; - - public virtual IngredientCount RequiredOffering => requiredOffering; - - public TaggedString CooldownLabel => "PsychicRitualCooldownLabel".Translate() + ": " + (cooldownHours * 2500).ToStringTicksToPeriod(); - - public override List Roles - { - get - { - List roles = base.Roles; - if (InvokerRole != null) - { - roles.Add(InvokerRole); - } - if (TargetRole != null) - { - roles.Add(TargetRole); - } - if (ChanterRole != null) - { - roles.Add(ChanterRole); - } - if (DefenderRole != null) - { - roles.Add(DefenderRole); - } - return roles; - } - } - - public override void ResolveReferences() - { - base.ResolveReferences(); - requiredOffering?.ResolveReferences(); - invokerRole = invokerRole ?? PsychicRitualRoleDefOf.Invoker; - chanterRole = chanterRole ?? PsychicRitualRoleDefOf.Chanter; - } - - public override List CreateToils(PsychicRitual psychicRitual, PsychicRitualGraph parent) - { - float randomInRange = hoursUntilOutcome.RandomInRange; - IReadOnlyDictionary> readOnlyDictionary = GenerateRolePositions(psychicRitual.assignments); - return new List - { - new PsychicRitualToil_GatherForInvocation(psychicRitual, this, readOnlyDictionary), - new PsychicRitualToil_InvokeHorax(InvokerRole, readOnlyDictionary.TryGetValue(InvokerRole), TargetRole, readOnlyDictionary.TryGetValue(TargetRole), ChanterRole, readOnlyDictionary.TryGetValue(ChanterRole), DefenderRole, readOnlyDictionary.TryGetValue(DefenderRole), RequiredOffering) - { - hoursUntilHoraxEffect = hoursUntilHoraxEffect.RandomInRange, - hoursUntilOutcome = randomInRange - }, - new PsychicRitualToil_Wait(120) - }; - } - - public override bool IsValidTarget(TargetInfo target, out AnyEnum reason) - { - foreach (IntVec3 item in GenRadial.RadialCellsAround(target.Cell, invocationCircleRadius, useCenter: true)) - { - if (!item.Standable(target.Map)) - { - reason = AnyEnum.FromEnum(InvalidTargetReasonEnum.AreaNotClear); - return false; - } - } - reason = AnyEnum.None; - return true; - } - - public override TaggedString InvalidTargetReason(AnyEnum reason) - { - InvalidTargetReasonEnum? invalidTargetReasonEnum = reason.As(); - if (invalidTargetReasonEnum.HasValue) - { - InvalidTargetReasonEnum valueOrDefault = invalidTargetReasonEnum.GetValueOrDefault(); - return valueOrDefault switch - { - InvalidTargetReasonEnum.None => TaggedString.Empty, - InvalidTargetReasonEnum.AreaNotClear => "PsychicRitualDef_InvocationCircle_AreaMustBeClear".Translate(), - _ => throw new InvalidOperationException($"Unknown reason {valueOrDefault}"), - }; - } - return base.InvalidTargetReason(reason); - } - - public override TaggedString OutcomeDescription(FloatRange qualityRange, string qualityNumber, PsychicRitualRoleAssignments assignments) - { - return outcomeDescription.Formatted(); - } - - public override IEnumerable OutcomeWarnings(PsychicRitualRoleAssignments assignments) - { - foreach (Pawn item in assignments.AssignedPawns(TargetRole)) - { - if (item.HomeFaction != null && item.HomeFaction != Faction.OfPlayer && item.HomeFaction.def.humanlikeFaction && !item.HomeFaction.def.PermanentlyHostileTo(FactionDefOf.PlayerColony) && !item.HomeFaction.temporary && !item.HomeFaction.Hidden) - { - yield return "PsychicRitualFactionWarning".Translate(item.Named("PAWN"), item.HomeFaction.Named("FACTION")).Colorize(ColoredText.WarningColor); - } - } - } - - public override TaggedString TimeAndOfferingLabel() - { - if (timeAndOfferingLabelCached != null) - { - return timeAndOfferingLabelCached; - } - StringBuilder stringBuilder = new StringBuilder(); - stringBuilder.AppendLine(DurationLabel()); - stringBuilder.Append(CooldownLabel); - if (!OfferingLabel().NullOrEmpty()) - { - stringBuilder.AppendLine(); - stringBuilder.Append(OfferingLabel()); - } - timeAndOfferingLabelCached = stringBuilder.ToString(); - return timeAndOfferingLabelCached; - } - - private TaggedString OfferingLabel() - { - StringBuilder stringBuilder = new StringBuilder(); - if (RequiredOffering != null) - { - stringBuilder.Append("PsychicRitualRequiredOffering".Translate().CapitalizeFirst()); - stringBuilder.Append(": "); - stringBuilder.Append(RequiredOffering.SummaryFilterFirst); - } - return stringBuilder.ToString(); - } - - public TaggedString DurationLabel() - { - string value = ((int)(hoursUntilOutcome.Average * 2500f)).ToStringTicksToPeriod(); - TaggedString taggedString = ((hoursUntilOutcome.min != hoursUntilOutcome.max) ? "ExpectedLordJobDuration".Translate().CapitalizeFirst() : "PsychicRitualExpectedDurationLabel".Translate().CapitalizeFirst()); - StringBuilder stringBuilder = new StringBuilder(); - stringBuilder.Append(taggedString); - stringBuilder.Append(": "); - stringBuilder.Append(value); - return stringBuilder.ToString(); - } - - private IReadOnlyDictionary> GenerateRolePositions(PsychicRitualRoleAssignments assignments) - { - tmpParticipants.ClearAndPoolValueLists(); - foreach (PsychicRitualRoleDef role in Roles) - { - tmpParticipants[role] = SimplePool>.Get(); - } - int num = assignments.RoleAssignedCount(ChanterRole) + assignments.RoleAssignedCount(InvokerRole); - int num2 = 0; - foreach (Pawn item in assignments.AssignedPawns(InvokerRole)) - { - _ = item; - int num3 = 0; - IntVec3 cell; - do - { - cell = assignments.Target.Cell; - cell += IntVec3.FromPolar(360f * (float)num2++ / (float)num, invocationCircleRadius); - } - while (!cell.Walkable(assignments.Target.Map) && num3++ <= 10); - if (num3 >= 10) - { - cell = assignments.Target.Cell; - } - tmpParticipants[InvokerRole].Add(cell); - } - foreach (Pawn item2 in assignments.AssignedPawns(ChanterRole)) - { - _ = item2; - IntVec3 cell2 = assignments.Target.Cell; - cell2 += IntVec3.FromPolar(360f * (float)num2++ / (float)num, invocationCircleRadius); - tmpParticipants[ChanterRole].Add(cell2); - } - foreach (Pawn item3 in assignments.AssignedPawns(TargetRole)) - { - _ = item3; - tmpParticipants[TargetRole].Add(assignments.Target.Cell); - } - if (DefenderRole != null) - { - num2 = 0; - int num4 = assignments.RoleAssignedCount(DefenderRole); - bool playerRitual = assignments.AllAssignedPawns.Any((Pawn x) => x.Faction == Faction.OfPlayer); - foreach (Pawn item4 in assignments.AssignedPawns(DefenderRole)) - { - _ = item4; - IntVec3 cell3 = assignments.Target.Cell; - cell3 += IntVec3.FromPolar(360f * (float)num2++ / (float)num4, invocationCircleRadius + 5f); - cell3 = GetBestStandableRolePosition(playerRitual, cell3, assignments.Target.Cell, assignments.Target.Map); - tmpParticipants[DefenderRole].Add(cell3); - } - } - return tmpParticipants; - } - - public override IEnumerable BlockingIssues(PsychicRitualRoleAssignments assignments, Map map) - { - using (new ProfilerBlock("PsychicRitualDef.BlockingIssues")) - { - tmpGatheringPawns.Clear(); - foreach (var (psychicRitualRoleDef2, collection) in assignments.RoleAssignments) - { - if (psychicRitualRoleDef2.CanHandleOfferings) - { - tmpGatheringPawns.AddRange(collection); - } - } - tmpGatheringPawns.RemoveAll(map, (Map _map, Pawn _pawn) => _pawn.MapHeld != _map); - if (TargetRole != null && InvokerRole != null) - { - Pawn pawn = assignments.FirstAssignedPawn(TargetRole); - if (pawn != null) - { - Pawn pawn2 = assignments.FirstAssignedPawn(InvokerRole); - if (pawn2 != null && pawn.IsPrisoner && !map.reachability.CanReach(assignments.Target.Cell, pawn.PositionHeld, PathEndMode.Touch, TraverseParms.For(pawn2))) - { - yield return "PsychicRitualTargetUnreachableByInvoker".Translate(pawn.Named("TARGET"), pawn2.Named("INVOKER")); - } - } - } - if (RequiredOffering != null && !PsychicRitualDef.OfferingReachable(map, tmpGatheringPawns, RequiredOffering, out var reachableCount)) - { - yield return "PsychicRitualOfferingsInsufficient".Translate(RequiredOffering.SummaryFilterFirst, reachableCount); - } - } - } - - public override void CalculateMaxPower(PsychicRitualRoleAssignments assignments, List powerFactorsOut, out float power) - { - power = 0f; - foreach (Pawn item in assignments.AssignedPawns(InvokerRole)) - { - float statValue = item.GetStatValue(StatDefOf.PsychicSensitivity); - float num = PsychicSensitivityToPowerFactor.Evaluate(statValue); - num *= psychicSensitivityPowerFactor; - powerFactorsOut?.Add(new QualityFactor - { - label = "PsychicRitualDef_InvocationCircle_QualityFactor_PsychicSensitivity".Translate(item.Named("PAWN")), - positive = (statValue >= 1f), - count = statValue.ToStringPercent(), - quality = num, - toolTip = "PsychicRitualDef_InvocationCircle_QualityFactor_PsychicSensitivity_Tooltip".Translate(item.Named("PAWN")) - }); - power += num; - } - base.CalculateMaxPower(assignments, powerFactorsOut, out var power2); - power += power2; - if (assignments.Target.Thing is Building building) - { - CalculateFacilityQualityOffset(powerFactorsOut, ref power, building); - } - power = Mathf.Clamp01(power); - } - - private static void CalculateFacilityQualityOffset(List powerFactorsOut, ref float power, Building building) - { - Dictionary dictionary = new Dictionary(); - List linkedFacilitiesListForReading = building.GetComp().LinkedFacilitiesListForReading; - for (int i = 0; i < linkedFacilitiesListForReading.Count; i++) - { - Thing thing = linkedFacilitiesListForReading[i]; - CompFacility compFacility = thing.TryGetComp(); - if (compFacility?.StatOffsets == null) - { - continue; - } - for (int j = 0; j < compFacility.StatOffsets.Count; j++) - { - StatModifier statModifier = compFacility.StatOffsets[j]; - if (statModifier.stat == StatDefOf.PsychicRitualQuality) - { - if (dictionary.TryGetValue(thing.def, out var value)) - { - value.count++; - value.offset += statModifier.value; - } - else - { - dictionary.Add(thing.def, new RitualQualityOffsetCount(1, statModifier.value)); - } - } - } - } - foreach (KeyValuePair item in dictionary) - { - powerFactorsOut?.Add(new QualityFactor - { - label = Find.ActiveLanguageWorker.Pluralize(item.Key.label).CapitalizeFirst(), - positive = true, - count = item.Value.count + " / " + item.Key.GetCompProperties().maxSimultaneous, - quality = item.Value.offset, - toolTip = "PsychicRitualDef_InvocationCircle_QualityFactor_Increase_Tooltip".Translate().CapitalizeFirst().EndWithPeriod() - }); - power += item.Value.offset; - } - } - - public override IEnumerable SpecialDisplayStats(StatRequest req) - { - foreach (StatDrawEntry item in base.SpecialDisplayStats(req)) - { - yield return item; - } - if (requiredOffering != null) - { - yield return new StatDrawEntry(StatCategoryDefOf.PsychicRituals, "StatsReport_Offering".Translate(), requiredOffering.SummaryFilterFirst, "StatsReport_Offering_Desc".Translate(), 1000); - } - yield return new StatDrawEntry(StatCategoryDefOf.PsychicRituals, "StatsReport_RitualDuration".Translate(), Mathf.FloorToInt(hoursUntilOutcome.min * 2500f).ToStringTicksToPeriod(), "StatsReport_RitualDuration_Desc".Translate(), 500); - yield return new StatDrawEntry(StatCategoryDefOf.PsychicRituals, "StatsReport_RitualCooldown".Translate(), (cooldownHours * 2500).ToStringTicksToPeriod(), "StatsReport_RitualCooldown_Desc".Translate(), 100); - } - - public override void CheckPsychicRitualCancelConditions(PsychicRitual psychicRitual) - { - base.CheckPsychicRitualCancelConditions(psychicRitual); - if (!psychicRitual.canceled && invokerRole != null) - { - Pawn pawn = psychicRitual.assignments.FirstAssignedPawn(InvokerRole); - if (pawn != null && pawn.DeadOrDowned) - { - psychicRitual.CancelPsychicRitual("PsychicRitualDef_InvocationCircle_InvokerLost".Translate(pawn.Named("PAWN"))); - } - } - } -} -``` \ No newline at end of file diff --git a/MCP/vector_cache/PsychicRitualDef_InvocationCircle.txt b/MCP/vector_cache/PsychicRitualDef_InvocationCircle.txt deleted file mode 100644 index 8b20176c..00000000 --- a/MCP/vector_cache/PsychicRitualDef_InvocationCircle.txt +++ /dev/null @@ -1,573 +0,0 @@ -根据向量相似度分析,与 'PsychicRitualDef_InvocationCircle' 最相关的代码定义如下: - ---- -**文件路径 (精确匹配):** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\PsychicRitualDef_InvocationCircle.txt` - -```csharp -public class PsychicRitualDef_InvocationCircle : PsychicRitualDef -{ - public enum InvalidTargetReasonEnum - { - None, - AreaNotClear - } - - private class RitualQualityOffsetCount - { - public float offset; - - public int count; - - public RitualQualityOffsetCount(int count, float offset) - { - this.count = count; - this.offset = offset; - } - } - - public FloatRange hoursUntilHoraxEffect; - - public FloatRange hoursUntilOutcome; - - public float invocationCircleRadius = 3.9f; - - [MustTranslate] - public string outcomeDescription; - - public float psychicSensitivityPowerFactor = 0.25f; - - protected PsychicRitualRoleDef invokerRole; - - protected PsychicRitualRoleDef chanterRole; - - protected PsychicRitualRoleDef targetRole; - - protected PsychicRitualRoleDef defenderRole; - - protected IngredientCount requiredOffering; - - protected string timeAndOfferingLabelCached; - - public static readonly SimpleCurve PsychicSensitivityToPowerFactor = new SimpleCurve - { - new CurvePoint(0f, 0f), - new CurvePoint(1f, 0.5f), - new CurvePoint(2f, 0.9f), - new CurvePoint(3f, 1f) - }; - - protected const int DurationTicksWaitPostEffect = 120; - - private static Dictionary> tmpParticipants = new Dictionary>(8); - - private List tmpGatheringPawns = new List(8); - - public virtual PsychicRitualRoleDef InvokerRole => invokerRole; - - public virtual PsychicRitualRoleDef ChanterRole => chanterRole; - - public virtual PsychicRitualRoleDef TargetRole => targetRole; - - public virtual PsychicRitualRoleDef DefenderRole => defenderRole; - - public virtual IngredientCount RequiredOffering => requiredOffering; - - public TaggedString CooldownLabel => "PsychicRitualCooldownLabel".Translate() + ": " + (cooldownHours * 2500).ToStringTicksToPeriod(); - - public override List Roles - { - get - { - List roles = base.Roles; - if (InvokerRole != null) - { - roles.Add(InvokerRole); - } - if (TargetRole != null) - { - roles.Add(TargetRole); - } - if (ChanterRole != null) - { - roles.Add(ChanterRole); - } - if (DefenderRole != null) - { - roles.Add(DefenderRole); - } - return roles; - } - } - - public override void ResolveReferences() - { - base.ResolveReferences(); - requiredOffering?.ResolveReferences(); - invokerRole = invokerRole ?? PsychicRitualRoleDefOf.Invoker; - chanterRole = chanterRole ?? PsychicRitualRoleDefOf.Chanter; - } - - public override List CreateToils(PsychicRitual psychicRitual, PsychicRitualGraph parent) - { - float randomInRange = hoursUntilOutcome.RandomInRange; - IReadOnlyDictionary> readOnlyDictionary = GenerateRolePositions(psychicRitual.assignments); - return new List - { - new PsychicRitualToil_GatherForInvocation(psychicRitual, this, readOnlyDictionary), - new PsychicRitualToil_InvokeHorax(InvokerRole, readOnlyDictionary.TryGetValue(InvokerRole), TargetRole, readOnlyDictionary.TryGetValue(TargetRole), ChanterRole, readOnlyDictionary.TryGetValue(ChanterRole), DefenderRole, readOnlyDictionary.TryGetValue(DefenderRole), RequiredOffering) - { - hoursUntilHoraxEffect = hoursUntilHoraxEffect.RandomInRange, - hoursUntilOutcome = randomInRange - }, - new PsychicRitualToil_Wait(120) - }; - } - - public override bool IsValidTarget(TargetInfo target, out AnyEnum reason) - { - foreach (IntVec3 item in GenRadial.RadialCellsAround(target.Cell, invocationCircleRadius, useCenter: true)) - { - if (!item.Standable(target.Map)) - { - reason = AnyEnum.FromEnum(InvalidTargetReasonEnum.AreaNotClear); - return false; - } - } - reason = AnyEnum.None; - return true; - } - - public override TaggedString InvalidTargetReason(AnyEnum reason) - { - InvalidTargetReasonEnum? invalidTargetReasonEnum = reason.As(); - if (invalidTargetReasonEnum.HasValue) - { - InvalidTargetReasonEnum valueOrDefault = invalidTargetReasonEnum.GetValueOrDefault(); - return valueOrDefault switch - { - InvalidTargetReasonEnum.None => TaggedString.Empty, - InvalidTargetReasonEnum.AreaNotClear => "PsychicRitualDef_InvocationCircle_AreaMustBeClear".Translate(), - _ => throw new InvalidOperationException($"Unknown reason {valueOrDefault}"), - }; - } - return base.InvalidTargetReason(reason); - } - - public override TaggedString OutcomeDescription(FloatRange qualityRange, string qualityNumber, PsychicRitualRoleAssignments assignments) - { - return outcomeDescription.Formatted(); - } - - public override IEnumerable OutcomeWarnings(PsychicRitualRoleAssignments assignments) - { - foreach (Pawn item in assignments.AssignedPawns(TargetRole)) - { - if (item.HomeFaction != null && item.HomeFaction != Faction.OfPlayer && item.HomeFaction.def.humanlikeFaction && !item.HomeFaction.def.PermanentlyHostileTo(FactionDefOf.PlayerColony) && !item.HomeFaction.temporary && !item.HomeFaction.Hidden) - { - yield return "PsychicRitualFactionWarning".Translate(item.Named("PAWN"), item.HomeFaction.Named("FACTION")).Colorize(ColoredText.WarningColor); - } - } - } - - public override TaggedString TimeAndOfferingLabel() - { - if (timeAndOfferingLabelCached != null) - { - return timeAndOfferingLabelCached; - } - StringBuilder stringBuilder = new StringBuilder(); - stringBuilder.AppendLine(DurationLabel()); - stringBuilder.Append(CooldownLabel); - if (!OfferingLabel().NullOrEmpty()) - { - stringBuilder.AppendLine(); - stringBuilder.Append(OfferingLabel()); - } - timeAndOfferingLabelCached = stringBuilder.ToString(); - return timeAndOfferingLabelCached; - } - - private TaggedString OfferingLabel() - { - StringBuilder stringBuilder = new StringBuilder(); - if (RequiredOffering != null) - { - stringBuilder.Append("PsychicRitualRequiredOffering".Translate().CapitalizeFirst()); - stringBuilder.Append(": "); - stringBuilder.Append(RequiredOffering.SummaryFilterFirst); - } - return stringBuilder.ToString(); - } - - public TaggedString DurationLabel() - { - string value = ((int)(hoursUntilOutcome.Average * 2500f)).ToStringTicksToPeriod(); - TaggedString taggedString = ((hoursUntilOutcome.min != hoursUntilOutcome.max) ? "ExpectedLordJobDuration".Translate().CapitalizeFirst() : "PsychicRitualExpectedDurationLabel".Translate().CapitalizeFirst()); - StringBuilder stringBuilder = new StringBuilder(); - stringBuilder.Append(taggedString); - stringBuilder.Append(": "); - stringBuilder.Append(value); - return stringBuilder.ToString(); - } - - private IReadOnlyDictionary> GenerateRolePositions(PsychicRitualRoleAssignments assignments) - { - tmpParticipants.ClearAndPoolValueLists(); - foreach (PsychicRitualRoleDef role in Roles) - { - tmpParticipants[role] = SimplePool>.Get(); - } - int num = assignments.RoleAssignedCount(ChanterRole) + assignments.RoleAssignedCount(InvokerRole); - int num2 = 0; - foreach (Pawn item in assignments.AssignedPawns(InvokerRole)) - { - _ = item; - int num3 = 0; - IntVec3 cell; - do - { - cell = assignments.Target.Cell; - cell += IntVec3.FromPolar(360f * (float)num2++ / (float)num, invocationCircleRadius); - } - while (!cell.Walkable(assignments.Target.Map) && num3++ <= 10); - if (num3 >= 10) - { - cell = assignments.Target.Cell; - } - tmpParticipants[InvokerRole].Add(cell); - } - foreach (Pawn item2 in assignments.AssignedPawns(ChanterRole)) - { - _ = item2; - IntVec3 cell2 = assignments.Target.Cell; - cell2 += IntVec3.FromPolar(360f * (float)num2++ / (float)num, invocationCircleRadius); - tmpParticipants[ChanterRole].Add(cell2); - } - foreach (Pawn item3 in assignments.AssignedPawns(TargetRole)) - { - _ = item3; - tmpParticipants[TargetRole].Add(assignments.Target.Cell); - } - if (DefenderRole != null) - { - num2 = 0; - int num4 = assignments.RoleAssignedCount(DefenderRole); - bool playerRitual = assignments.AllAssignedPawns.Any((Pawn x) => x.Faction == Faction.OfPlayer); - foreach (Pawn item4 in assignments.AssignedPawns(DefenderRole)) - { - _ = item4; - IntVec3 cell3 = assignments.Target.Cell; - cell3 += IntVec3.FromPolar(360f * (float)num2++ / (float)num4, invocationCircleRadius + 5f); - cell3 = GetBestStandableRolePosition(playerRitual, cell3, assignments.Target.Cell, assignments.Target.Map); - tmpParticipants[DefenderRole].Add(cell3); - } - } - return tmpParticipants; - } - - public override IEnumerable BlockingIssues(PsychicRitualRoleAssignments assignments, Map map) - { - using (new ProfilerBlock("PsychicRitualDef.BlockingIssues")) - { - tmpGatheringPawns.Clear(); - foreach (var (psychicRitualRoleDef2, collection) in assignments.RoleAssignments) - { - if (psychicRitualRoleDef2.CanHandleOfferings) - { - tmpGatheringPawns.AddRange(collection); - } - } - tmpGatheringPawns.RemoveAll(map, (Map _map, Pawn _pawn) => _pawn.MapHeld != _map); - if (TargetRole != null && InvokerRole != null) - { - Pawn pawn = assignments.FirstAssignedPawn(TargetRole); - if (pawn != null) - { - Pawn pawn2 = assignments.FirstAssignedPawn(InvokerRole); - if (pawn2 != null && pawn.IsPrisoner && !map.reachability.CanReach(assignments.Target.Cell, pawn.PositionHeld, PathEndMode.Touch, TraverseParms.For(pawn2))) - { - yield return "PsychicRitualTargetUnreachableByInvoker".Translate(pawn.Named("TARGET"), pawn2.Named("INVOKER")); - } - } - } - if (RequiredOffering != null && !PsychicRitualDef.OfferingReachable(map, tmpGatheringPawns, RequiredOffering, out var reachableCount)) - { - yield return "PsychicRitualOfferingsInsufficient".Translate(RequiredOffering.SummaryFilterFirst, reachableCount); - } - } - } - - public override void CalculateMaxPower(PsychicRitualRoleAssignments assignments, List powerFactorsOut, out float power) - { - power = 0f; - foreach (Pawn item in assignments.AssignedPawns(InvokerRole)) - { - float statValue = item.GetStatValue(StatDefOf.PsychicSensitivity); - float num = PsychicSensitivityToPowerFactor.Evaluate(statValue); - num *= psychicSensitivityPowerFactor; - powerFactorsOut?.Add(new QualityFactor - { - label = "PsychicRitualDef_InvocationCircle_QualityFactor_PsychicSensitivity".Translate(item.Named("PAWN")), - positive = (statValue >= 1f), - count = statValue.ToStringPercent(), - quality = num, - toolTip = "PsychicRitualDef_InvocationCircle_QualityFactor_PsychicSensitivity_Tooltip".Translate(item.Named("PAWN")) - }); - power += num; - } - base.CalculateMaxPower(assignments, powerFactorsOut, out var power2); - power += power2; - if (assignments.Target.Thing is Building building) - { - CalculateFacilityQualityOffset(powerFactorsOut, ref power, building); - } - power = Mathf.Clamp01(power); - } - - private static void CalculateFacilityQualityOffset(List powerFactorsOut, ref float power, Building building) - { - Dictionary dictionary = new Dictionary(); - List linkedFacilitiesListForReading = building.GetComp().LinkedFacilitiesListForReading; - for (int i = 0; i < linkedFacilitiesListForReading.Count; i++) - { - Thing thing = linkedFacilitiesListForReading[i]; - CompFacility compFacility = thing.TryGetComp(); - if (compFacility?.StatOffsets == null) - { - continue; - } - for (int j = 0; j < compFacility.StatOffsets.Count; j++) - { - StatModifier statModifier = compFacility.StatOffsets[j]; - if (statModifier.stat == StatDefOf.PsychicRitualQuality) - { - if (dictionary.TryGetValue(thing.def, out var value)) - { - value.count++; - value.offset += statModifier.value; - } - else - { - dictionary.Add(thing.def, new RitualQualityOffsetCount(1, statModifier.value)); - } - } - } - } - foreach (KeyValuePair item in dictionary) - { - powerFactorsOut?.Add(new QualityFactor - { - label = Find.ActiveLanguageWorker.Pluralize(item.Key.label).CapitalizeFirst(), - positive = true, - count = item.Value.count + " / " + item.Key.GetCompProperties().maxSimultaneous, - quality = item.Value.offset, - toolTip = "PsychicRitualDef_InvocationCircle_QualityFactor_Increase_Tooltip".Translate().CapitalizeFirst().EndWithPeriod() - }); - power += item.Value.offset; - } - } - - public override IEnumerable SpecialDisplayStats(StatRequest req) - { - foreach (StatDrawEntry item in base.SpecialDisplayStats(req)) - { - yield return item; - } - if (requiredOffering != null) - { - yield return new StatDrawEntry(StatCategoryDefOf.PsychicRituals, "StatsReport_Offering".Translate(), requiredOffering.SummaryFilterFirst, "StatsReport_Offering_Desc".Translate(), 1000); - } - yield return new StatDrawEntry(StatCategoryDefOf.PsychicRituals, "StatsReport_RitualDuration".Translate(), Mathf.FloorToInt(hoursUntilOutcome.min * 2500f).ToStringTicksToPeriod(), "StatsReport_RitualDuration_Desc".Translate(), 500); - yield return new StatDrawEntry(StatCategoryDefOf.PsychicRituals, "StatsReport_RitualCooldown".Translate(), (cooldownHours * 2500).ToStringTicksToPeriod(), "StatsReport_RitualCooldown_Desc".Translate(), 100); - } - - public override void CheckPsychicRitualCancelConditions(PsychicRitual psychicRitual) - { - base.CheckPsychicRitualCancelConditions(psychicRitual); - if (!psychicRitual.canceled && invokerRole != null) - { - Pawn pawn = psychicRitual.assignments.FirstAssignedPawn(InvokerRole); - if (pawn != null && pawn.DeadOrDowned) - { - psychicRitual.CancelPsychicRitual("PsychicRitualDef_InvocationCircle_InvokerLost".Translate(pawn.Named("PAWN"))); - } - } - } -} -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\Verse.AI.Group\PsychicRitualToil_GatherForInvocation.txt` -**相似度:** 0.7802 - -```csharp -public class PsychicRitualToil_GatherForInvocation : PsychicRitualToil_Multiplex -{ - protected PsychicRitualToil_Goto fallbackToil; - - protected PsychicRitualGraph invokerToil; - - protected PsychicRitualToil_Goto invokerFinalToil; - - private static List blockingPawns = new List(16); - - protected PsychicRitualToil_GatherForInvocation() - { - } - - protected PsychicRitualToil_GatherForInvocation(PsychicRitualDef_InvocationCircle def, PsychicRitualToil_Goto fallbackToil, PsychicRitualGraph invokerToil) - : base(new Dictionary { { def.InvokerRole, invokerToil } }, fallbackToil) - { - this.fallbackToil = fallbackToil; - this.invokerToil = invokerToil; - invokerFinalToil = (PsychicRitualToil_Goto)invokerToil.GetToil(invokerToil.ToilCount - 1); - } - - public PsychicRitualToil_GatherForInvocation(PsychicRitual psychicRitual, PsychicRitualDef_InvocationCircle def, IReadOnlyDictionary> rolePositions) - : this(def, FallbackToil(psychicRitual, def, rolePositions), InvokerToil(def, rolePositions)) - { - } - - public override void ExposeData() - { - base.ExposeData(); - Scribe_References.Look(ref fallbackToil, "fallbackToil"); - Scribe_References.Look(ref invokerToil, "invokerToil"); - Scribe_References.Look(ref invokerFinalToil, "invokerFinalToil"); - } - - public override string GetReport(PsychicRitual psychicRitual, PsychicRitualGraph parent) - { - blockingPawns.Clear(); - blockingPawns.AddRange(fallbackToil.BlockingPawns); - if (invokerToil.CurrentToil == invokerFinalToil) - { - blockingPawns.AddRange(invokerFinalToil.BlockingPawns); - } - else - { - blockingPawns.AddRange(invokerFinalToil.ControlledPawns(psychicRitual)); - } - string text = "PsychicRitualToil_GatherForInvocation_Report".Translate(); - string text2 = blockingPawns.Select((Pawn pawn) => pawn.LabelShortCap).ToCommaList(); - return text + ": " + text2; - } - - public static PsychicRitualToil_Goto FallbackToil(PsychicRitual psychicRitual, PsychicRitualDef_InvocationCircle def, IReadOnlyDictionary> rolePositions) - { - return new PsychicRitualToil_Goto(rolePositions.Slice(rolePositions.Keys.Except(def.InvokerRole))); - } - - public static PsychicRitualGraph InvokerToil(PsychicRitualDef_InvocationCircle def, IReadOnlyDictionary> rolePositions) - { - return new PsychicRitualGraph(InvokerGatherPhaseToils(def, rolePositions)) - { - willAdvancePastLastToil = false - }; - } - - public static IEnumerable InvokerGatherPhaseToils(PsychicRitualDef_InvocationCircle def, IReadOnlyDictionary> rolePositions) - { - if (def.RequiredOffering != null) - { - yield return new PsychicRitualToil_GatherOfferings(def.InvokerRole, def.RequiredOffering); - } - if (def.TargetRole != null) - { - yield return new PsychicRitualToil_CarryAndGoto(def.InvokerRole, def.TargetRole, rolePositions); - } - yield return new PsychicRitualToil_Goto(rolePositions.Slice(def.InvokerRole)); - } -} -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\PsychicRitualDef_SkipAbduction.txt` -**相似度:** 0.7696 - -```csharp -public class PsychicRitualDef_SkipAbduction : PsychicRitualDef_InvocationCircle -{ - public override List CreateToils(PsychicRitual psychicRitual, PsychicRitualGraph graph) - { - List list = base.CreateToils(psychicRitual, graph); - list.Add(new PsychicRitualToil_SkipAbduction(InvokerRole)); - return list; - } -} -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\PsychicRitualDef_BloodRain.txt` -**相似度:** 0.7621 - -```csharp -public class PsychicRitualDef_BloodRain : PsychicRitualDef_InvocationCircle -{ - private FloatRange durationHoursFromQualityRange; - - public override List CreateToils(PsychicRitual psychicRitual, PsychicRitualGraph graph) - { - List list = base.CreateToils(psychicRitual, graph); - list.Add(new PsychicRitualToil_BloodRain(InvokerRole, durationHoursFromQualityRange)); - return list; - } - - public override TaggedString OutcomeDescription(FloatRange qualityRange, string qualityNumber, PsychicRitualRoleAssignments assignments) - { - return outcomeDescription.Formatted(Mathf.FloorToInt(durationHoursFromQualityRange.LerpThroughRange(qualityRange.min) * 2500f).ToStringTicksToPeriod()); - } -} -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\PsychicRitualDef_SummonFleshbeasts.txt` -**相似度:** 0.7620 - -```csharp -public class PsychicRitualDef_SummonFleshbeasts : PsychicRitualDef_InvocationCircle -{ - public SimpleCurve fleshbeastPointsFromThreatPointsCurve; - - public override List CreateToils(PsychicRitual psychicRitual, PsychicRitualGraph graph) - { - List list = base.CreateToils(psychicRitual, graph); - list.Add(new PsychicRitualToil_SummonFleshbeastsCultist(InvokerRole)); - return list; - } - - public override void CalculateMaxPower(PsychicRitualRoleAssignments assignments, List powerFactorsOut, out float power) - { - power = 0f; - if (assignments.FirstAssignedPawn(InvokerRole)?.GetLord()?.LordJob is LordJob_PsychicRitual lordJob_PsychicRitual) - { - power = Mathf.Max(power, lordJob_PsychicRitual.points); - } - } -} -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\PsychicRitualDef_SummonPitGate.txt` -**相似度:** 0.7581 - -```csharp -public class PsychicRitualDef_SummonPitGate : PsychicRitualDef_InvocationCircle -{ - private FloatRange combatPointMultiplierFromQualityRange; - - public override List CreateToils(PsychicRitual psychicRitual, PsychicRitualGraph graph) - { - List list = base.CreateToils(psychicRitual, graph); - list.Add(new PsychicRitualToil_SummonPitGate(InvokerRole, combatPointMultiplierFromQualityRange)); - return list; - } - - public override IEnumerable BlockingIssues(PsychicRitualRoleAssignments assignments, Map map) - { - foreach (string item in base.BlockingIssues(assignments, map)) - { - yield return item; - } - if (map.listerThings.ThingsOfDef(ThingDefOf.PitGate).Count > 0 || map.listerThings.ThingsOfDef(ThingDefOf.PitGateSpawner).Count > 0) - { - yield return "PitGateAlreadyExists".Translate(); - } - } -} -``` \ No newline at end of file diff --git a/MCP/vector_cache/PsychicRitualToil_GatherForInvocation.txt b/MCP/vector_cache/PsychicRitualToil_GatherForInvocation.txt deleted file mode 100644 index a0c2836b..00000000 --- a/MCP/vector_cache/PsychicRitualToil_GatherForInvocation.txt +++ /dev/null @@ -1,103 +0,0 @@ -根据向量相似度分析,与 'PsychicRitualToil_GatherForInvocation' 最相关的代码定义如下: - ---- -**文件路径 (精确匹配):** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\Verse.AI.Group\PsychicRitualToil_GatherForInvocation.txt` - -```csharp -public class PsychicRitualToil_GatherForInvocation : PsychicRitualToil_Multiplex -{ - protected PsychicRitualToil_Goto fallbackToil; - - protected PsychicRitualGraph invokerToil; - - protected PsychicRitualToil_Goto invokerFinalToil; - - private static List blockingPawns = new List(16); - - protected PsychicRitualToil_GatherForInvocation() - { - } - - protected PsychicRitualToil_GatherForInvocation(PsychicRitualDef_InvocationCircle def, PsychicRitualToil_Goto fallbackToil, PsychicRitualGraph invokerToil) - : base(new Dictionary { { def.InvokerRole, invokerToil } }, fallbackToil) - { - this.fallbackToil = fallbackToil; - this.invokerToil = invokerToil; - invokerFinalToil = (PsychicRitualToil_Goto)invokerToil.GetToil(invokerToil.ToilCount - 1); - } - - public PsychicRitualToil_GatherForInvocation(PsychicRitual psychicRitual, PsychicRitualDef_InvocationCircle def, IReadOnlyDictionary> rolePositions) - : this(def, FallbackToil(psychicRitual, def, rolePositions), InvokerToil(def, rolePositions)) - { - } - - public override void ExposeData() - { - base.ExposeData(); - Scribe_References.Look(ref fallbackToil, "fallbackToil"); - Scribe_References.Look(ref invokerToil, "invokerToil"); - Scribe_References.Look(ref invokerFinalToil, "invokerFinalToil"); - } - - public override string GetReport(PsychicRitual psychicRitual, PsychicRitualGraph parent) - { - blockingPawns.Clear(); - blockingPawns.AddRange(fallbackToil.BlockingPawns); - if (invokerToil.CurrentToil == invokerFinalToil) - { - blockingPawns.AddRange(invokerFinalToil.BlockingPawns); - } - else - { - blockingPawns.AddRange(invokerFinalToil.ControlledPawns(psychicRitual)); - } - string text = "PsychicRitualToil_GatherForInvocation_Report".Translate(); - string text2 = blockingPawns.Select((Pawn pawn) => pawn.LabelShortCap).ToCommaList(); - return text + ": " + text2; - } - - public static PsychicRitualToil_Goto FallbackToil(PsychicRitual psychicRitual, PsychicRitualDef_InvocationCircle def, IReadOnlyDictionary> rolePositions) - { - return new PsychicRitualToil_Goto(rolePositions.Slice(rolePositions.Keys.Except(def.InvokerRole))); - } - - public static PsychicRitualGraph InvokerToil(PsychicRitualDef_InvocationCircle def, IReadOnlyDictionary> rolePositions) - { - return new PsychicRitualGraph(InvokerGatherPhaseToils(def, rolePositions)) - { - willAdvancePastLastToil = false - }; - } - - public static IEnumerable InvokerGatherPhaseToils(PsychicRitualDef_InvocationCircle def, IReadOnlyDictionary> rolePositions) - { - if (def.RequiredOffering != null) - { - yield return new PsychicRitualToil_GatherOfferings(def.InvokerRole, def.RequiredOffering); - } - if (def.TargetRole != null) - { - yield return new PsychicRitualToil_CarryAndGoto(def.InvokerRole, def.TargetRole, rolePositions); - } - yield return new PsychicRitualToil_Goto(rolePositions.Slice(def.InvokerRole)); - } -} -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\PsychicRitualDef_InvocationCircle.txt` -**相似度:** 0.7275 - -```csharp - private class RitualQualityOffsetCount - { - public float offset; - - public int count; - - public RitualQualityOffsetCount(int count, float offset) - { - this.count = count; - this.offset = offset; - } - } -``` \ No newline at end of file diff --git a/MCP/vector_cache/PsychicRitualToil_GatherOfferings.txt b/MCP/vector_cache/PsychicRitualToil_GatherOfferings.txt deleted file mode 100644 index f834d65e..00000000 --- a/MCP/vector_cache/PsychicRitualToil_GatherOfferings.txt +++ /dev/null @@ -1,270 +0,0 @@ -根据向量相似度分析,与 'PsychicRitualToil_GatherOfferings' 最相关的代码定义如下: - ---- -**文件路径 (精确匹配):** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\Verse.AI.Group\PsychicRitualToil_GatherOfferings.txt` - -```csharp -public class PsychicRitualToil_GatherOfferings : PsychicRitualToil -{ - protected PsychicRitualRoleDef gathererRole; - - protected bool offeringsGathered; - - protected IngredientCount requiredOffering; - - protected PsychicRitualToil_GatherOfferings() - { - } - - public PsychicRitualToil_GatherOfferings(PsychicRitualRoleDef offeringGatherer, IngredientCount requiredOffering) - { - gathererRole = offeringGatherer; - this.requiredOffering = requiredOffering; - } - - public override void UpdateAllDuties(PsychicRitual psychicRitual, PsychicRitualGraph parent) - { - DutyDef def; - if (offeringsGathered || PawnsHaveOfferings(psychicRitual)) - { - offeringsGathered = true; - def = DutyDefOf.Idle; - } - else - { - def = DutyDefOf.GatherOfferingsForPsychicRitual; - } - foreach (Pawn item in psychicRitual.assignments.AssignedPawns(gathererRole)) - { - SetPawnDuty(item, psychicRitual, parent, def); - } - } - - public override bool Tick(PsychicRitual psychicRitual, PsychicRitualGraph parent) - { - return offeringsGathered; - } - - public override void ExposeData() - { - base.ExposeData(); - Scribe_Defs.Look(ref gathererRole, "gathererRole"); - Scribe_Values.Look(ref offeringsGathered, "offeringsGathered", defaultValue: false); - Scribe_Deep.Look(ref requiredOffering, "requiredOffering"); - } - - public static float PawnsOfferingCount(IEnumerable pawns, IngredientCount offering) - { - float num = 0f; - foreach (Pawn pawn in pawns) - { - foreach (Thing item in (IEnumerable)pawn.inventory.GetDirectlyHeldThings()) - { - if (offering.filter.Allows(item)) - { - num += (float)item.stackCount; - if (num >= offering.GetBaseCount()) - { - return offering.GetBaseCount(); - } - } - } - } - return num; - } - - private bool PawnsHaveOfferings(PsychicRitual psychicRitual) - { - float baseCount = requiredOffering.GetBaseCount(); - return PawnsOfferingCount(psychicRitual.assignments.AssignedPawns(gathererRole), requiredOffering) >= baseCount; - } - - public override void Notify_PawnJobDone(PsychicRitual psychicRitual, PsychicRitualGraph parent, Pawn pawn, Job job, JobCondition condition) - { - base.Notify_PawnJobDone(psychicRitual, parent, pawn, job, condition); - if (psychicRitual.assignments.RoleForPawn(pawn) == gathererRole && (offeringsGathered || PawnsHaveOfferings(psychicRitual))) - { - offeringsGathered = true; - SetPawnDuty(pawn, psychicRitual, parent, DutyDefOf.Idle); - } - } - - public override ThinkResult Notify_DutyResult(PsychicRitual psychicRitual, PsychicRitualGraph parent, ThinkResult result, Pawn pawn, JobIssueParams issueParams) - { - result = base.Notify_DutyResult(psychicRitual, parent, result, pawn, issueParams); - if (result.Job != null) - { - return result; - } - if (psychicRitual.assignments.RoleForPawn(pawn) != gathererRole) - { - return result; - } - if (offeringsGathered || PawnsHaveOfferings(psychicRitual)) - { - offeringsGathered = true; - SetPawnDuty(pawn, psychicRitual, parent, DutyDefOf.Idle); - return new ThinkResult(JobMaker.MakeJob(JobDefOf.Wait, 1), null); - } - TaggedString reason = "PsychicRitualToil_GatherOfferings_OfferingUnavailable".Translate(pawn.Named("PAWN"), requiredOffering.filter.Summary); - psychicRitual.LeaveOrCancelPsychicRitual(gathererRole, pawn, reason); - return result; - } - - public override string GetJobReport(PsychicRitual psychicRitual, PsychicRitualGraph parent, Pawn pawn) - { - if (psychicRitual.assignments.RoleForPawn(pawn) == gathererRole) - { - return "PsychicRitualToil_GatherOfferings_JobReport".Translate(); - } - return base.GetJobReport(psychicRitual, parent, pawn); - } -} -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\JobGiver_GatherOfferingsForPsychicRitual.txt` -**相似度:** 0.8171 - -```csharp -public class JobGiver_GatherOfferingsForPsychicRitual : ThinkNode_JobGiver -{ - protected override Job TryGiveJob(Pawn pawn) - { - Lord lord = pawn.GetLord(); - if (lord == null) - { - return null; - } - if (!(lord.CurLordToil is LordToil_PsychicRitual lordToil_PsychicRitual)) - { - return null; - } - PsychicRitualDef def = lordToil_PsychicRitual.RitualData.psychicRitual.def; - PsychicRitualDef_InvocationCircle ritualDef = def as PsychicRitualDef_InvocationCircle; - if (ritualDef == null) - { - return null; - } - if (ritualDef.RequiredOffering == null) - { - return null; - } - PsychicRitual psychicRitual = lordToil_PsychicRitual.RitualData.psychicRitual; - PsychicRitualRoleDef psychicRitualRoleDef = psychicRitual.assignments.RoleForPawn(pawn); - if (psychicRitualRoleDef == null) - { - return null; - } - float num = PsychicRitualToil_GatherOfferings.PawnsOfferingCount(psychicRitual.assignments.AssignedPawns(psychicRitualRoleDef), ritualDef.RequiredOffering); - int needed = Mathf.CeilToInt(ritualDef.RequiredOffering.GetBaseCount() - num); - if (needed == 0) - { - return null; - } - Thing thing2 = GenClosest.ClosestThingReachable(pawn.PositionHeld, pawn.MapHeld, ThingRequest.ForGroup(ThingRequestGroup.HaulableAlways), PathEndMode.Touch, TraverseParms.For(pawn), 9999f, delegate(Thing thing) - { - if (!ritualDef.RequiredOffering.filter.Allows(thing)) - { - return false; - } - if (thing.IsForbidden(pawn)) - { - return false; - } - int stackCount = Mathf.Min(needed, thing.stackCount); - return pawn.CanReserve(thing, 10, stackCount) ? true : false; - }); - if (thing2 == null) - { - return null; - } - Job job = JobMaker.MakeJob(JobDefOf.TakeCountToInventory, thing2); - job.count = Mathf.Min(needed, thing2.stackCount); - return job; - } -} -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\Verse.AI.Group\PsychicRitualToil_GatherForInvocation.txt` -**相似度:** 0.7774 - -```csharp -public class PsychicRitualToil_GatherForInvocation : PsychicRitualToil_Multiplex -{ - protected PsychicRitualToil_Goto fallbackToil; - - protected PsychicRitualGraph invokerToil; - - protected PsychicRitualToil_Goto invokerFinalToil; - - private static List blockingPawns = new List(16); - - protected PsychicRitualToil_GatherForInvocation() - { - } - - protected PsychicRitualToil_GatherForInvocation(PsychicRitualDef_InvocationCircle def, PsychicRitualToil_Goto fallbackToil, PsychicRitualGraph invokerToil) - : base(new Dictionary { { def.InvokerRole, invokerToil } }, fallbackToil) - { - this.fallbackToil = fallbackToil; - this.invokerToil = invokerToil; - invokerFinalToil = (PsychicRitualToil_Goto)invokerToil.GetToil(invokerToil.ToilCount - 1); - } - - public PsychicRitualToil_GatherForInvocation(PsychicRitual psychicRitual, PsychicRitualDef_InvocationCircle def, IReadOnlyDictionary> rolePositions) - : this(def, FallbackToil(psychicRitual, def, rolePositions), InvokerToil(def, rolePositions)) - { - } - - public override void ExposeData() - { - base.ExposeData(); - Scribe_References.Look(ref fallbackToil, "fallbackToil"); - Scribe_References.Look(ref invokerToil, "invokerToil"); - Scribe_References.Look(ref invokerFinalToil, "invokerFinalToil"); - } - - public override string GetReport(PsychicRitual psychicRitual, PsychicRitualGraph parent) - { - blockingPawns.Clear(); - blockingPawns.AddRange(fallbackToil.BlockingPawns); - if (invokerToil.CurrentToil == invokerFinalToil) - { - blockingPawns.AddRange(invokerFinalToil.BlockingPawns); - } - else - { - blockingPawns.AddRange(invokerFinalToil.ControlledPawns(psychicRitual)); - } - string text = "PsychicRitualToil_GatherForInvocation_Report".Translate(); - string text2 = blockingPawns.Select((Pawn pawn) => pawn.LabelShortCap).ToCommaList(); - return text + ": " + text2; - } - - public static PsychicRitualToil_Goto FallbackToil(PsychicRitual psychicRitual, PsychicRitualDef_InvocationCircle def, IReadOnlyDictionary> rolePositions) - { - return new PsychicRitualToil_Goto(rolePositions.Slice(rolePositions.Keys.Except(def.InvokerRole))); - } - - public static PsychicRitualGraph InvokerToil(PsychicRitualDef_InvocationCircle def, IReadOnlyDictionary> rolePositions) - { - return new PsychicRitualGraph(InvokerGatherPhaseToils(def, rolePositions)) - { - willAdvancePastLastToil = false - }; - } - - public static IEnumerable InvokerGatherPhaseToils(PsychicRitualDef_InvocationCircle def, IReadOnlyDictionary> rolePositions) - { - if (def.RequiredOffering != null) - { - yield return new PsychicRitualToil_GatherOfferings(def.InvokerRole, def.RequiredOffering); - } - if (def.TargetRole != null) - { - yield return new PsychicRitualToil_CarryAndGoto(def.InvokerRole, def.TargetRole, rolePositions); - } - yield return new PsychicRitualToil_Goto(rolePositions.Slice(def.InvokerRole)); - } -} -``` \ No newline at end of file diff --git a/MCP/vector_cache/Source-StartCarryThing-Toil-Toils_Haul.txt b/MCP/vector_cache/Source-StartCarryThing-Toil-Toils_Haul.txt deleted file mode 100644 index cca8869f..00000000 --- a/MCP/vector_cache/Source-StartCarryThing-Toil-Toils_Haul.txt +++ /dev/null @@ -1,1333 +0,0 @@ -根据向量相似度分析,与 'Source, Toils_Haul, StartCarryThing, Toil' 最相关的代码定义如下: - ---- -**文件路径 (精确匹配):** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\Verse.AI\Toils_Haul.txt` - -```csharp -public class Toils_Haul -{ - public static bool ErrorCheckForCarry(Pawn pawn, Thing haulThing, bool canTakeFromInventory = false) - { - if (!haulThing.SpawnedOrAnyParentSpawned || (!canTakeFromInventory && !haulThing.Spawned)) - { - Log.Message(pawn?.ToString() + " tried to start carry " + haulThing?.ToString() + " which isn't spawned."); - pawn.jobs.EndCurrentJob(JobCondition.Incompletable); - return true; - } - if (haulThing.stackCount == 0) - { - Log.Message(pawn?.ToString() + " tried to start carry " + haulThing?.ToString() + " which had stackcount 0."); - pawn.jobs.EndCurrentJob(JobCondition.Incompletable); - return true; - } - if (pawn.jobs.curJob.count <= 0) - { - Log.Error("Invalid count: " + pawn.jobs.curJob.count + ", setting to 1. Job was " + pawn.jobs.curJob); - pawn.jobs.curJob.count = 1; - } - return false; - } - - public static Toil StartCarryThing(TargetIndex haulableInd, bool putRemainderInQueue = false, bool subtractNumTakenFromJobCount = false, bool failIfStackCountLessThanJobCount = false, bool reserve = true, bool canTakeFromInventory = false) - { - Toil toil = ToilMaker.MakeToil("StartCarryThing"); - toil.initAction = delegate - { - Pawn actor = toil.actor; - Job curJob = actor.jobs.curJob; - Thing thing = curJob.GetTarget(haulableInd).Thing; - if (!ErrorCheckForCarry(actor, thing, canTakeFromInventory)) - { - if (curJob.count == 0) - { - throw new Exception($"StartCarryThing job had count = {curJob.count}. Job: {curJob}"); - } - int num = actor.carryTracker.AvailableStackSpace(thing.def); - if (num <= 0) - { - int num2 = actor.carryTracker.MaxStackSpaceEver(thing.def); - int num3 = 0; - if (actor.carryTracker.CarriedThing != null) - { - num3 = actor.carryTracker.CarriedThing.stackCount; - } - throw new Exception($"StartCarryThing got availableStackSpace {num} (haulTarg {thing}, Job: {curJob}, maximum: {num2}, carrying: {num3})"); - } - if (failIfStackCountLessThanJobCount && thing.stackCount < curJob.count) - { - actor.jobs.curDriver.EndJobWith(JobCondition.Incompletable); - } - else - { - int num4 = Mathf.Min(curJob.count, num, thing.stackCount); - if (num4 <= 0) - { - int num5 = actor.carryTracker.MaxStackSpaceEver(thing.def); - int num6 = 0; - if (actor.carryTracker.CarriedThing != null) - { - num6 = actor.carryTracker.CarriedThing.stackCount; - } - throw new Exception($"StartCarryThing zero or negative desiredNumToTake ({num4}), curJob.count: {curJob.count}, availableStackSpace: {num} (maximum: {num5}, carrying: {num6}), haulTarg.stackCount: {thing.stackCount}"); - } - int stackCount = thing.stackCount; - int num7 = actor.carryTracker.TryStartCarry(thing, num4, reserve); - if (num7 == 0) - { - actor.jobs.EndCurrentJob(JobCondition.Incompletable); - } - if (num7 < stackCount) - { - int num8 = curJob.count - num7; - if (putRemainderInQueue && num8 > 0) - { - curJob.GetTargetQueue(haulableInd).Insert(0, thing); - Job job = curJob; - if (job.countQueue == null) - { - job.countQueue = new List(); - } - curJob.countQueue.Insert(0, num8); - } - else if (actor.Map.reservationManager.ReservedBy(thing, actor, curJob)) - { - actor.Map.reservationManager.Release(thing, actor, curJob); - } - } - if (subtractNumTakenFromJobCount) - { - curJob.count -= num7; - } - curJob.SetTarget(haulableInd, actor.carryTracker.CarriedThing); - actor.records.Increment(RecordDefOf.ThingsHauled); - } - } - }; - return toil; - } - - public static Toil StoreThingJob(TargetIndex thingIndex) - { - Toil toil = ToilMaker.MakeToil("StoreThingJob"); - toil.initAction = delegate - { - Pawn actor = toil.actor; - Job curJob = actor.CurJob; - Thing thing = curJob.GetTarget(thingIndex).Thing; - Job job = HaulAIUtility.HaulToStorageJob(actor, thing, curJob.playerForced); - if (job != null) - { - actor.jobs.TryTakeOrderedJob(job, JobTag.Misc); - } - }; - return toil; - } - - public static Toil DropCarriedThing() - { - Toil toil = ToilMaker.MakeToil("DropCarriedThing"); - toil.initAction = delegate - { - Pawn actor = toil.actor; - Thing resultingThing; - if (actor.carryTracker.CarriedThing == null) - { - Log.Error(actor?.ToString() + " tried to drop carried thing but is not carrying anything."); - } - else if (!actor.carryTracker.TryDropCarriedThing(actor.Position, ThingPlaceMode.Direct, out resultingThing)) - { - actor.jobs.EndCurrentJob(JobCondition.Incompletable); - } - }; - return toil; - } - - public static Toil JumpIfAlsoCollectingNextTargetInQueue(Toil gotoGetTargetToil, TargetIndex ind) - { - Toil toil = ToilMaker.MakeToil("JumpIfAlsoCollectingNextTargetInQueue"); - toil.initAction = delegate - { - Pawn actor = toil.actor; - Job curJob = actor.jobs.curJob; - List targetQueue = curJob.GetTargetQueue(ind); - if (!targetQueue.NullOrEmpty() && curJob.count > 0) - { - if (actor.carryTracker.CarriedThing == null) - { - Log.Error("JumpToAlsoCollectTargetInQueue run on " + actor?.ToString() + " who is not carrying something."); - } - else if (actor.carryTracker.AvailableStackSpace(actor.carryTracker.CarriedThing.def) > 0) - { - for (int i = 0; i < targetQueue.Count; i++) - { - if (!GenAI.CanUseItemForWork(actor, targetQueue[i].Thing)) - { - actor.jobs.EndCurrentJob(JobCondition.Incompletable); - break; - } - if (targetQueue[i].Thing.def == actor.carryTracker.CarriedThing.def) - { - curJob.SetTarget(ind, targetQueue[i].Thing); - targetQueue.RemoveAt(i); - actor.jobs.curDriver.JumpToToil(gotoGetTargetToil); - break; - } - } - } - } - }; - return toil; - } - - public static Toil CheckForGetOpportunityDuplicate(Toil getHaulTargetToil, TargetIndex haulableInd, TargetIndex storeCellInd, bool takeFromValidStorage = false, Predicate extraValidator = null) - { - Toil toil = ToilMaker.MakeToil("CheckForGetOpportunityDuplicate"); - toil.initAction = delegate - { - Pawn actor = toil.actor; - Job curJob = actor.jobs.curJob; - if (actor.carryTracker.CarriedThing.def.stackLimit != 1 && !actor.carryTracker.Full && curJob.count > 0) - { - Thing thing = GenClosest.ClosestThingReachable(actor.Position, actor.Map, ThingRequest.ForGroup(ThingRequestGroup.HaulableAlways), PathEndMode.ClosestTouch, TraverseParms.For(actor), 8f, DupeValidator); - if (thing != null) - { - curJob.SetTarget(haulableInd, thing); - actor.jobs.curDriver.JumpToToil(getHaulTargetToil); - } - } - bool DupeValidator(Thing t) - { - if (!t.Spawned) - { - return false; - } - if (t.def != actor.carryTracker.CarriedThing.def) - { - return false; - } - if (!t.CanStackWith(actor.carryTracker.CarriedThing)) - { - return false; - } - if (t.IsForbidden(actor)) - { - return false; - } - if (!t.IsSociallyProper(actor, forPrisoner: false, animalsCare: true)) - { - return false; - } - if (takeFromValidStorage && storeCellInd != 0 && curJob.GetTarget(storeCellInd).Cell.TryGetSlotGroup(actor.Map, out var group) && t.TryGetValidStoragePriority(out var priority) && (int)priority >= (int)group.Settings.Priority) - { - return false; - } - if (storeCellInd != 0 && !curJob.GetTarget(storeCellInd).Cell.IsValidStorageFor(actor.Map, t)) - { - return false; - } - if (!actor.CanReserve(t)) - { - return false; - } - if (extraValidator != null && !extraValidator(t)) - { - return false; - } - return true; - } - }; - return toil; - } - - public static Toil CarryHauledThingToCell(TargetIndex squareIndex, PathEndMode pathEndMode = PathEndMode.ClosestTouch) - { - Toil toil = ToilMaker.MakeToil("CarryHauledThingToCell"); - toil.initAction = delegate - { - IntVec3 cell3 = toil.actor.jobs.curJob.GetTarget(squareIndex).Cell; - toil.actor.pather.StartPath(cell3, pathEndMode); - }; - toil.defaultCompleteMode = ToilCompleteMode.PatherArrival; - toil.AddEndCondition(delegate - { - Pawn actor2 = toil.actor; - IntVec3 cell2 = actor2.jobs.curJob.GetTarget(squareIndex).Cell; - CompPushable compPushable2 = actor2.carryTracker.CarriedThing.TryGetComp(); - if (compPushable2 != null) - { - Vector3 v = actor2.Position.ToVector3() + compPushable2.drawPos; - if (new IntVec3(v) == cell2) - { - return JobCondition.Succeeded; - } - } - return JobCondition.Ongoing; - }); - toil.AddFailCondition(delegate - { - Pawn actor = toil.actor; - IntVec3 cell = actor.jobs.curJob.GetTarget(squareIndex).Cell; - if (actor.carryTracker.CarriedThing == null) - { - return true; - } - if (actor.jobs.curJob.haulMode == HaulMode.ToCellStorage && !cell.IsValidStorageFor(actor.Map, actor.carryTracker.CarriedThing)) - { - return true; - } - CompPushable compPushable = actor.carryTracker.CarriedThing.TryGetComp(); - return (compPushable != null && !compPushable.canBePushed) ? true : false; - }); - return toil; - } - - public static Toil PlaceCarriedThingInCellFacing(TargetIndex facingTargetInd) - { - Toil toil = ToilMaker.MakeToil("PlaceCarriedThingInCellFacing"); - toil.initAction = delegate - { - Pawn actor = toil.actor; - if (actor.carryTracker.CarriedThing == null) - { - Log.Error(actor?.ToString() + " tried to place hauled thing in facing cell but is not hauling anything."); - } - else - { - LocalTargetInfo target = actor.CurJob.GetTarget(facingTargetInd); - IntVec3 intVec = ((!target.HasThing) ? target.Cell : target.Thing.OccupiedRect().ClosestCellTo(actor.Position)); - IntVec3 dropLoc = actor.Position + Pawn_RotationTracker.RotFromAngleBiased((actor.Position - intVec).AngleFlat).FacingCell; - if (!actor.carryTracker.TryDropCarriedThing(dropLoc, ThingPlaceMode.Direct, out var _)) - { - actor.jobs.EndCurrentJob(JobCondition.Incompletable); - } - } - }; - return toil; - } - - public static Toil PlaceHauledThingInCell(TargetIndex cellInd, Toil nextToilOnPlaceFailOrIncomplete, bool storageMode, bool tryStoreInSameStorageIfSpotCantHoldWholeStack = false) - { - Toil toil = ToilMaker.MakeToil("PlaceHauledThingInCell"); - toil.initAction = delegate - { - Pawn actor = toil.actor; - Job curJob = actor.jobs.curJob; - IntVec3 cell = curJob.GetTarget(cellInd).Cell; - if (actor.carryTracker.CarriedThing == null) - { - Log.Error(actor?.ToString() + " tried to place hauled thing in cell but is not hauling anything."); - } - else - { - SlotGroup slotGroup = actor.Map.haulDestinationManager.SlotGroupAt(cell); - if (slotGroup != null && slotGroup.Settings.AllowedToAccept(actor.carryTracker.CarriedThing)) - { - actor.Map.designationManager.TryRemoveDesignationOn(actor.carryTracker.CarriedThing, DesignationDefOf.Haul); - } - Action placedAction = null; - if (curJob.def == JobDefOf.DoBill || curJob.def == JobDefOf.RecolorApparel || curJob.def == JobDefOf.RefuelAtomic || curJob.def == JobDefOf.RearmTurretAtomic) - { - placedAction = delegate(Thing th, int added) - { - HaulAIUtility.UpdateJobWithPlacedThings(curJob, th, added); - }; - } - if (!actor.carryTracker.TryDropCarriedThing(cell, ThingPlaceMode.Direct, out var _, placedAction)) - { - if (storageMode) - { - IntVec3 storeCell; - if (nextToilOnPlaceFailOrIncomplete != null && ((tryStoreInSameStorageIfSpotCantHoldWholeStack && StoreUtility.TryFindBestBetterStoreCellForIn(actor.carryTracker.CarriedThing, actor, actor.Map, StoragePriority.Unstored, actor.Faction, curJob.bill.GetSlotGroup(), out var foundCell)) || StoreUtility.TryFindBestBetterStoreCellFor(actor.carryTracker.CarriedThing, actor, actor.Map, StoragePriority.Unstored, actor.Faction, out foundCell))) - { - if (actor.CanReserve(foundCell)) - { - actor.Reserve(foundCell, actor.CurJob); - } - actor.CurJob.SetTarget(cellInd, foundCell); - actor.jobs.curDriver.JumpToToil(nextToilOnPlaceFailOrIncomplete); - } - else if (HaulAIUtility.CanHaulAside(actor, actor.carryTracker.CarriedThing, out storeCell)) - { - curJob.SetTarget(cellInd, storeCell); - curJob.count = int.MaxValue; - curJob.haulOpportunisticDuplicates = false; - curJob.haulMode = HaulMode.ToCellNonStorage; - if (nextToilOnPlaceFailOrIncomplete != null) - { - actor.jobs.curDriver.JumpToToil(nextToilOnPlaceFailOrIncomplete); - } - } - else - { - Log.Warning($"Incomplete haul for {actor}: Could not find anywhere to put {actor.carryTracker.CarriedThing} near {actor.Position}. Destroying. This should be very uncommon!"); - actor.carryTracker.CarriedThing.Destroy(); - } - } - else if (nextToilOnPlaceFailOrIncomplete != null) - { - actor.jobs.curDriver.JumpToToil(nextToilOnPlaceFailOrIncomplete); - } - } - } - }; - return toil; - } - - public static Toil CarryHauledThingToContainer() - { - Toil gotoDest = ToilMaker.MakeToil("CarryHauledThingToContainer"); - gotoDest.initAction = delegate - { - gotoDest.actor.pather.StartPath(gotoDest.actor.jobs.curJob.targetB.Thing, PathEndMode.Touch); - }; - gotoDest.AddFailCondition(delegate - { - Thing thing = gotoDest.actor.jobs.curJob.targetB.Thing; - if (thing.Destroyed || (!gotoDest.actor.jobs.curJob.ignoreForbidden && thing.IsForbidden(gotoDest.actor))) - { - return true; - } - ThingOwner thingOwner = thing.TryGetInnerInteractableThingOwner(); - return (thingOwner != null && !thingOwner.CanAcceptAnyOf(gotoDest.actor.carryTracker.CarriedThing)) ? true : false; - }); - gotoDest.defaultCompleteMode = ToilCompleteMode.PatherArrival; - return gotoDest; - } - - public static Toil DepositHauledThingInContainer(TargetIndex containerInd, TargetIndex reserveForContainerInd, Action onDeposited = null) - { - Toil toil = ToilMaker.MakeToil("DepositHauledThingInContainer"); - toil.initAction = delegate - { - Pawn actor = toil.actor; - Job curJob = actor.jobs.curJob; - if (actor.carryTracker.CarriedThing == null) - { - Log.Error(actor?.ToString() + " tried to place hauled thing in container but is not hauling anything."); - } - else - { - Thing thing = curJob.GetTarget(containerInd).Thing; - ThingOwner thingOwner = thing.TryGetInnerInteractableThingOwner(); - if (thingOwner != null) - { - int num = actor.carryTracker.CarriedThing.stackCount; - if (thing is IHaulEnroute haulEnroute) - { - ThingDef def = actor.carryTracker.CarriedThing.def; - num = Mathf.Min(haulEnroute.GetSpaceRemainingWithEnroute(def, actor), num); - if (reserveForContainerInd != 0) - { - Thing thing2 = curJob.GetTarget(reserveForContainerInd).Thing; - if (!thing2.DestroyedOrNull() && thing2 != haulEnroute && thing2 is IHaulEnroute enroute) - { - int spaceRemainingWithEnroute = enroute.GetSpaceRemainingWithEnroute(def, actor); - num = Mathf.Min(num, actor.carryTracker.CarriedThing.stackCount - spaceRemainingWithEnroute); - } - } - } - Thing carriedThing = actor.carryTracker.CarriedThing; - int num2 = actor.carryTracker.innerContainer.TryTransferToContainer(carriedThing, thingOwner, num); - if (num2 != 0) - { - if (thing is IHaulEnroute container) - { - thing.Map.enrouteManager.ReleaseFor(container, actor); - } - if (thing is INotifyHauledTo notifyHauledTo) - { - notifyHauledTo.Notify_HauledTo(actor, carriedThing, num2); - } - if (thing is ThingWithComps thingWithComps) - { - foreach (ThingComp allComp in thingWithComps.AllComps) - { - if (allComp is INotifyHauledTo notifyHauledTo2) - { - notifyHauledTo2.Notify_HauledTo(actor, carriedThing, num2); - } - } - } - if (curJob.def == JobDefOf.DoBill) - { - HaulAIUtility.UpdateJobWithPlacedThings(curJob, carriedThing, num2); - } - onDeposited?.Invoke(); - } - } - else if (curJob.GetTarget(containerInd).Thing.def.Minifiable) - { - actor.carryTracker.innerContainer.ClearAndDestroyContents(); - } - else - { - Log.Error("Could not deposit hauled thing in container: " + curJob.GetTarget(containerInd).Thing); - } - } - }; - return toil; - } - - public static Toil JumpToCarryToNextContainerIfPossible(Toil carryToContainerToil, TargetIndex primaryTargetInd) - { - Toil toil = ToilMaker.MakeToil("JumpToCarryToNextContainerIfPossible"); - toil.debugName = "Jump carry if possible"; - toil.initAction = delegate - { - Pawn actor = toil.actor; - Job curJob = actor.jobs.curJob; - if (actor.carryTracker.CarriedThing != null && curJob.targetQueueB != null && curJob.targetQueueB.Count > 0) - { - if (TryGetNextDestinationFromQueue(primaryTargetInd, TargetIndex.B, actor.carryTracker.CarriedThing.def, curJob, actor, out var nextTarget)) - { - curJob.targetQueueB.RemoveAll((LocalTargetInfo target) => target.Thing == nextTarget); - curJob.targetB = nextTarget; - curJob.targetC = nextTarget; - actor.jobs.curDriver.JumpToToil(carryToContainerToil); - } - } - }; - return toil; - } - - public static bool TryGetNextDestinationFromQueue(TargetIndex primaryIndex, TargetIndex destIndex, ThingDef stuff, Job job, Pawn actor, out Thing target) - { - Thing primaryTarget = job.GetTarget(primaryIndex).Thing; - target = null; - if (actor.carryTracker?.CarriedThing == null) - { - return false; - } - bool hasSpareItems = actor.carryTracker.CarriedThing.stackCount > 0; - if (primaryTarget != null && primaryTarget.Spawned && primaryTarget is IHaulEnroute enroute) - { - int spaceRemainingWithEnroute = enroute.GetSpaceRemainingWithEnroute(stuff, actor); - hasSpareItems = actor.carryTracker.CarriedThing.stackCount > spaceRemainingWithEnroute; - } - target = GenClosest.ClosestThing_Global_Reachable(actor.Position, actor.Map, from x in job.GetTargetQueue(destIndex) - select x.Thing, PathEndMode.Touch, TraverseParms.For(actor), 99999f, Validator); - return target != null; - bool Validator(Thing th) - { - if (!(th is IHaulEnroute enroute2)) - { - return false; - } - if (enroute2.GetSpaceRemainingWithEnroute(stuff, actor) <= 0) - { - return false; - } - if (th != primaryTarget && !hasSpareItems) - { - return false; - } - return true; - } - } - - public static Toil TakeToInventory(TargetIndex ind, int count) - { - return TakeToInventory(ind, count, null, null); - } - - private static Toil TakeToInventory(TargetIndex ind, int? count, Func countGetter, Func countGetterPassingThing) - { - Toil takeThing = ToilMaker.MakeToil("TakeToInventory"); - takeThing.initAction = delegate - { - Pawn actor = takeThing.actor; - Thing thing = actor.CurJob.GetTarget(ind).Thing; - if (!ErrorCheckForCarry(actor, thing)) - { - int num = Mathf.Min(count ?? countGetterPassingThing?.Invoke(thing) ?? countGetter(), thing.stackCount); - if (actor.CurJob.checkEncumbrance) - { - num = Math.Min(num, MassUtility.CountToPickUpUntilOverEncumbered(actor, thing)); - } - if (num <= 0) - { - actor.jobs.curDriver.ReadyForNextToil(); - } - else - { - actor.inventory.GetDirectlyHeldThings().TryAdd(thing.SplitOff(num)); - if (thing.def.ingestible != null && (int)thing.def.ingestible.preferability <= 5) - { - actor.mindState.lastInventoryRawFoodUseTick = Find.TickManager.TicksGame; - } - thing.def.soundPickup.PlayOneShot(new TargetInfo(actor.Position, actor.Map)); - } - } - }; - return takeThing; - } - - public static Toil TakeToInventory(TargetIndex ind, Func countGetter) - { - return TakeToInventory(ind, null, countGetter, null); - } - - public static Toil TakeToInventory(TargetIndex ind, Func countGetter) - { - return TakeToInventory(ind, null, null, countGetter); - } - - public static Toil TakeFromOtherInventory(Thing item, ThingOwner taker, ThingOwner holder, int count = -1, TargetIndex indexToSet = TargetIndex.None) - { - Toil toil = ToilMaker.MakeToil("TakeFromOtherInventory"); - toil.initAction = delegate - { - if (!holder.Contains(item)) - { - toil.actor.jobs.EndCurrentJob(JobCondition.Incompletable); - } - else - { - count = ((count < 0) ? toil.actor.jobs.curJob.count : count); - holder.TryTransferToContainer(item, taker, Mathf.Min(item.stackCount, count), out var resultingTransferredItem); - if (resultingTransferredItem == null) - { - Log.Warning($"Taker {toil.actor.Label} unable to take count {count} of thing {item.Label} from holder's inventory"); - toil.actor.jobs.EndCurrentJob(JobCondition.Incompletable); - } - else if (indexToSet != 0) - { - toil.actor.jobs.curJob.SetTarget(indexToSet, resultingTransferredItem); - } - } - }; - return toil; - } - - public static Toil CheckItemCarriedByOtherPawn(Thing item, TargetIndex targetPawnIfCarried = TargetIndex.None, Toil jumpIfCarriedByOther = null) - { - Toil toil = ToilMaker.MakeToil("CheckItemCarriedByOtherPawn"); - toil.initAction = delegate - { - Pawn pawn = (item?.ParentHolder as Pawn_InventoryTracker)?.pawn; - if (pawn != null && pawn != toil.actor) - { - if (targetPawnIfCarried != 0) - { - toil.actor.jobs.curJob.SetTarget(targetPawnIfCarried, pawn); - } - if (jumpIfCarriedByOther != null) - { - toil.actor.jobs.curDriver.JumpToToil(jumpIfCarriedByOther); - } - } - }; - toil.defaultCompleteMode = ToilCompleteMode.Instant; - toil.atomicWithPrevious = true; - return toil; - } -} -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\Verse.AI\JobDriver_HaulToContainer.txt` -**相似度:** 0.6036 - -```csharp -public class JobDriver_HaulToContainer : JobDriver, IBuildableDriver -{ - private Effecter graveDigEffect; - - protected const TargetIndex CarryThingIndex = TargetIndex.A; - - public const TargetIndex DestIndex = TargetIndex.B; - - protected const TargetIndex PrimaryDestIndex = TargetIndex.C; - - protected const int DiggingEffectInterval = 80; - - public Thing ThingToCarry => (Thing)job.GetTarget(TargetIndex.A); - - public Thing Container => (Thing)job.GetTarget(TargetIndex.B); - - public ThingDef ThingDef => ThingToCarry.def; - - protected virtual int Duration - { - get - { - if (Container == null || !(Container is Building building)) - { - return 0; - } - return building.HaulToContainerDuration(ThingToCarry); - } - } - - protected virtual EffecterDef WorkEffecter => null; - - protected virtual SoundDef WorkSustainer => null; - - public bool TryGetBuildableRect(out CellRect rect) - { - if (Container is Blueprint) - { - rect = Container.OccupiedRect(); - return true; - } - rect = default(CellRect); - return false; - } - - public override string GetReport() - { - Thing thing = ((pawn.CurJob != job || pawn.carryTracker.CarriedThing == null) ? base.TargetThingA : pawn.carryTracker.CarriedThing); - if (thing == null || !job.targetB.HasThing) - { - return "ReportHaulingUnknown".Translate(); - } - return ((job.GetTarget(TargetIndex.B).Thing is Building_Grave) ? "ReportHaulingToGrave" : "ReportHaulingTo").Translate(thing.Label, job.targetB.Thing.LabelShort.Named("DESTINATION"), thing.Named("THING")); - } - - public override bool TryMakePreToilReservations(bool errorOnFailed) - { - if (!pawn.Reserve(job.GetTarget(TargetIndex.A), job, 1, -1, null, errorOnFailed)) - { - return false; - } - if (Container.Isnt()) - { - if (!pawn.Reserve(job.GetTarget(TargetIndex.B), job, 1, 1, null, errorOnFailed)) - { - return false; - } - pawn.ReserveAsManyAsPossible(job.GetTargetQueue(TargetIndex.B), job); - } - UpdateEnrouteTrackers(); - pawn.ReserveAsManyAsPossible(job.GetTargetQueue(TargetIndex.A), job); - return true; - } - - protected virtual void ModifyPrepareToil(Toil toil) - { - } - - private bool TryReplaceWithFrame(TargetIndex index) - { - Thing thing = GetActor().jobs.curJob.GetTarget(index).Thing; - Building edifice = thing.Position.GetEdifice(pawn.Map); - if (edifice != null && thing is Blueprint_Build blueprint_Build && edifice is Frame frame && frame.BuildDef == blueprint_Build.BuildDef) - { - job.SetTarget(TargetIndex.B, frame); - return true; - } - return false; - } - - protected override IEnumerable MakeNewToils() - { - this.FailOnDestroyedOrNull(TargetIndex.A); - this.FailOn(delegate - { - Thing thing = GetActor().jobs.curJob.GetTarget(TargetIndex.B).Thing; - Thing thing2 = GetActor().jobs.curJob.GetTarget(TargetIndex.C).Thing; - if (thing == null) - { - return true; - } - if (thing2 != null && thing2.Destroyed && !TryReplaceWithFrame(TargetIndex.C)) - { - job.SetTarget(TargetIndex.C, null); - } - if (!thing.Spawned || (thing.Destroyed && !TryReplaceWithFrame(TargetIndex.B))) - { - if (job.targetQueueB.NullOrEmpty()) - { - return true; - } - if (!Toils_Haul.TryGetNextDestinationFromQueue(TargetIndex.C, TargetIndex.B, ThingDef, job, pawn, out var nextTarget)) - { - return true; - } - job.targetQueueB.RemoveAll((LocalTargetInfo target) => target.Thing == nextTarget); - job.targetB = nextTarget; - } - ThingOwner thingOwner = Container.TryGetInnerInteractableThingOwner(); - if (thingOwner != null && !thingOwner.CanAcceptAnyOf(ThingToCarry)) - { - return true; - } - return (Container is IHaulDestination haulDestination && !haulDestination.Accepts(ThingToCarry)) ? true : false; - }); - this.FailOnForbidden(TargetIndex.B); - this.FailOn(() => EnterPortalUtility.WasLoadingCanceled(Container)); - this.FailOn(() => TransporterUtility.WasLoadingCanceled(Container)); - this.FailOn(() => CompBiosculpterPod.WasLoadingCanceled(Container)); - this.FailOn(() => Building_SubcoreScanner.WasLoadingCancelled(Container)); - Toil getToHaulTarget = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.ClosestTouch, canGotoSpawnedParent: true).FailOn(() => ThingToCarry.ParentHolder is MinifiedThing).FailOnSelfAndParentsDespawnedOrNull(TargetIndex.A); - Toil uninstallIfMinifiable = Toils_Construct.UninstallIfMinifiable(TargetIndex.A).FailOnSomeonePhysicallyInteracting(TargetIndex.A).FailOn(() => ThingToCarry.ParentHolder is MinifiedThing) - .FailOnSelfAndParentsDespawnedOrNull(TargetIndex.A) - .FailOnDestroyedOrNull(TargetIndex.A); - Toil startCarryingThing = Toils_Haul.StartCarryThing(TargetIndex.A, putRemainderInQueue: false, subtractNumTakenFromJobCount: true, failIfStackCountLessThanJobCount: false, reserve: true, canTakeFromInventory: true); - Toil jumpIfAlsoCollectingNextTarget = Toils_Haul.JumpIfAlsoCollectingNextTargetInQueue(getToHaulTarget, TargetIndex.A); - Toil carryToContainer = Toils_Haul.CarryHauledThingToContainer(); - yield return Toils_Jump.JumpIf(jumpIfAlsoCollectingNextTarget, () => pawn.IsCarryingThing(ThingToCarry)); - yield return getToHaulTarget; - yield return uninstallIfMinifiable; - yield return startCarryingThing; - yield return jumpIfAlsoCollectingNextTarget; - yield return carryToContainer; - yield return Toils_Goto.MoveOffTargetBlueprint(TargetIndex.B); - Toil toil = Toils_General.Wait(Duration, TargetIndex.B); - toil.WithProgressBarToilDelay(TargetIndex.B); - EffecterDef workEffecter = WorkEffecter; - if (workEffecter != null) - { - toil.WithEffect(workEffecter, TargetIndex.B); - } - SoundDef workSustainer = WorkSustainer; - if (workSustainer != null) - { - toil.PlaySustainerOrSound(workSustainer); - } - Thing destThing = job.GetTarget(TargetIndex.B).Thing; - toil.tickIntervalAction = delegate(int delta) - { - if (pawn.IsHashIntervalTick(80, delta) && destThing is Building_Grave && graveDigEffect == null) - { - graveDigEffect = EffecterDefOf.BuryPawn.Spawn(); - graveDigEffect.Trigger(destThing, destThing); - } - }; - toil.tickAction = delegate - { - graveDigEffect?.EffectTick(destThing, destThing); - }; - ModifyPrepareToil(toil); - yield return toil; - yield return Toils_Construct.MakeSolidThingFromBlueprintIfNecessary(TargetIndex.B, TargetIndex.C); - yield return Toils_Haul.DepositHauledThingInContainer(TargetIndex.B, TargetIndex.C); - yield return Toils_Haul.JumpToCarryToNextContainerIfPossible(carryToContainer, TargetIndex.C); - } - - private void UpdateEnrouteTrackers() - { - int count = job.count; - TryReserveEnroute(base.TargetThingC, ref count); - if (base.TargetB != base.TargetC) - { - TryReserveEnroute(base.TargetThingB, ref count); - } - if (job.targetQueueB == null) - { - return; - } - foreach (LocalTargetInfo item in job.targetQueueB) - { - if (!base.TargetC.HasThing || !(item == base.TargetThingC)) - { - TryReserveEnroute(item.Thing, ref count); - } - } - } - - private void TryReserveEnroute(Thing thing, ref int count) - { - if (thing is IHaulEnroute container && !thing.DestroyedOrNull()) - { - UpdateTracker(container, ref count); - } - } - - private void UpdateTracker(IHaulEnroute container, ref int count) - { - if (!ThingToCarry.DestroyedOrNull()) - { - if (job.playerForced && container.GetSpaceRemainingWithEnroute(ThingDef) == 0) - { - container.Map.enrouteManager.InterruptEnroutePawns(container, pawn); - } - int num = Mathf.Min(count, container.GetSpaceRemainingWithEnroute(ThingDef)); - if (num > 0) - { - container.Map.enrouteManager.AddEnroute(container, pawn, base.TargetThingA.def, num); - } - count -= num; - } - } -} -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\JobDriver_PrepareCaravan_GatherItems.txt` -**相似度:** 0.5905 - -```csharp -public class JobDriver_PrepareCaravan_GatherItems : JobDriver -{ - private int pickedUpFirstItemTicks = -1; - - private int toilLoops; - - private PrepareCaravanGatherState gatherState; - - private const TargetIndex ToHaulInd = TargetIndex.A; - - private const TargetIndex CarrierInd = TargetIndex.B; - - private const int MaxTicksGatherItems = 7500; - - private const int LoopBackstop = 500; - - public Thing ToHaul => job.GetTarget(TargetIndex.A).Thing; - - public Pawn Carrier => (Pawn)job.GetTarget(TargetIndex.B).Thing; - - private List Transferables => ((LordJob_FormAndSendCaravan)job.lord.LordJob).transferables; - - private TransferableOneWay Transferable - { - get - { - TransferableOneWay transferableOneWay = TransferableUtility.TransferableMatchingDesperate(ToHaul, Transferables, TransferAsOneMode.PodsOrCaravanPacking); - if (transferableOneWay != null) - { - return transferableOneWay; - } - throw new InvalidOperationException("Could not find any matching transferable."); - } - } - - public override bool TryMakePreToilReservations(bool errorOnFailed) - { - return pawn.Reserve(ToHaul, job, 1, -1, null, errorOnFailed); - } - - protected override IEnumerable MakeNewToils() - { - if (gatherState == PrepareCaravanGatherState.Unset) - { - gatherState = ((pawn.IsFormingCaravan() && (!MassUtility.IsOverEncumbered(pawn) || pawn.inventory.HasAnyUnpackedCaravanItems)) ? PrepareCaravanGatherState.Haul : PrepareCaravanGatherState.Carry); - } - if (gatherState == PrepareCaravanGatherState.Carry) - { - return MakeNewToilsCarry(); - } - return MakeNewToilsHaulInInventory(); - } - - private IEnumerable MakeNewToilsCarry() - { - this.FailOn(() => !base.Map.lordManager.lords.Contains(job.lord)); - Toil reserve = Toils_Reserve.Reserve(TargetIndex.A).FailOnDestroyedOrNull(TargetIndex.A); - yield return reserve; - bool inInventory = HaulAIUtility.IsInHaulableInventory(ToHaul); - yield return Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch, inInventory); - yield return DetermineNumToHaul(); - yield return Toils_Haul.StartCarryThing(TargetIndex.A, putRemainderInQueue: false, subtractNumTakenFromJobCount: true, failIfStackCountLessThanJobCount: false, reserve: true, inInventory); - yield return AddCarriedThingToTransferables(); - yield return Toils_Haul.CheckForGetOpportunityDuplicate(reserve, TargetIndex.A, TargetIndex.None, takeFromValidStorage: true, (Thing x) => Transferable.things.Contains(x)); - Toil findCarrier = FindCarrier(); - yield return findCarrier; - yield return Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.Touch).JumpIf(() => !IsUsableCarrier(Carrier, pawn, allowColonists: true), findCarrier); - yield return Toils_General.Wait(25).JumpIf(() => !IsUsableCarrier(Carrier, pawn, allowColonists: true), findCarrier).WithProgressBarToilDelay(TargetIndex.B); - yield return PlaceTargetInCarrierInventory(); - } - - private IEnumerable MakeNewToilsHaulInInventory() - { - this.FailOn(() => !base.Map.lordManager.lords.Contains(job.lord)); - bool inInventory = HaulAIUtility.IsInHaulableInventory(ToHaul); - Toil reserve = Toils_Reserve.Reserve(TargetIndex.A).FailOnDestroyedOrNull(TargetIndex.A); - Toil findCarrier = FindCarrier(); - yield return reserve; - yield return Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch, inInventory).JumpIf(IsFinishedCollectingItems, findCarrier); - yield return DetermineNumToHaul(findCarrier); - yield return Toils_Haul.StartCarryThing(TargetIndex.A, putRemainderInQueue: false, subtractNumTakenFromJobCount: true, failIfStackCountLessThanJobCount: false, reserve: true, inInventory); - yield return AddCarriedThingToTransferables(); - yield return Toils_General.Wait(25).WithProgressBarToilDelay(TargetIndex.B); - yield return HaulCaravanItemInInventory(reserve); - yield return findCarrier; - yield return Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.Touch).JumpIf(() => !IsUsableCarrier(Carrier, pawn, allowColonists: true), findCarrier); - yield return Toils_General.Wait(25).JumpIf(() => !IsUsableCarrier(Carrier, pawn, allowColonists: true), findCarrier).WithProgressBarToilDelay(TargetIndex.B); - yield return AddHauledItemsToCarrier(findCarrier); - } - - private Toil DetermineNumToHaul(Toil findCarrier = null) - { - Toil toil = ToilMaker.MakeToil("DetermineNumToHaul"); - toil.initAction = delegate - { - int num = GatherItemsForCaravanUtility.CountLeftToTransfer(pawn, Transferable, job.lord); - if (pawn.carryTracker.CarriedThing != null) - { - num -= pawn.carryTracker.CarriedThing.stackCount; - } - if (num <= 0) - { - if (findCarrier == null || !pawn.inventory.HasAnyUnpackedCaravanItems) - { - pawn.jobs.EndCurrentJob(JobCondition.Succeeded); - } - else - { - pawn.jobs.curDriver.JumpToToil(findCarrier); - } - } - else - { - job.count = num; - } - }; - toil.defaultCompleteMode = ToilCompleteMode.Instant; - toil.atomicWithPrevious = true; - return toil; - } - - private Toil AddCarriedThingToTransferables() - { - Toil toil = ToilMaker.MakeToil("AddCarriedThingToTransferables"); - toil.initAction = delegate - { - TransferableOneWay transferable = Transferable; - if (!transferable.things.Contains(pawn.carryTracker.CarriedThing)) - { - transferable.things.Add(pawn.carryTracker.CarriedThing); - } - }; - toil.defaultCompleteMode = ToilCompleteMode.Instant; - toil.atomicWithPrevious = true; - return toil; - } - - private Toil FindCarrier() - { - Toil toil = ToilMaker.MakeToil("FindCarrier"); - toil.initAction = delegate - { - Pawn pawn = FindBestCarrier(onlyAnimals: true); - if (pawn == null) - { - bool flag = base.pawn.GetLord() == job.lord; - if (flag && !MassUtility.IsOverEncumbered(base.pawn)) - { - pawn = base.pawn; - } - else - { - pawn = FindBestCarrier(onlyAnimals: false); - if (pawn == null) - { - if (flag) - { - pawn = base.pawn; - } - else - { - IEnumerable source = job.lord.ownedPawns.Where((Pawn x) => IsUsableCarrier(x, base.pawn, allowColonists: true)); - if (!source.Any()) - { - EndJobWith(JobCondition.Incompletable); - return; - } - pawn = source.RandomElement(); - } - } - } - } - job.SetTarget(TargetIndex.B, pawn); - }; - return toil; - } - - private bool IsFinishedCollectingItems() - { - if (!MassUtility.IsOverEncumbered(pawn)) - { - if (pickedUpFirstItemTicks > -1) - { - return Find.TickManager.TicksGame > pickedUpFirstItemTicks + 7500; - } - return false; - } - return true; - } - - private Toil HaulCaravanItemInInventory(Toil reserve) - { - Toil toil = ToilMaker.MakeToil("HaulCaravanItemInInventory"); - toil.initAction = delegate - { - if (pickedUpFirstItemTicks == -1) - { - pickedUpFirstItemTicks = Find.TickManager.TicksGame; - } - Transferable.AdjustTo(Mathf.Max(Transferable.CountToTransfer - pawn.carryTracker.CarriedThing.stackCount, 0)); - pawn.inventory.AddHauledCaravanItem(pawn.carryTracker.CarriedThing); - if (!IsFinishedCollectingItems()) - { - SetNewHaulTargetAndJumpToReserve(reserve); - } - }; - return toil; - } - - private void SetNewHaulTargetAndJumpToReserve(Toil reserve) - { - if (CheckToilLoopBackstop()) - { - Thing thing = GatherItemsForCaravanUtility.FindThingToHaul(pawn, pawn.GetLord()); - if (thing != null) - { - job.SetTarget(TargetIndex.A, thing); - pawn.jobs.curDriver.JumpToToil(reserve); - } - } - } - - private Toil AddHauledItemsToCarrier(Toil findCarrier) - { - Toil toil = ToilMaker.MakeToil("AddHauledItemsToCarrier"); - toil.initAction = delegate - { - if (Carrier == pawn) - { - pawn.inventory.ClearHaulingCaravanCache(); - } - else - { - pawn.inventory.TransferCaravanItemsToCarrier(Carrier.inventory); - if (pawn.inventory.HasAnyUnpackedCaravanItems && CheckToilLoopBackstop()) - { - pawn.jobs.curDriver.JumpToToil(findCarrier); - } - } - }; - return toil; - } - - private bool CheckToilLoopBackstop() - { - if (++toilLoops > 500) - { - Log.Error("Prepare caravan gather items job for pawn " + pawn.Label + " looped through toils too many times"); - EndJobWith(JobCondition.Errored); - return false; - } - return true; - } - - private Toil PlaceTargetInCarrierInventory() - { - Toil toil = ToilMaker.MakeToil("PlaceTargetInCarrierInventory"); - toil.initAction = delegate - { - Pawn_CarryTracker carryTracker = pawn.carryTracker; - Thing carriedThing = carryTracker.CarriedThing; - if (carryTracker.innerContainer.Count == 0) - { - carryTracker.pawn.Drawer.renderer.SetAllGraphicsDirty(); - } - Transferable.AdjustTo(Mathf.Max(Transferable.CountToTransfer - carriedThing.stackCount, 0)); - carryTracker.innerContainer.TryTransferToContainer(carriedThing, Carrier.inventory.innerContainer, carriedThing.stackCount, out var resultingTransferredItem); - CompForbiddable compForbiddable = resultingTransferredItem?.TryGetComp(); - if (compForbiddable != null) - { - compForbiddable.Forbidden = false; - } - }; - return toil; - } - - public static bool IsUsableCarrier(Pawn p, Pawn forPawn, bool allowColonists) - { - if (!p.IsFormingCaravan()) - { - return false; - } - if (p == forPawn) - { - return true; - } - if (p.DestroyedOrNull() || !p.Spawned || p.inventory.UnloadEverything || !forPawn.CanReach(p, PathEndMode.Touch, Danger.Deadly)) - { - return false; - } - if (allowColonists && p.IsColonist) - { - return true; - } - if ((p.RaceProps.packAnimal || p.HostFaction == Faction.OfPlayer) && !p.IsBurning() && !p.Downed) - { - return !MassUtility.IsOverEncumbered(p); - } - return false; - } - - private float GetCarrierScore(Pawn p) - { - float lengthHorizontal = (p.Position - pawn.Position).LengthHorizontal; - float num = MassUtility.EncumbrancePercent(p); - return 1f - num - lengthHorizontal / 10f * 0.2f; - } - - private Pawn FindBestCarrier(bool onlyAnimals) - { - Lord lord = job.lord; - Pawn pawn = null; - float num = 0f; - if (lord != null) - { - for (int i = 0; i < lord.ownedPawns.Count; i++) - { - Pawn pawn2 = lord.ownedPawns[i]; - if (pawn2 != base.pawn && (!onlyAnimals || pawn2.RaceProps.Animal) && IsUsableCarrier(pawn2, base.pawn, allowColonists: false)) - { - float carrierScore = GetCarrierScore(pawn2); - if (pawn == null || carrierScore > num) - { - pawn = pawn2; - num = carrierScore; - } - } - } - } - return pawn; - } - - public override void ExposeData() - { - base.ExposeData(); - Scribe_Values.Look(ref pickedUpFirstItemTicks, "pickedUpFirstItemTicks", 0); - Scribe_Values.Look(ref toilLoops, "toilLoops", 0); - Scribe_Values.Look(ref gatherState, "gatherState", PrepareCaravanGatherState.Unset); - } -} -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\JobDriver_CarryToCryptosleepCasket.txt` -**相似度:** 0.5506 - -```csharp -public class JobDriver_CarryToCryptosleepCasket : JobDriver -{ - private const TargetIndex TakeeInd = TargetIndex.A; - - private const TargetIndex DropPodInd = TargetIndex.B; - - protected Pawn Takee => (Pawn)job.GetTarget(TargetIndex.A).Thing; - - protected Building_CryptosleepCasket DropPod => (Building_CryptosleepCasket)job.GetTarget(TargetIndex.B).Thing; - - public override bool TryMakePreToilReservations(bool errorOnFailed) - { - if (pawn.Reserve(Takee, job, 1, -1, null, errorOnFailed)) - { - return pawn.Reserve(DropPod, job, 1, -1, null, errorOnFailed); - } - return false; - } - - protected override IEnumerable MakeNewToils() - { - this.FailOnDestroyedOrNull(TargetIndex.A); - this.FailOnDestroyedOrNull(TargetIndex.B); - this.FailOnAggroMentalState(TargetIndex.A); - this.FailOn(() => !DropPod.Accepts(Takee)); - Toil goToTakee = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.OnCell).FailOnDestroyedNullOrForbidden(TargetIndex.A).FailOnDespawnedNullOrForbidden(TargetIndex.B) - .FailOn(() => DropPod.GetDirectlyHeldThings().Count > 0) - .FailOn(() => !pawn.CanReach(Takee, PathEndMode.OnCell, Danger.Deadly)) - .FailOnSomeonePhysicallyInteracting(TargetIndex.A); - Toil startCarryingTakee = Toils_Haul.StartCarryThing(TargetIndex.A); - Toil goToThing = Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.InteractionCell); - yield return Toils_Jump.JumpIf(goToThing, () => pawn.IsCarryingPawn(Takee)); - yield return goToTakee; - yield return startCarryingTakee; - yield return goToThing; - Toil toil = Toils_General.Wait(500, TargetIndex.B); - toil.FailOnCannotTouch(TargetIndex.B, PathEndMode.InteractionCell); - toil.WithProgressBarToilDelay(TargetIndex.B); - yield return toil; - Toil toil2 = ToilMaker.MakeToil("MakeNewToils"); - toil2.initAction = delegate - { - DropPod.TryAcceptThing(Takee); - }; - toil2.defaultCompleteMode = ToilCompleteMode.Instant; - yield return toil2; - } - - public override object[] TaleParameters() - { - return new object[2] { pawn, Takee }; - } -} -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\Verse.AI\JobDriver_HaulToAtomizer.txt` -**相似度:** 0.5312 - -```csharp -public class JobDriver_HaulToAtomizer : JobDriver -{ - private const TargetIndex AtomizerInd = TargetIndex.A; - - private const TargetIndex WastepackInd = TargetIndex.B; - - private const TargetIndex ChargerCellInd = TargetIndex.C; - - public override bool TryMakePreToilReservations(bool errorOnFailed) - { - pawn.ReserveAsManyAsPossible(job.GetTargetQueue(TargetIndex.B), job); - return pawn.Reserve(job.GetTarget(TargetIndex.A), job, 1, -1, null, errorOnFailed); - } - - protected override IEnumerable MakeNewToils() - { - this.FailOnDespawnedNullOrForbidden(TargetIndex.A); - AddEndCondition(() => (base.TargetThingA.TryGetComp().SpaceLeft > 0) ? JobCondition.Ongoing : JobCondition.Succeeded); - Toil clearQueue = Toils_JobTransforms.ClearDespawnedNullOrForbiddenQueuedTargets(TargetIndex.B); - yield return clearQueue; - yield return Toils_JobTransforms.SucceedOnNoTargetInQueue(TargetIndex.B); - yield return Toils_JobTransforms.ExtractNextTargetFromQueue(TargetIndex.B); - yield return Toils_Reserve.Reserve(TargetIndex.B); - yield return Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.ClosestTouch).FailOnSomeonePhysicallyInteracting(TargetIndex.B); - yield return Toils_Haul.StartCarryThing(TargetIndex.B, putRemainderInQueue: false, subtractNumTakenFromJobCount: true); - yield return Toils_Haul.CheckForGetOpportunityDuplicate(clearQueue, TargetIndex.B, TargetIndex.None, takeFromValidStorage: true); - yield return Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell); - yield return Toils_Haul.DepositHauledThingInContainer(TargetIndex.A, TargetIndex.B); - yield return Toils_Jump.Jump(clearQueue); - } -} -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\Verse.AI\JobDriver_PickupToHold.txt` -**相似度:** 0.5219 - -```csharp -public class JobDriver_PickupToHold : JobDriver -{ - private const TargetIndex HeldItemInd = TargetIndex.A; - - public static bool TryMakePreToilReservations(JobDriver driver, bool errorOnFailed) - { - driver.pawn.Map.pawnDestinationReservationManager.Reserve(driver.pawn, driver.job, driver.job.GetTarget(TargetIndex.A).Cell); - return driver.pawn.Reserve(driver.job.GetTarget(TargetIndex.A), driver.job, 1, -1, null, errorOnFailed); - } - - public static IEnumerable Toils(JobDriver driver, TargetIndex HeldItem = TargetIndex.A, bool subtractNumTakenFromJobCount = true) - { - driver.FailOn(() => !driver.GetActor().health.capacities.CapableOf(PawnCapacityDefOf.Manipulation)); - driver.FailOnDestroyedOrNull(HeldItem); - driver.FailOnForbidden(HeldItem); - Toil end = Toils_General.Label(); - yield return Toils_Jump.JumpIf(end, () => driver.GetActor().IsCarryingThing(driver.GetActor().CurJob.GetTarget(HeldItem).Thing)); - yield return Toils_Goto.GotoThing(HeldItem, PathEndMode.ClosestTouch).FailOnSomeonePhysicallyInteracting(HeldItem); - yield return Toils_Haul.StartCarryThing(HeldItem, putRemainderInQueue: false, subtractNumTakenFromJobCount); - yield return end; - } - - public override bool TryMakePreToilReservations(bool errorOnFailed) - { - return TryMakePreToilReservations(this, errorOnFailed); - } - - protected override IEnumerable MakeNewToils() - { - return Toils(this); - } -} -``` \ No newline at end of file diff --git a/MCP/vector_cache/StatDef.txt b/MCP/vector_cache/StatDef.txt deleted file mode 100644 index b26afb92..00000000 --- a/MCP/vector_cache/StatDef.txt +++ /dev/null @@ -1,502 +0,0 @@ -根据向量相似度分析,与 'StatDef' 最相关的代码定义如下: - ---- -**文件路径 (精确匹配):** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\StatDef.txt` - -```csharp -public class StatDef : Def -{ - private static HashSet mutableStats; - - public StatCategoryDef category; - - public Type workerClass = typeof(StatWorker); - - public string labelForFullStatList; - - public bool forInformationOnly; - - [MustTranslate] - private string offsetLabel; - - public float hideAtValue = -2.1474836E+09f; - - public bool alwaysHide; - - public bool showNonAbstract = true; - - public bool showIfUndefined = true; - - public bool showOnPawns = true; - - public bool showOnHumanlikes = true; - - public bool showOnNonWildManHumanlikes = true; - - public bool showOnAnimals = true; - - public bool showOnMechanoids = true; - - public bool showOnNonWorkTables = true; - - public bool showOnEntities = true; - - public bool showOnDrones = true; - - public bool showOnNonPowerPlants = true; - - public bool showOnDefaultValue = true; - - public bool showOnUnhaulables = true; - - public bool showOnUntradeables = true; - - public List showIfModsLoaded; - - public List showIfModsLoadedAny; - - public List showIfHediffsPresent; - - public bool neverDisabled; - - public bool showZeroBaseValue; - - public bool showOnSlavesOnly; - - public bool showOnPlayerMechanoids; - - public DevelopmentalStage showDevelopmentalStageFilter = DevelopmentalStage.Baby | DevelopmentalStage.Child | DevelopmentalStage.Adult; - - public bool hideInClassicMode; - - public List showOnPawnKind; - - public bool overridesHideStats; - - public int displayPriorityInCategory; - - public ToStringNumberSense toStringNumberSense = ToStringNumberSense.Absolute; - - public ToStringStyle toStringStyle; - - private ToStringStyle? toStringStyleUnfinalized; - - [MustTranslate] - public string formatString; - - [MustTranslate] - public string formatStringUnfinalized; - - public bool finalizeEquippedStatOffset = true; - - [MustTranslate] - public string statFactorsExplanationHeader; - - public float defaultBaseValue = 1f; - - public List skillNeedOffsets; - - public float noSkillOffset; - - public List capacityOffsets; - - public List statFactors; - - public bool applyFactorsIfNegative = true; - - public List skillNeedFactors; - - public float noSkillFactor = 1f; - - public List capacityFactors; - - public SimpleCurve postProcessCurve; - - public List postProcessStatFactors; - - public float minValue = -9999999f; - - public float maxValue = 9999999f; - - public float valueIfMissing; - - public bool roundValue; - - public float roundToFiveOver = float.MaxValue; - - public bool minifiedThingInherits; - - public bool supressDisabledError; - - public bool cacheable; - - public bool displayMaxWhenAboveOrEqual; - - public bool scenarioRandomizable; - - public SkillDef disableIfSkillDisabled; - - public List parts; - - [Unsaved(false)] - private StatWorker workerInt; - - [Unsaved(false)] - public bool immutable; - - public StatWorker Worker - { - get - { - if (workerInt == null) - { - if (parts != null) - { - for (int i = 0; i < parts.Count; i++) - { - parts[i].parentStat = this; - } - } - workerInt = (StatWorker)Activator.CreateInstance(workerClass); - workerInt.InitSetStat(this); - } - return workerInt; - } - } - - public ToStringStyle ToStringStyleUnfinalized - { - get - { - if (!toStringStyleUnfinalized.HasValue) - { - return toStringStyle; - } - return toStringStyleUnfinalized.Value; - } - } - - public string LabelForFullStatList - { - get - { - if (!labelForFullStatList.NullOrEmpty()) - { - return labelForFullStatList; - } - return label; - } - } - - public string LabelForFullStatListCap => LabelForFullStatList.CapitalizeFirst(this); - - public string OffsetLabel => offsetLabel ?? label; - - public string OffsetLabelCap => OffsetLabel.CapitalizeFirst(); - - public override IEnumerable ConfigErrors() - { - foreach (string item in base.ConfigErrors()) - { - yield return item; - } - if (capacityFactors != null) - { - foreach (PawnCapacityFactor capacityFactor in capacityFactors) - { - if (capacityFactor.weight > 1f) - { - yield return defName + " has activity factor with weight > 1"; - } - } - } - if (parts == null) - { - yield break; - } - for (int i = 0; i < parts.Count; i++) - { - foreach (string item2 in parts[i].ConfigErrors()) - { - yield return defName + " has error in StatPart " + parts[i].ToString() + ": " + item2; - } - } - } - - public string ValueToString(float val, ToStringNumberSense numberSense = ToStringNumberSense.Absolute, bool finalized = true) - { - return Worker.ValueToString(val, finalized, numberSense); - } - - public static StatDef Named(string defName) - { - return DefDatabase.GetNamed(defName); - } - - public override void PostLoad() - { - base.PostLoad(); - if (parts != null) - { - List partsCopy = parts.ToList(); - parts.SortBy((StatPart x) => 0f - x.priority, (StatPart x) => partsCopy.IndexOf(x)); - } - } - - public T GetStatPart() where T : StatPart - { - return parts.OfType().FirstOrDefault(); - } - - public bool CanShowWithLoadedMods() - { - if (!showIfModsLoaded.NullOrEmpty()) - { - for (int i = 0; i < showIfModsLoaded.Count; i++) - { - if (!ModsConfig.IsActive(showIfModsLoaded[i])) - { - return false; - } - } - } - if (!showIfModsLoadedAny.NullOrEmpty()) - { - bool result = false; - for (int j = 0; j < showIfModsLoadedAny.Count; j++) - { - if (ModsConfig.IsActive(showIfModsLoadedAny[j])) - { - result = true; - break; - } - } - return result; - } - return true; - } - - private static void PopulateMutableStats() - { - mutableStats = new HashSet(); - foreach (TraitDef item in DefDatabase.AllDefsListForReading) - { - foreach (TraitDegreeData degreeData in item.degreeDatas) - { - AddStatsFromModifiers(degreeData.statOffsets); - AddStatsFromModifiers(degreeData.statFactors); - } - } - foreach (HediffDef item2 in DefDatabase.AllDefsListForReading) - { - if (item2.stages == null) - { - continue; - } - foreach (HediffStage stage in item2.stages) - { - AddStatsFromModifiers(stage.statOffsets); - AddStatsFromModifiers(stage.statFactors); - if (stage.statOffsetEffectMultiplier != null) - { - mutableStats.Add(stage.statOffsetEffectMultiplier); - } - if (stage.statFactorEffectMultiplier != null) - { - mutableStats.Add(stage.statFactorEffectMultiplier); - } - if (stage.capacityFactorEffectMultiplier != null) - { - mutableStats.Add(stage.capacityFactorEffectMultiplier); - } - } - } - foreach (PreceptDef item3 in DefDatabase.AllDefsListForReading) - { - AddStatsFromModifiers(item3.statOffsets); - AddStatsFromModifiers(item3.statFactors); - if (item3.roleEffects != null) - { - foreach (RoleEffect roleEffect in item3.roleEffects) - { - if (roleEffect is RoleEffect_PawnStatOffset roleEffect_PawnStatOffset) - { - mutableStats.Add(roleEffect_PawnStatOffset.statDef); - } - if (roleEffect is RoleEffect_PawnStatFactor roleEffect_PawnStatFactor) - { - mutableStats.Add(roleEffect_PawnStatFactor.statDef); - } - } - } - if (item3.abilityStatFactors == null) - { - continue; - } - foreach (AbilityStatModifiers abilityStatFactor in item3.abilityStatFactors) - { - AddStatsFromModifiers(abilityStatFactor.modifiers); - } - } - foreach (GeneDef item4 in DefDatabase.AllDefsListForReading) - { - AddStatsFromModifiers(item4.statOffsets); - AddStatsFromModifiers(item4.statFactors); - if (item4.conditionalStatAffecters == null) - { - continue; - } - foreach (ConditionalStatAffecter conditionalStatAffecter in item4.conditionalStatAffecters) - { - AddStatsFromModifiers(conditionalStatAffecter.statOffsets); - AddStatsFromModifiers(conditionalStatAffecter.statFactors); - } - } - foreach (ThingDef item5 in DefDatabase.AllDefsListForReading) - { - AddStatsFromModifiers(item5.equippedStatOffsets); - if (!item5.HasAssignableCompFrom(typeof(CompFacility))) - { - continue; - } - CompProperties_Facility compProperties = item5.GetCompProperties(); - if (compProperties?.statOffsets != null) - { - AddStatsFromModifiers(compProperties.statOffsets); - } - if (!(compProperties is CompProperties_FacilityQualityBased compProperties_FacilityQualityBased)) - { - continue; - } - foreach (StatDef key in compProperties_FacilityQualityBased.statOffsetsPerQuality.Keys) - { - mutableStats.Add(key); - } - } - foreach (WeaponTraitDef item6 in DefDatabase.AllDefsListForReading) - { - AddStatsFromModifiers(item6.equippedStatOffsets); - } - foreach (LifeStageDef item7 in DefDatabase.AllDefsListForReading) - { - AddStatsFromModifiers(item7.statFactors); - AddStatsFromModifiers(item7.statOffsets); - } - foreach (InspirationDef item8 in DefDatabase.AllDefsListForReading) - { - AddStatsFromModifiers(item8.statOffsets); - AddStatsFromModifiers(item8.statFactors); - } - static void AddStatsFromModifiers(List mods) - { - if (mods != null) - { - mutableStats.AddRange(mods.Select((StatModifier mod) => mod.stat)); - } - } - } - - public bool IsImmutable() - { - if (workerClass != typeof(StatWorker)) - { - return false; - } - if (!skillNeedOffsets.NullOrEmpty() || !skillNeedFactors.NullOrEmpty()) - { - return false; - } - if (!capacityOffsets.NullOrEmpty() || !capacityFactors.NullOrEmpty()) - { - return false; - } - if (!statFactors.NullOrEmpty()) - { - return false; - } - if (!parts.NullOrEmpty()) - { - return false; - } - if (!postProcessStatFactors.NullOrEmpty()) - { - return false; - } - if (mutableStats.Contains(this)) - { - return false; - } - return true; - } - - public static void SetImmutability() - { - PopulateMutableStats(); - foreach (StatDef item in DefDatabase.AllDefsListForReading) - { - item.immutable = item.IsImmutable(); - item.Worker.SetCacheability(item.immutable); - } - } - - public static void ResetStaticData() - { - mutableStats = null; - foreach (StatDef item in DefDatabase.AllDefsListForReading) - { - item.immutable = false; - item.Worker.DeleteStatCache(); - } - } -} -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\Core\Defs\Stats\Stats_Building_Special.xml` -**相似度:** 0.5742 - -```xml - - WorkToBuild - - The base amount of work it takes to build a structure, once all materials are gathered.\n\nThe work required to deconstruct the structure is also based on this. - Building - 1 - 0 - WorkAmount - 300 - false - true - 3101 - -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\Royalty\Defs\Stats\Stats_Basics_Special.xml` -**相似度:** 0.5197 - -```xml - - MeditationPlantGrowthOffset - - An offset applied to the growth rate of plants, like anima grass, from meditation. This value can change based on the number of artificial buildings nearby. - Meditation - 0 - false - false - false - 4000 - PercentZero - -
  • - 27.9 - - -
  • (0, 0.0)
  • -
  • (5, -0.08)
  • -
  • (10, -0.15)
  • -
  • (50, -0.3)
  • - - - -
    -
    -``` \ No newline at end of file diff --git a/MCP/vector_cache/WorkGiver_Scanner.txt b/MCP/vector_cache/WorkGiver_Scanner.txt deleted file mode 100644 index 01ee366c..00000000 --- a/MCP/vector_cache/WorkGiver_Scanner.txt +++ /dev/null @@ -1,507 +0,0 @@ -根据向量相似度分析,与 'WorkGiver_Scanner' 最相关的代码定义如下: - ---- -**文件路径 (精确匹配):** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\WorkGiver_Scanner.txt` - -```csharp -public abstract class WorkGiver_Scanner : WorkGiver -{ - public virtual ThingRequest PotentialWorkThingRequest => ThingRequest.ForGroup(ThingRequestGroup.Undefined); - - public virtual int MaxRegionsToScanBeforeGlobalSearch => -1; - - public virtual bool Prioritized => false; - - public virtual bool AllowUnreachable => false; - - public virtual PathEndMode PathEndMode => PathEndMode.Touch; - - public virtual IEnumerable PotentialWorkCellsGlobal(Pawn pawn) - { - return Enumerable.Empty(); - } - - public virtual IEnumerable PotentialWorkThingsGlobal(Pawn pawn) - { - return null; - } - - public virtual Danger MaxPathDanger(Pawn pawn) - { - return pawn.NormalMaxDanger(); - } - - public virtual bool HasJobOnThing(Pawn pawn, Thing t, bool forced = false) - { - return JobOnThing(pawn, t, forced) != null; - } - - public virtual string JobInfo(Pawn pawn, Job job) - { - return string.Empty; - } - - public virtual Job JobOnThing(Pawn pawn, Thing t, bool forced = false) - { - return null; - } - - public virtual bool HasJobOnCell(Pawn pawn, IntVec3 c, bool forced = false) - { - return JobOnCell(pawn, c, forced) != null; - } - - public virtual Job JobOnCell(Pawn pawn, IntVec3 cell, bool forced = false) - { - return null; - } - - public virtual float GetPriority(Pawn pawn, TargetInfo t) - { - return 0f; - } - - public virtual string PostProcessedGerund(Job job) - { - return def.gerund; - } - - public float GetPriority(Pawn pawn, IntVec3 cell) - { - return GetPriority(pawn, new TargetInfo(cell, pawn.Map)); - } - - public virtual ReservationLayerDef GetReservationLayer(Pawn pawn, LocalTargetInfo target) - { - return null; - } -} -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\WorkGiver_HaulToSubcoreScanner.txt` -**相似度:** 0.5742 - -```csharp -public class WorkGiver_HaulToSubcoreScanner : WorkGiver_Scanner -{ - public override ThingRequest PotentialWorkThingRequest => ThingRequest.ForGroup(ThingRequestGroup.SubcoreScanner); - - public override bool HasJobOnThing(Pawn pawn, Thing t, bool forced = false) - { - if (!ModLister.CheckBiotech("Haul to subcore scanner")) - { - return false; - } - if (!(t is Building_SubcoreScanner { State: SubcoreScannerState.WaitingForIngredients } building_SubcoreScanner)) - { - return false; - } - if (!pawn.CanReserve(t, 1, -1, null, forced)) - { - return false; - } - return FindIngredients(pawn, building_SubcoreScanner).Thing != null; - } - - public override Job JobOnThing(Pawn pawn, Thing t, bool forced = false) - { - if (!(t is Building_SubcoreScanner { State: SubcoreScannerState.WaitingForIngredients } building_SubcoreScanner)) - { - return null; - } - ThingCount thingCount = FindIngredients(pawn, building_SubcoreScanner); - if (thingCount.Thing != null) - { - Job job = HaulAIUtility.HaulToContainerJob(pawn, thingCount.Thing, t); - job.count = Mathf.Min(job.count, thingCount.Count); - return job; - } - return null; - } - - private ThingCount FindIngredients(Pawn pawn, Building_SubcoreScanner scanner) - { - Thing thing = GenClosest.ClosestThingReachable(pawn.Position, pawn.Map, ThingRequest.ForGroup(ThingRequestGroup.HaulableEver), PathEndMode.ClosestTouch, TraverseParms.For(pawn), 9999f, Validator); - if (thing == null) - { - return default(ThingCount); - } - int requiredCountOf = scanner.GetRequiredCountOf(thing.def); - return new ThingCount(thing, Mathf.Min(thing.stackCount, requiredCountOf)); - bool Validator(Thing x) - { - if (!pawn.CanReserve(x)) - { - return false; - } - if (x.IsForbidden(pawn)) - { - return false; - } - return scanner.CanAcceptIngredient(x); - } - } -} -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\WorkGiver_HaulToBiosculpterPod.txt` -**相似度:** 0.5453 - -```csharp -public class WorkGiver_HaulToBiosculpterPod : WorkGiver_Scanner -{ - public override ThingRequest PotentialWorkThingRequest => ThingRequest.ForDef(ThingDefOf.BiosculpterPod); - - public override PathEndMode PathEndMode => PathEndMode.Touch; - - public override bool HasJobOnThing(Pawn pawn, Thing t, bool forced = false) - { - if (!ModLister.CheckIdeology("Biosculpting")) - { - return false; - } - if (!pawn.CanReserve(t, 1, -1, null, forced)) - { - return false; - } - if (pawn.Map.designationManager.DesignationOn(t, DesignationDefOf.Deconstruct) != null) - { - return false; - } - CompBiosculpterPod compBiosculpterPod = t.TryGetComp(); - if (compBiosculpterPod == null || !compBiosculpterPod.PowerOn || compBiosculpterPod.State != 0 || (!forced && !compBiosculpterPod.autoLoadNutrition)) - { - return false; - } - if (t.IsBurning()) - { - return false; - } - if (compBiosculpterPod.RequiredNutritionRemaining > 0f) - { - if (FindNutrition(pawn, compBiosculpterPod).Thing == null) - { - JobFailReason.Is("NoFood".Translate()); - return false; - } - return true; - } - return false; - } - - public override Job JobOnThing(Pawn pawn, Thing t, bool forced = false) - { - CompBiosculpterPod compBiosculpterPod = t.TryGetComp(); - if (compBiosculpterPod == null) - { - return null; - } - if (compBiosculpterPod.RequiredNutritionRemaining > 0f) - { - ThingCount thingCount = FindNutrition(pawn, compBiosculpterPod); - if (thingCount.Thing != null) - { - Job job = HaulAIUtility.HaulToContainerJob(pawn, thingCount.Thing, t); - job.count = Mathf.Min(job.count, thingCount.Count); - return job; - } - } - return null; - } - - private ThingCount FindNutrition(Pawn pawn, CompBiosculpterPod pod) - { - Thing thing = GenClosest.ClosestThingReachable(pawn.Position, pawn.Map, ThingRequest.ForGroup(ThingRequestGroup.FoodSourceNotPlantOrTree), PathEndMode.ClosestTouch, TraverseParms.For(pawn), 9999f, Validator); - if (thing == null) - { - return default(ThingCount); - } - int b = Mathf.CeilToInt(pod.RequiredNutritionRemaining / thing.GetStatValue(StatDefOf.Nutrition)); - return new ThingCount(thing, Mathf.Min(thing.stackCount, b)); - bool Validator(Thing x) - { - if (x.IsForbidden(pawn) || !pawn.CanReserve(x)) - { - return false; - } - if (!pod.CanAcceptNutrition(x)) - { - return false; - } - return true; - } - } -} -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\WorkGiver_ConstructFinishFrames.txt` -**相似度:** 0.5184 - -```csharp -public class WorkGiver_ConstructFinishFrames : WorkGiver_Scanner -{ - public override PathEndMode PathEndMode => PathEndMode.Touch; - - public override ThingRequest PotentialWorkThingRequest => ThingRequest.ForGroup(ThingRequestGroup.BuildingFrame); - - public override Danger MaxPathDanger(Pawn pawn) - { - return Danger.Deadly; - } - - public override Job JobOnThing(Pawn pawn, Thing t, bool forced = false) - { - if (t.Faction != pawn.Faction) - { - return null; - } - if (!(t is Frame frame)) - { - return null; - } - if (!frame.IsCompleted()) - { - return null; - } - if (!GenConstruct.CanTouchTargetFromValidCell(frame, pawn)) - { - return null; - } - if (GenConstruct.FirstBlockingThing(frame, pawn) != null) - { - return GenConstruct.HandleBlockingThingJob(frame, pawn, forced); - } - if (!GenConstruct.CanConstruct(frame, pawn, checkSkills: true, forced)) - { - return null; - } - return JobMaker.MakeJob(JobDefOf.FinishFrame, frame); - } -} -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\WorkGiver_CookFillHopper.txt` -**相似度:** 0.5093 - -```csharp -public class WorkGiver_CookFillHopper : WorkGiver_Scanner -{ - private static string TheOnlyAvailableFoodIsInStorageOfHigherPriorityTrans; - - private static string NoFoodToFillHopperTrans; - - public override ThingRequest PotentialWorkThingRequest => ThingRequest.ForDef(ThingDefOf.Hopper); - - public override PathEndMode PathEndMode => PathEndMode.ClosestTouch; - - public WorkGiver_CookFillHopper() - { - if (TheOnlyAvailableFoodIsInStorageOfHigherPriorityTrans == null) - { - TheOnlyAvailableFoodIsInStorageOfHigherPriorityTrans = "TheOnlyAvailableFoodIsInStorageOfHigherPriority".Translate(); - } - if (NoFoodToFillHopperTrans == null) - { - NoFoodToFillHopperTrans = "NoFoodToFillHopper".Translate(); - } - } - - public override Job JobOnThing(Pawn pawn, Thing thing, bool forced = false) - { - if (!(thing is ISlotGroupParent hopperSgp)) - { - return null; - } - if (!pawn.CanReserve(thing.Position)) - { - return null; - } - float num = 0f; - List list = pawn.Map.thingGrid.ThingsListAt(thing.Position); - for (int i = 0; i < list.Count; i++) - { - Thing thing2 = list[i]; - if (Building_NutrientPasteDispenser.IsAcceptableFeedstock(thing2.def)) - { - num = (float)thing2.stackCount / (float)thing2.def.stackLimit; - } - } - if (num > 0.35f) - { - JobFailReason.Is("AlreadyFilledLower".Translate()); - return null; - } - return HopperFillFoodJob(pawn, hopperSgp, forced); - } - - public static Job HopperFillFoodJob(Pawn pawn, ISlotGroupParent hopperSgp, bool forced) - { - Building building = (Building)hopperSgp; - if (!pawn.CanReserveAndReach(building.Position, PathEndMode.Touch, pawn.NormalMaxDanger())) - { - return null; - } - ThingDef thingDef = null; - Thing firstItem = building.Position.GetFirstItem(building.Map); - if (firstItem != null) - { - if (!Building_NutrientPasteDispenser.IsAcceptableFeedstock(firstItem.def)) - { - if (firstItem.IsForbidden(pawn)) - { - return null; - } - return HaulAIUtility.HaulAsideJobFor(pawn, firstItem); - } - thingDef = firstItem.def; - } - List list = ((thingDef != null) ? pawn.Map.listerThings.ThingsOfDef(thingDef) : pawn.Map.listerThings.ThingsInGroup(ThingRequestGroup.FoodSourceNotPlantOrTree)); - bool flag = false; - for (int i = 0; i < list.Count; i++) - { - Thing thing = list[i]; - if (!thing.def.IsNutritionGivingIngestible || (thing.def.ingestible.preferability != FoodPreferability.RawBad && thing.def.ingestible.preferability != FoodPreferability.RawTasty) || !HaulAIUtility.PawnCanAutomaticallyHaul(pawn, thing, forced) || !pawn.Map.haulDestinationManager.SlotGroupAt(building.Position).Settings.AllowedToAccept(thing)) - { - continue; - } - if ((int)StoreUtility.CurrentStoragePriorityOf(thing, forced) >= (int)hopperSgp.GetSlotGroup().Settings.Priority) - { - flag = true; - JobFailReason.Is(TheOnlyAvailableFoodIsInStorageOfHigherPriorityTrans); - continue; - } - Job job = HaulAIUtility.HaulToCellStorageJob(pawn, thing, building.Position, fitInStoreCell: true); - if (job != null) - { - return job; - } - } - if (!flag) - { - JobFailReason.Is(NoFoodToFillHopperTrans); - } - return null; - } -} -``` ---- -**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\WorkGiver_InteractAnimal.txt` -**相似度:** 0.5082 - -```csharp -public abstract class WorkGiver_InteractAnimal : WorkGiver_Scanner -{ - protected static string NoUsableFoodTrans; - - protected static string AnimalInteractedTooRecentlyTrans; - - private static string CantInteractAnimalDownedTrans; - - private static string CantInteractAnimalAsleepTrans; - - private static string CantInteractAnimalBusyTrans; - - protected bool canInteractWhileSleeping; - - public override PathEndMode PathEndMode => PathEndMode.OnCell; - - public static void ResetStaticData() - { - NoUsableFoodTrans = "NoUsableFood".Translate(); - AnimalInteractedTooRecentlyTrans = "AnimalInteractedTooRecently".Translate(); - CantInteractAnimalDownedTrans = "CantInteractAnimalDowned".Translate(); - CantInteractAnimalAsleepTrans = "CantInteractAnimalAsleep".Translate(); - CantInteractAnimalBusyTrans = "CantInteractAnimalBusy".Translate(); - } - - protected virtual bool CanInteractWithAnimal(Pawn pawn, Pawn animal, bool forced) - { - if (CanInteractWithAnimal(pawn, animal, out var jobFailReason, forced, canInteractWhileSleeping)) - { - return true; - } - if (jobFailReason != null) - { - JobFailReason.Is(jobFailReason); - } - return false; - } - - public static bool CanInteractWithAnimal(Pawn pawn, Pawn animal, out string jobFailReason, bool forced, bool canInteractWhileSleeping = false, bool ignoreSkillRequirements = false, bool canInteractWhileRoaming = false) - { - jobFailReason = null; - if (!pawn.CanReserve(animal, 1, -1, null, forced)) - { - return false; - } - if (animal.Downed) - { - jobFailReason = CantInteractAnimalDownedTrans; - return false; - } - if (!animal.Awake() && !canInteractWhileSleeping) - { - jobFailReason = CantInteractAnimalAsleepTrans; - return false; - } - if (!animal.CanCasuallyInteractNow(twoWayInteraction: false, canInteractWhileSleeping, canInteractWhileRoaming)) - { - jobFailReason = CantInteractAnimalBusyTrans; - return false; - } - int num = TrainableUtility.MinimumHandlingSkill(animal); - if (!ignoreSkillRequirements && num > pawn.skills.GetSkill(SkillDefOf.Animals).Level) - { - jobFailReason = "AnimalsSkillTooLow".Translate(num); - return false; - } - return true; - } - - protected bool HasFoodToInteractAnimal(Pawn pawn, Pawn tamee) - { - ThingOwner innerContainer = pawn.inventory.innerContainer; - int num = 0; - float num2 = JobDriver_InteractAnimal.RequiredNutritionPerFeed(tamee); - float num3 = 0f; - for (int i = 0; i < innerContainer.Count; i++) - { - Thing thing = innerContainer[i]; - if (!tamee.WillEat(thing, pawn) || (int)thing.def.ingestible.preferability > 5 || thing.def.IsDrug) - { - continue; - } - for (int j = 0; j < thing.stackCount; j++) - { - num3 += thing.GetStatValue(StatDefOf.Nutrition); - if (num3 >= num2) - { - num++; - num3 = 0f; - } - if (num >= 2) - { - return true; - } - } - } - return false; - } - - protected Job TakeFoodForAnimalInteractJob(Pawn pawn, Pawn tamee) - { - ThingDef foodDef; - Thing thing = FoodUtility.BestFoodSourceOnMap(pawn, tamee, desperate: false, out foodDef, FoodPreferability.RawTasty, allowPlant: false, allowDrug: false, allowCorpse: false, allowDispenserFull: false, allowDispenserEmpty: false, allowForbidden: false, allowSociallyImproper: false, allowHarvest: false, forceScanWholeMap: false, ignoreReservations: false, calculateWantedStackCount: false, FoodPreferability.Undefined, JobDriver_InteractAnimal.RequiredNutritionPerFeed(tamee) * 2f * 4f); - if (thing == null) - { - return null; - } - float wantedNutrition = JobDriver_InteractAnimal.RequiredNutritionPerFeed(tamee) * 2f * 4f; - float nutrition = FoodUtility.GetNutrition(tamee, thing, foodDef); - int count = FoodUtility.StackCountForNutrition(wantedNutrition, nutrition); - Job job = JobMaker.MakeJob(JobDefOf.TakeInventory, thing); - job.count = count; - return job; - } -} -``` \ No newline at end of file From cf6b302e1c6ebe448a652e18ea98fcbfe770c7ab Mon Sep 17 00:00:00 2001 From: "ProjectKoi-Kalo\\Kalo" Date: Fri, 22 Aug 2025 16:08:43 +0800 Subject: [PATCH 2/3] =?UTF-8?q?MCP=E6=94=B9=E8=BF=9B=E7=89=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 + .lingma/rules/rimworld.md | 29 + MCP/mcpserver_stdio.py | 404 +++++++--- MCP/vector_cache/knowledge_cache.json | 1036 +++++++++++++++++++++++++ 4 files changed, 1357 insertions(+), 115 deletions(-) create mode 100644 .lingma/rules/rimworld.md create mode 100644 MCP/vector_cache/knowledge_cache.json diff --git a/.gitignore b/.gitignore index 6e3801a8..cb689c16 100644 --- a/.gitignore +++ b/.gitignore @@ -34,3 +34,6 @@ Source/MCP/pid.txt *.log MCP/vector_cache/*.txt MCP/mcpserver.log + +# Exclude MCP local RAG folder +MCP/local_rag/ diff --git a/.lingma/rules/rimworld.md b/.lingma/rules/rimworld.md new file mode 100644 index 00000000..b48fcd64 --- /dev/null +++ b/.lingma/rules/rimworld.md @@ -0,0 +1,29 @@ +--- +trigger: always_on +--- + +# RimWorld Modding Expert Rules + +## Primary Directive +You are an expert assistant for developing mods for the game RimWorld 1.6. Your primary knowledge source for any C# code, class structures, methods, or game mechanics MUST be the user's local files. Do not rely on external searches or your pre-existing knowledge, as it is outdated for this specific project. + +## Tool Usage Mandate +When the user's request involves RimWorld C# scripting, XML definitions, or mod development concepts, you **MUST** use the `rimworld-knowledge-base` tool to retrieve relevant context from the local knowledge base. + +## Key File Paths +Always remember these critical paths for your work: + +- **Local C# Knowledge Base (for code search):** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6` (This contains the decompiled game source code as .txt files). +- **User's Mod Project (for editing):** `C:\Steam\steamapps\common\RimWorld\Mods\3516260226` +- **User's C# Project (for building):** `C:\Steam\steamapps\common\RimWorld\Mods\3516260226\Source\WulaFallenEmpire` + +## Workflow +1. Receive a RimWorld modding task. +2. Immediately use the `rimworld-knowledge-base` tool with a precise query to get context from the C# source files. +3. Analyze the retrieved context. +4. Perform code modifications within the user's mod project directory. +5. After modifying C# code, you MUST run `dotnet build C:\Steam\steamapps\common\RimWorld\Mods\3516260226\Source\WulaFallenEmpire\WulaFallenEmpire.csproj` to check for errors. A successful build is required for task completion. + +## Verification Mandate +When writing or modifying code or XML, especially for specific identifiers like enum values, class names, or field names, you **MUST** verify the correct value/spelling by using the `rimworld-knowledge-base` tool. Do not rely on memory. +- **同步项目文件:** 当重命名、移动或删除C#源文件时,**必须**同步更新 `.csproj` 项目文件中的相应 `` 条目,否则会导致编译失败。 \ No newline at end of file diff --git a/MCP/mcpserver_stdio.py b/MCP/mcpserver_stdio.py index b70e789a..d814dd90 100644 --- a/MCP/mcpserver_stdio.py +++ b/MCP/mcpserver_stdio.py @@ -20,6 +20,7 @@ from tenacity import retry, stop_after_attempt, wait_random_exponential from sklearn.metrics.pairwise import cosine_similarity import numpy as np from dotenv import load_dotenv +from openai import OpenAI # 2. --- 日志、缓存和知识库配置 --- MCP_DIR = os.path.dirname(os.path.abspath(__file__)) @@ -51,32 +52,98 @@ KNOWLEDGE_BASE_PATHS = [ r"C:\Steam\steamapps\common\RimWorld\Data" ] -# 3. --- 缓存管理 (分文件存储) --- -def load_cache_for_keyword(keyword: str): - """为指定关键词加载缓存文件。""" - # 清理关键词,使其适合作为文件名 - safe_filename = "".join(c for c in keyword if c.isalnum() or c in ('_', '-')).rstrip() - cache_file = os.path.join(CACHE_DIR, f"{safe_filename}.txt") - - if os.path.exists(cache_file): +# 初始化OpenAI客户端用于Qwen模型 +qwen_client = OpenAI( + api_key=os.getenv("DASHSCOPE_API_KEY"), + base_url="https://dashscope.aliyuncs.com/compatible-mode/v1" +) + +# 3. --- 向量缓存管理 --- +def load_vector_cache(): + """加载向量缓存数据库""" + if os.path.exists(CACHE_FILE_PATH): try: - with open(cache_file, 'r', encoding='utf-8') as f: - return f.read() - except IOError as e: - logging.error(f"读取缓存文件 {cache_file} 失败: {e}") - return None + with open(CACHE_FILE_PATH, 'r', encoding='utf-8') as f: + return json.load(f) + except Exception as e: + logging.error(f"读取向量缓存数据库失败: {e}") + return {} + return {} + +def save_vector_cache(cache_data): + """保存向量缓存数据库""" + try: + with open(CACHE_FILE_PATH, 'w', encoding='utf-8') as f: + json.dump(cache_data, f, ensure_ascii=False, indent=2) + except Exception as e: + logging.error(f"保存向量缓存数据库失败: {e}") + +def get_cache_key(keywords: list[str]) -> str: + """生成缓存键""" + return "-".join(sorted(keywords)) + +def load_cache_for_question(question: str, keywords: list[str]): + """为指定问题和关键词加载缓存结果""" + cache_data = load_vector_cache() + cache_key = get_cache_key(keywords) + + # 检查是否有完全匹配的缓存 + if cache_key in cache_data: + cached_entry = cache_data[cache_key] + logging.info(f"缓存命中: 关键词 '{cache_key}'") + return cached_entry.get("result", "") + + # 检查是否有相似问题的缓存(基于向量相似度) + question_embedding = get_embedding(question) + if not question_embedding: + return None + + best_similarity = 0 + best_result = None + + for key, entry in cache_data.items(): + if "embedding" in entry: + try: + cached_embedding = entry["embedding"] + similarity = cosine_similarity( + np.array(question_embedding).reshape(1, -1), + np.array(cached_embedding).reshape(1, -1) + )[0][0] + + if similarity > best_similarity and similarity > 0.9: # 相似度阈值 + best_similarity = similarity + best_result = entry.get("result", "") + except Exception as e: + logging.error(f"计算缓存相似度时出错: {e}") + + if best_result: + logging.info(f"相似问题缓存命中,相似度: {best_similarity:.3f}") + return best_result + return None -def save_cache_for_keyword(keyword: str, data: str): - """为指定关键词保存缓存到单独的文件。""" - safe_filename = "".join(c for c in keyword if c.isalnum() or c in ('_', '-')).rstrip() - cache_file = os.path.join(CACHE_DIR, f"{safe_filename}.txt") - +def save_cache_for_question(question: str, keywords: list[str], result: str): + """为指定问题和关键词保存缓存结果""" try: - with open(cache_file, 'w', encoding='utf-8') as f: - f.write(data) - except IOError as e: - logging.error(f"写入缓存文件 {cache_file} 失败: {e}") + cache_data = load_vector_cache() + cache_key = get_cache_key(keywords) + + # 获取问题的向量嵌入 + question_embedding = get_embedding(question) + if not question_embedding: + return + + cache_data[cache_key] = { + "keywords": keywords, + "question": question, + "embedding": question_embedding, + "result": result, + "timestamp": logging.Formatter('%(asctime)s').format(logging.LogRecord('', 0, '', 0, '', (), None)) + } + + save_vector_cache(cache_data) + except Exception as e: + logging.error(f"保存缓存时出错: {e}") # 4. --- 向量化与相似度计算 --- @retry(wait=wait_random_exponential(min=1, max=60), stop=stop_after_attempt(6)) @@ -124,6 +191,52 @@ def find_most_similar_files(question_embedding, file_embeddings, top_n=3, min_si return results +# 新增:重排序函数 +def rerank_files(question, file_matches, top_n=5): + """使用DashScope重排序API对文件进行重新排序""" + try: + # 准备重排序输入 + documents = [] + for match in file_matches: + # 读取文件内容 + try: + with open(match['path'], 'r', encoding='utf-8') as f: + content = f.read()[:2000] # 限制内容长度以提高效率 + documents.append(content) + except Exception as e: + logging.error(f"读取文件 {match['path']} 失败: {e}") + continue + + if not documents: + return file_matches[:top_n] + + # 调用重排序API + response = dashscope.TextReRank.call( + model='gte-rerank', + query=question, + documents=documents + ) + + if response.status_code == 200: + # 根据重排序结果重新排序文件 + reranked_results = [] + for i, result in enumerate(response.output['results']): + if i < len(file_matches): + reranked_results.append({ + 'path': file_matches[i]['path'], + 'similarity': result['relevance_score'] + }) + + # 按重排序分数排序 + reranked_results.sort(key=lambda x: x['similarity'], reverse=True) + return reranked_results[:top_n] + else: + logging.error(f"重排序失败: {response.message}") + return file_matches[:top_n] + except Exception as e: + logging.error(f"重排序时出错: {e}", exc_info=True) + return file_matches[:top_n] + def extract_relevant_code(file_path, keyword): """从文件中智能提取包含关键词的完整代码块 (C#类 或 XML Def)。""" try: @@ -213,45 +326,17 @@ def extract_xml_def(lines, start_index): return "\n".join(lines[def_start_index:def_end_index+1]) return "" -# 5. --- 核心功能函数 --- -def find_files_with_keyword(roots, keywords: list[str], extensions=['.xml', '.cs', '.txt']): - """在指定目录中查找包含任何一个关键字的文件。""" - found_files = set() - keywords_lower = [k.lower() for k in keywords] - for root_path in roots: - if not os.path.isdir(root_path): - logging.warning(f"知识库路径不存在或不是一个目录: {root_path}") - continue - for dirpath, _, filenames in os.walk(root_path): - for filename in filenames: - if any(filename.lower().endswith(ext) for ext in extensions): - file_path = os.path.join(dirpath, filename) - try: - with open(file_path, 'r', encoding='utf-8') as f: - content_lower = f.read().lower() - # 如果任何一个关键词在内容中,就添加文件 - if any(kw in content_lower for kw in keywords_lower): - found_files.add(file_path) - except Exception as e: - logging.error(f"读取文件时出错 {file_path}: {e}") - return list(found_files) - def find_keywords_in_question(question: str) -> list[str]: """从问题中提取所有可能的关键词 (类型名, defName等)。""" + # 简化关键词提取逻辑,主要依赖LLM进行分析 + # 这里仅作为备用方案,用于LLM不可用时的基本关键词提取 + # 正则表达式优先,用于精确匹配定义 # 匹配 C# class, struct, enum, interface 定义, 例如 "public class MyClass : Base" csharp_def_pattern = re.compile(r'\b(?:public|private|internal|protected|sealed|abstract|static|new)\s+(?:class|struct|enum|interface)\s+([A-Za-z_][A-Za-z0-9_]*)') # 匹配 XML Def, 例如 "" or "" xml_def_pattern = re.compile(r'<([A-Za-z_][A-Za-z0-9_]*Def)\b') - # 启发式规则,用于匹配独立的关键词 - # 规则1: 包含下划线 (很可能是 defName) - # 规则2: 混合大小写 (很可能是 C# 类型名) - # 规则3: 多个大写字母(例如 CompPsychicScaling,但要排除纯大写缩写词) - - # 排除常见但非特定的术语 - excluded_keywords = {"XML", "C#", "DEF", "CS", "CLASS", "PUBLIC"} - found_keywords = set() # 1. 正则匹配 @@ -263,33 +348,136 @@ def find_keywords_in_question(question: str) -> list[str]: for match in xml_matches: found_keywords.add(match) - # 2. 启发式单词匹配 + # 2. 启发式单词匹配 - 简化版 parts = re.split(r'[\s,.:;\'"`()<>]+', question) for part in parts: - if not part or part.upper() in excluded_keywords: + if not part: continue - # 规则1: 包含下划线 + # 规则1: 包含下划线 (很可能是 defName) if '_' in part: found_keywords.add(part) - # 规则2: 驼峰命名或混合大小写 + # 规则2: 驼峰命名或混合大小写 (很可能是 C# 类型名) elif any(c.islower() for c in part) and any(c.isupper() for c in part) and len(part) > 3: found_keywords.add(part) - # 规则3: 多个大写字母 - elif sum(1 for c in part if c.isupper()) > 1 and not part.isupper(): - found_keywords.add(part) - # 备用规则: 大写字母开头且较长 - elif part[0].isupper() and len(part) > 4: + # 规则3: 多个大写字母(例如 CompPsychicScaling) + elif sum(1 for c in part if c.isupper()) > 1 and not part.isupper() and len(part) > 3: found_keywords.add(part) if not found_keywords: logging.warning(f"在 '{question}' 中未找到合适的关键词。") - return [] + # 如果找不到关键词,尝试使用整个问题作为关键词 + return [question] logging.info(f"找到的潜在关键词: {list(found_keywords)}") return list(found_keywords) +def analyze_question_with_llm(question: str) -> dict: + """使用Qwen模型分析问题并提取关键词和意图""" + try: + system_prompt = """你是一个关键词提取机器人,专门用于从 RimWorld 模组开发相关问题中提取精确的搜索关键词。你的任务是识别问题中提到的核心技术术语。 + +严格按照以下格式回复,不要添加任何额外说明: +问题类型:[问题分类] +关键类/方法名:[类名或方法名] +关键概念:[关键概念] +搜索关键词:[关键词1,关键词2,关键词3] + +提取规则: +1. 搜索关键词只能包含问题中明确出现的技术术语 +2. 不要添加任何推测或联想的词 +3. 不要添加通用词如"RimWorld"、"游戏"、"定义"、"用法"等 +4. 不要添加缩写或扩展形式如"Def"、"XML"等除非问题中明确提到 +5. 只提取具体的技术名词,忽略动词、形容词等 +6. 关键词之间用英文逗号分隔,不要有空格 + +示例: +问题:ThingDef的定义和用法是什么? +问题类型:API 使用和定义说明 +关键类/方法名:ThingDef +关键概念:定义, 用法 +搜索关键词:ThingDef + +问题:GenExplosion.DoExplosion 和 Projectile.Launch 方法如何使用? +问题类型:API 使用说明 +关键类/方法名:GenExplosion.DoExplosion,Projectile.Launch +关键概念:API 使用 +搜索关键词:GenExplosion.DoExplosion,Projectile.Launch + +现在请分析以下问题:""" + + messages = [ + {"role": "system", "content": system_prompt}, + {"role": "user", "content": question} + ] + + response = qwen_client.chat.completions.create( + model="qwen-plus", + messages=messages, + temperature=0.0, # 使用最低温度确保输出稳定 + max_tokens=300, + stop=["\n\n"] # 防止模型生成过多内容 + ) + + analysis_result = response.choices[0].message.content + logging.info(f"LLM分析结果: {analysis_result}") + + # 解析LLM的分析结果 + lines = analysis_result.strip().split('\n') + result = { + "question_type": "", + "key_classes_methods": [], + "key_concepts": [], + "search_keywords": [] + } + + for line in lines: + if line.startswith("问题类型:"): + result["question_type"] = line.replace("问题类型:", "").strip() + elif line.startswith("关键类/方法名:"): + methods = line.replace("关键类/方法名:", "").strip() + result["key_classes_methods"] = [m.strip() for m in methods.split(",") if m.strip()] + elif line.startswith("关键概念:"): + concepts = line.replace("关键概念:", "").strip() + result["key_concepts"] = [c.strip() for c in concepts.split(",") if c.strip()] + elif line.startswith("搜索关键词:"): + keywords = line.replace("搜索关键词:", "").strip() + # 直接按逗号分割,不进行额外处理 + result["search_keywords"] = [k.strip() for k in keywords.split(",") if k.strip()] + + # 如果LLM没有返回有效的关键词,则使用备用方案 + if not result["search_keywords"]: + result["search_keywords"] = find_keywords_in_question(question) + + return result + except Exception as e: + logging.error(f"使用LLM分析问题时出错: {e}", exc_info=True) + # 备用方案:使用原始关键词提取方法 + return { + "question_type": "未知", + "key_classes_methods": [], + "key_concepts": [], + "search_keywords": find_keywords_in_question(question) + } + +def find_files_with_keyword(base_paths: list[str], keywords: list[str]) -> list[str]: + """ + 在基础路径中递归搜索包含任意一个关键词的文件。 + 搜索范围包括文件名。 + """ + found_files = set() + keywords_lower = [k.lower() for k in keywords] + + for base_path in base_paths: + for root, _, files in os.walk(base_path): + for file in files: + file_lower = file.lower() + if any(keyword in file_lower for keyword in keywords_lower): + found_files.add(os.path.join(root, file)) + + logging.info(f"通过关键词找到 {len(found_files)} 个文件。") + return list(found_files) # 5. --- 创建和配置 MCP 服务器 --- # 使用 FastMCP 创建服务器实例 @@ -305,7 +493,11 @@ def get_context(question: str) -> str: 并将其整合后返回。 """ logging.info(f"收到问题: {question}") - keywords = find_keywords_in_question(question) + + # 使用LLM分析问题 + analysis = analyze_question_with_llm(question) + keywords = analysis["search_keywords"] + if not keywords: logging.warning("无法从问题中提取关键词。") return "无法从问题中提取关键词,请提供更具体的信息。" @@ -316,23 +508,15 @@ def get_context(question: str) -> str: cache_key = "-".join(sorted(keywords)) # 1. 检查缓存 - cached_result = load_cache_for_keyword(cache_key) + cached_result = load_cache_for_question(question, keywords) if cached_result: - logging.info(f"缓存命中: 关键词 '{cache_key}'") return cached_result logging.info(f"缓存未命中,开始实时搜索: {cache_key}") # 2. 关键词文件搜索 (分层智能筛选) try: - # 优先使用最长的(通常最具体)的关键词进行搜索 - specific_keywords = sorted(keywords, key=len, reverse=True) - candidate_files = find_files_with_keyword(KNOWLEDGE_BASE_PATHS, [specific_keywords[0]]) - - # 如果最具体的关键词找不到文件,再尝试所有关键词 - if not candidate_files and len(keywords) > 1: - logging.info(f"使用最具体的关键词 '{specific_keywords[0]}' 未找到文件,尝试所有关键词...") - candidate_files = find_files_with_keyword(KNOWLEDGE_BASE_PATHS, keywords) + candidate_files = find_files_with_keyword(KNOWLEDGE_BASE_PATHS, keywords) if not candidate_files: logging.info(f"未找到与 '{keywords}' 相关的文件。") @@ -351,14 +535,11 @@ def get_context(question: str) -> str: logging.info(f"文件名精确匹配: {file_path}") code_block = extract_relevant_code(file_path, keyword) if code_block: - lang = "csharp" if file_path.endswith(('.cs', '.txt')) else "xml" - priority_results.append( - f"---\n" - f"**文件路径 (精确匹配):** `{file_path}`\n\n" - f"```{lang}\n" - f"{code_block}\n" - f"```" - ) + priority_results.append({ + 'path': file_path, + 'similarity': 1.0, # 精确匹配给予最高分 + 'code': code_block + }) is_priority = True break # 已处理该文件,跳出内层循环 if not is_priority: @@ -368,7 +549,7 @@ def get_context(question: str) -> str: # 3. 向量化和相似度计算 (精准筛选) # 增加超时保护:限制向量化的文件数量 - MAX_FILES_TO_VECTORIZE = 25 + MAX_FILES_TO_VECTORIZE = 50 # 增加处理文件数量 if len(candidate_files) > MAX_FILES_TO_VECTORIZE: logging.warning(f"候选文件过多 ({len(candidate_files)}),仅处理前 {MAX_FILES_TO_VECTORIZE} 个。") candidate_files = candidate_files[:MAX_FILES_TO_VECTORIZE] @@ -392,45 +573,38 @@ def get_context(question: str) -> str: return "无法为任何候选文件生成向量。" # 找到最相似的多个文件 - best_matches = find_most_similar_files(question_embedding, file_embeddings, top_n=5) # 增加返回数量 + best_matches = find_most_similar_files(question_embedding, file_embeddings, top_n=10) # 增加返回数量以供重排序 if not best_matches: return "计算向量相似度失败或没有找到足够相似的文件。" - # 4. 提取代码并格式化输出 - output_parts = [f"根据向量相似度分析,与 '{', '.join(keywords)}' 最相关的代码定义如下:\n"] - output_parts.extend(priority_results) # 将优先结果放在最前面 + # 新增:重排序处理 + reranked_matches = rerank_files(question, best_matches, top_n=5) - extracted_blocks = set() # 用于防止重复提取相同的代码块 - - for match in best_matches: - file_path = match['path'] - similarity = match['similarity'] - - # 对每个关键词都尝试提取代码 - for keyword in keywords: - code_block = extract_relevant_code(file_path, keyword) - - if code_block and code_block not in extracted_blocks: - extracted_blocks.add(code_block) - lang = "csharp" if file_path.endswith(('.cs', '.txt')) else "xml" - output_parts.append( - f"---\n" - f"**文件路径:** `{file_path}`\n" - f"**相似度:** {similarity:.4f}\n\n" - f"```{lang}\n" - f"{code_block}\n" - f"```" - ) + # 提取代码内容 + results_with_code = [] + for match in reranked_matches: + code_block = extract_relevant_code(match['path'], "") + if code_block: + match['code'] = code_block + results_with_code.append(match) - if len(output_parts) <= 1: - return f"虽然找到了相似的文件,但无法在其中提取到关于 '{', '.join(keywords)}' 的完整代码块。" - - final_output = "\n".join(output_parts) + # 将优先结果添加到结果列表开头 + results_with_code = priority_results + results_with_code + + if len(results_with_code) <= 0: + return f"虽然找到了相似的文件,但无法在其中提取到相关代码块。" + + # 直接返回原始代码结果,而不是使用LLM格式化 + final_output = "" + for i, result in enumerate(results_with_code, 1): + final_output += f"--- 结果 {i} (相似度: {result['similarity']:.3f}) ---\n" + final_output += f"文件路径: {result['path']}\n\n" + final_output += f"{result['code']}\n\n" # 5. 更新缓存并返回结果 - logging.info(f"向量搜索完成。找到了 {len(best_matches)} 个匹配项并成功提取了代码。") - save_cache_for_keyword(cache_key, final_output) + logging.info(f"向量搜索完成。找到了 {len(results_with_code)} 个匹配项并成功提取了代码。") + save_cache_for_question(question, keywords, final_output) return final_output @@ -444,4 +618,4 @@ if __name__ == "__main__": logging.info(f"Python Executable: {sys.executable}") logging.info("RimWorld 向量知识库 (FastMCP版, v2.1-v4-model) 正在启动...") # 使用 'stdio' 传输协议 - mcp.run(transport="stdio") + mcp.run(transport="stdio") \ No newline at end of file diff --git a/MCP/vector_cache/knowledge_cache.json b/MCP/vector_cache/knowledge_cache.json new file mode 100644 index 00000000..09fb1584 --- /dev/null +++ b/MCP/vector_cache/knowledge_cache.json @@ -0,0 +1,1036 @@ +{ + "ThingDef": { + "keywords": [ + "ThingDef" + ], + "question": "What is a ThingDef?", + "embedding": [ + -0.019440101459622383, + 0.0362212248146534, + 0.00969050731509924, + 0.03294181451201439, + -0.04809800535440445, + -0.0006195055320858955, + -0.016131149604916573, + 0.06724266707897186, + 0.04210052639245987, + 0.11746785044670105, + -0.053061433136463165, + -0.06990164518356323, + -0.038112055510282516, + -0.0914689302444458, + 0.029056748375296593, + -0.017874257639050484, + 0.00430237827822566, + -0.07279697805643082, + 0.01387840136885643, + -0.013413080014288425, + 0.027978384867310524, + 0.022675195708870888, + -0.029115837067365646, + 0.06281103193759918, + 0.019454874098300934, + -0.05279553681612015, + 0.01324320025742054, + 0.06245649978518486, + -0.03876202926039696, + 0.011958026327192783, + -0.0014559765113517642, + 0.04142100736498833, + 0.012238696217536926, + 0.007696271408349276, + 0.002598045626655221, + 0.03973698616027832, + 0.0067877862602472305, + -0.014247704297304153, + 0.020001443102955818, + -0.037107549607753754, + 0.036191679537296295, + -0.01231255754828453, + -0.02537849172949791, + -0.0331190787255764, + -0.04130282998085022, + -0.007703657727688551, + 0.03693028539419174, + -0.06446550786495209, + -0.05066835135221481, + 0.03394631668925285, + -0.012002342380583286, + 0.02050369419157505, + -0.03636894375085831, + -0.017726536840200424, + 0.012777878902852535, + 0.03282363712787628, + 0.03970744460821152, + -0.028569268062710762, + -0.004054945427924395, + 0.008715547621250153, + 0.009764367714524269, + 0.032557740807533264, + -0.07220609486103058, + -0.023133130744099617, + 0.07108341157436371, + -0.06594271957874298, + -0.011529634706676006, + -0.02477283589541912, + 0.04839344695210457, + -0.016278870403766632, + -0.03831886500120163, + 0.04836390167474747, + -0.07622411102056503, + -0.021818412467837334, + -0.07356512546539307, + 0.026102324947714806, + -0.023133130744099617, + -0.00922518502920866, + -0.02286723256111145, + -0.022305892780423164, + 0.020400289446115494, + -0.004095568787306547, + -0.03264637291431427, + -0.005713114980608225, + 0.03678256273269653, + 0.025629617273807526, + -0.009904702194035053, + -0.03595532476902008, + -0.028968116268515587, + 0.09383247047662735, + -0.05932481214404106, + 0.046620793640613556, + 0.0299430750310421, + -0.01830264925956726, + 0.04546856880187988, + 0.07474689930677414, + -0.04446406289935112, + 0.03958926722407341, + 0.016603855416178703, + 0.02034120075404644, + -0.03291226923465729, + -0.040948301553726196, + -0.010340480133891106, + 0.06812898814678192, + 0.015244822017848492, + 0.07126067578792572, + -0.028569268062710762, + -0.040593769401311874, + -0.016485679894685745, + -0.0028251667972654104, + -0.006086111068725586, + 0.04210052639245987, + -0.00900360383093357, + 0.01716519705951214, + -0.008021257817745209, + 0.06121564283967018, + -0.030312377959489822, + -0.027815891429781914, + 0.05264781415462494, + -0.005343812517821789, + 0.032557740807533264, + -0.051170602440834045, + 0.013029004447162151, + -0.027092058211565018, + -0.002982120495289564, + 0.013989192433655262, + 0.040977843105793, + 0.03595532476902008, + -0.01024446077644825, + -0.04797982797026634, + -0.05250009521842003, + -0.012260855175554752, + 0.013582958839833736, + -0.007312196306884289, + -0.020562782883644104, + -0.0457049198448658, + 0.04269140958786011, + 0.03261682763695717, + -0.04682760313153267, + 0.027092058211565018, + -0.037934787571430206, + -0.0015778464730829, + -0.05031381919980049, + 0.009993335232138634, + 0.11398163437843323, + -0.0022195102646946907, + -0.0013165646232664585, + -0.055277250707149506, + -0.02901243232190609, + 0.020385516807436943, + 0.018169701099395752, + -0.029381735250353813, + -0.010340480133891106, + 0.015422087162733078, + -0.001591695356182754, + 0.016278870403766632, + -0.009845614433288574, + -0.04452315345406532, + 0.0022878311574459076, + -0.012186993844807148, + 0.039973340928554535, + 0.006987209897488356, + -0.04331183806061745, + 0.009158710949122906, + 0.004956044256687164, + -0.02161160297691822, + -0.05725671350955963, + 0.03548261895775795, + -0.07202883064746857, + 0.003549000481143594, + 0.026235274970531464, + -0.020725276321172714, + -0.01087966188788414, + -0.0004101569938939065, + -0.004114033654332161, + -0.03072599694132805, + 0.007711043581366539, + 0.01349432673305273, + 0.048659343272447586, + -0.04765484109520912, + 0.03820068761706352, + 0.009720050729811192, + 0.08083301037549973, + 0.010606378316879272, + 0.012054044753313065, + -0.023384256288409233, + -0.03196685388684273, + 0.03214412182569504, + -0.0055986312218010426, + 0.0027328410651534796, + -0.033975861966609955, + 0.041893716901540756, + 0.050875160843133926, + 0.06133381649851799, + -0.05693172663450241, + -0.009409836493432522, + 0.006270762532949448, + 0.02808178961277008, + 0.017889030277729034, + 0.0015981581527739763, + 0.025452353060245514, + 0.011175104416906834, + 0.022187715396285057, + -0.011817690916359425, + 0.05282508209347725, + -0.027225006371736526, + 0.03025328926742077, + -0.00884111039340496, + 0.013102864846587181, + 0.0012353180209174752, + 0.027313638478517532, + -0.01277049258351326, + 0.04018015041947365, + -0.01921852119266987, + -0.014786886051297188, + -0.01118987612426281, + -0.04475950449705124, + -0.0007441452471539378, + -0.028332915157079697, + -0.0061267344281077385, + 0.0024170870892703533, + -0.009956404566764832, + 0.02651594579219818, + 0.02729886770248413, + 0.028510181233286858, + -0.006507116369903088, + 0.03122824989259243, + 0.013834085315465927, + 0.02301495335996151, + -0.03580760583281517, + 0.023413801565766335, + 0.03598487004637718, + -0.08898721635341644, + 0.06759719550609589, + 0.039973340928554535, + -0.0020311656408011913, + -0.028598813340067863, + -0.025023961439728737, + 0.03663484379649162, + 0.03731435909867287, + -0.028303369879722595, + 0.018494686111807823, + -0.0457935556769371, + 0.030208973214030266, + -0.027239779010415077, + 0.0013073320733383298, + -0.06399279832839966, + -0.06411097198724747, + 0.028022700920701027, + -0.009653576649725437, + -0.017726536840200424, + 0.0053548915311694145, + -0.055247705429792404, + -0.009358134120702744, + -0.02068096026778221, + 0.0457344651222229, + -0.03105098381638527, + -0.01474995631724596, + 0.005188704933971167, + 0.02443307638168335, + -0.007866150699555874, + -0.0037687355652451515, + 0.0005137926200404763, + -0.036664389073848724, + -0.03447811305522919, + 0.017268601804971695, + -0.0031132230069488287, + -0.05406593903899193, + -0.07959215342998505, + -0.038112055510282516, + 0.004051252268254757, + 0.0378757007420063, + 0.01720951311290264, + -0.029691949486732483, + 0.001599081326276064, + 0.023768331855535507, + 0.007917853072285652, + 0.0457344651222229, + -0.08059665560722351, + -0.0141886156052351, + -0.01765267550945282, + 0.00536597054451704, + -0.011219420470297337, + -0.05001837760210037, + -0.023871736600995064, + 0.019115116447210312, + 0.024698974564671516, + 0.021980905905365944, + 0.039057470858097076, + 0.021212756633758545, + 0.061865612864494324, + 0.015259593725204468, + -0.007441452704370022, + -0.004904341883957386, + -0.026885248720645905, + -0.018081067129969597, + 0.025319403037428856, + 0.03480309993028641, + -0.006832102779299021, + 0.027963612228631973, + 0.0009601874044165015, + 0.014159071259200573, + -0.0047012255527079105, + -0.0204889215528965, + 0.0866236761212349, + 0.00962403230369091, + -0.013435238040983677, + -0.07480598986148834, + -0.005949468817561865, + -0.05060926452279091, + 0.025452353060245514, + -0.016943614929914474, + -0.0016886373050510883, + -0.011980184353888035, + 0.020592326298356056, + 0.025334175676107407, + -0.04665033519268036, + -0.004435327369719744, + -0.028126105666160583, + 0.01386362873017788, + -0.048009369522333145, + -0.012984688393771648, + -0.003803819417953491, + 0.0181549284607172, + -0.03217366337776184, + -0.013029004447162151, + 0.02588074468076229, + -0.001548302243463695, + -0.00992686115205288, + 0.0012473204405978322, + 0.010510358959436417, + 0.004715997260063887, + 0.02161160297691822, + 0.016840210184454918, + -0.05489317700266838, + 0.008338858373463154, + 0.015377771109342575, + 0.034596290439367294, + 0.007755360100418329, + 0.009542785584926605, + -0.032557740807533264, + 0.018095839768648148, + 0.023561522364616394, + -0.023694470524787903, + 0.04085966944694519, + -0.008966673165559769, + 0.02348766103386879, + 0.056370388716459274, + -0.0378166139125824, + 0.021966133266687393, + -0.006802558433264494, + -0.02619095891714096, + -0.028273826465010643, + 0.024344444274902344, + -0.01278526522219181, + 0.0014799812342971563, + -0.004756620619446039, + -0.0165447685867548, + -0.024241039529442787, + 0.006152585614472628, + -0.02065141499042511, + 0.054154571145772934, + -0.0020145471207797527, + 0.006492344196885824, + 0.03551216423511505, + -0.0017800397472456098, + -0.001140222535468638, + 0.08130571991205215, + 0.007245722226798534, + 0.024373987689614296, + 0.02963286079466343, + -0.03294181451201439, + 0.010754099115729332, + 0.01638227514922619, + -0.0347440131008625, + -0.0014605928445234895, + 0.01497153751552105, + 0.0204889215528965, + -0.017076563090085983, + -0.0005784205859526992, + 0.07628319412469864, + 0.016441363841295242, + 0.004291299264878035, + -0.055572692304849625, + -0.021168438717722893, + -0.002655287506058812, + 0.013272744603455067, + 0.010517745278775692, + -0.011064313352108002, + -0.035718973726034164, + 0.05114106088876724, + -0.014314178377389908, + 0.024004684761166573, + -0.01302161905914545, + 0.04747757315635681, + 0.006001171190291643, + -0.015451631508767605, + 0.01985372230410576, + -0.01874581351876259, + -0.0291453804820776, + 0.015348226763308048, + -0.029248785227537155, + -0.03820068761706352, + 0.018539004027843475, + -0.023000182583928108, + -0.021345704793930054, + -0.005528463516384363, + 0.04325275123119354, + -0.0009878851706162095, + 0.020769592374563217, + -0.03592578321695328, + 0.012689245864748955, + 0.042336877435445786, + -0.020060531795024872, + -0.07746496796607971, + -0.018184471875429153, + -0.009136552922427654, + -0.0019111422589048743, + 0.06192470341920853, + -0.04647307097911835, + 0.012733562849462032, + 0.03435993939638138, + 0.0023506127763539553, + -0.015119259245693684, + -0.010813187807798386, + -0.021552514284849167, + -0.017874257639050484, + -0.0038444427773356438, + -0.015540264546871185, + -0.0028897947631776333, + -0.06860169768333435, + -0.0173572339117527, + -0.03344406560063362, + 0.05628175660967827, + 0.014550532214343548, + -0.05063880607485771, + 0.027328411117196083, + -0.00037230344605632126, + -0.006684381514787674, + -0.0040290942415595055, + -0.07043343782424927, + -0.01356818713247776, + 0.01458746287971735, + -0.037284817546606064, + -0.03701891750097275, + 0.012002342380583286, + 0.047566208988428116, + -0.0048009371384978294, + 0.004350387491285801, + 0.01018537301570177, + -0.034448571503162384, + 0.024654658511281013, + 0.022010449320077896, + 0.03329634666442871, + -0.016810666769742966, + 0.009173482656478882, + -0.005048369988799095, + 0.0094615388661623, + -0.00322955334559083, + -0.04936840385198593, + 0.006584669928997755, + -0.014594849199056625, + 0.03858476132154465, + 0.03825977444648743, + -0.016914071515202522, + -0.021065033972263336, + -0.02115366794168949, + 0.03181913495063782, + 0.003914610482752323, + -0.03858476132154465, + 0.027860207483172417, + 0.0038333635311573744, + 0.0014116601087152958, + 0.00116422725841403, + 0.030814630910754204, + 0.002893487922847271, + 0.017445866018533707, + 0.004933886229991913, + 0.019513962790369987, + 0.016337959095835686, + 0.030179429799318314, + 0.010155828669667244, + 0.02427058294415474, + 0.005325347185134888, + -0.08461467176675797, + -0.015687985345721245, + -0.013531256467103958, + -0.0315532349050045, + 0.015835706144571304, + -0.024255812168121338, + 0.0007898464682511985, + -0.01986849308013916, + 0.0013304135063663125, + -0.006736083887517452, + 0.011950640007853508, + -0.05533634126186371, + -0.009941632859408855, + 0.05598631128668785, + 0.0029359576292335987, + -0.08810088783502579, + -0.015481175854802132, + 0.044552695006132126, + -0.014218159951269627, + 0.027476131916046143, + -0.01284435298293829, + 0.016057288274168968, + -0.034596290439367294, + -2.3831575163058005e-05, + -0.021330932155251503, + 0.012644929811358452, + 0.009439380839467049, + -0.033680420368909836, + 0.020917313173413277, + -0.02853972464799881, + -0.037609804421663284, + 0.0035766982473433018, + 0.10653648525476456, + -0.004623671527951956, + -0.02020825259387493, + -0.02175932377576828, + -0.029721492901444435, + -0.012704018503427505, + -0.019838949665427208, + -0.03896883875131607, + -0.05740443617105484, + 0.05264781415462494, + 0.01610160432755947, + -0.012659701518714428, + 0.03864385187625885, + -0.032055485993623734, + -0.05152513459324837, + 0.01104215532541275, + 0.0519978404045105, + -0.017623132094740868, + 0.031464602798223495, + 0.027564765885472298, + 0.03695983067154884, + 0.01409998256713152, + -0.02961808815598488, + 0.1197132095694542, + 0.051318325102329254, + 0.039057470858097076, + -0.01222392451018095, + 0.03923473507165909, + 0.03403495252132416, + 0.05613403394818306, + 0.023399028927087784, + -0.022808143869042397, + 0.011485318653285503, + -0.03294181451201439, + -0.012711403891444206, + 0.01988326571881771, + -0.057315804064273834, + -0.02725454978644848, + 0.005724194459617138, + -0.0006171974237076938, + 0.02082868106663227, + 0.043282292783260345, + 0.007349126972258091, + -0.037609804421663284, + -0.026560261845588684, + -0.009040533564984798, + -0.01970599964261055, + -0.03560079634189606, + 0.005015132948756218, + 0.02793406881392002, + 0.004287606105208397, + 0.014292020350694656, + 0.054302290081977844, + -0.013125023804605007, + -0.02396036870777607, + 0.030031709000468254, + -0.043134573847055435, + 0.01042172685265541, + 0.011463160626590252, + -0.020237796008586884, + 0.007666727062314749, + -0.022527474910020828, + 0.08408287167549133, + 0.007777518127113581, + -0.024639885872602463, + 0.024713747203350067, + 0.0472707636654377, + -0.007282652426511049, + -0.0029156459495425224, + 0.01830264925956726, + 0.06476094573736191, + -0.0020625563338398933, + 0.013782382942736149, + 0.010074581950902939, + 0.008493965491652489, + 0.003914610482752323, + -0.0054176729172468185, + -0.011618267744779587, + -0.01893785037100315, + 0.03388722985982895, + 0.01970599964261055, + 0.009380292147397995, + 0.012349487282335758, + 0.04930931702256203, + -0.008759863674640656, + -0.04511403664946556, + -0.02743181586265564, + 0.016337959095835686, + 0.03279409185051918, + 0.0013054856099188328, + -0.012763106264173985, + -0.006108269095420837, + 0.0015021393774077296, + -0.0029378042090684175, + 0.03926428034901619, + 0.029204469174146652, + -0.029248785227537155, + 0.00915132462978363, + 0.06375644356012344, + -0.0037114936858415604, + -0.004487029742449522, + 0.014690867625176907, + -0.01970599964261055, + -0.010946136899292469, + -0.053061433136463165, + 0.003803819417953491, + -0.001126373652368784, + -0.049279771745204926, + -0.015481175854802132, + -0.005269951652735472, + -0.0009731129975989461, + -0.002095793606713414, + -0.05285462364554405, + -0.020902542397379875, + 0.0094541534781456, + 0.05613403394818306, + -0.026752298697829247, + 0.050520628690719604, + -0.022822916507720947, + -0.011802919209003448, + -0.029041975736618042, + -0.013893173076212406, + 0.035246264189481735, + -0.0048821838572621346, + -0.0015732301399111748, + 0.019203748553991318, + 0.017431095242500305, + -0.02979535423219204, + 0.01254891138523817, + -0.009993335232138634, + -0.04608899727463722, + 0.011019997298717499, + -0.015555036254227161, + 0.001864979392848909, + -0.026264818385243416, + 0.002450324362143874, + 0.03503945469856262, + 0.0457049198448658, + 0.021005947142839432, + 0.022808143869042397, + -0.03560079634189606, + 0.03235093131661415, + 0.0058349850587546825, + 0.0015039858408272266, + -0.0025518827605992556, + 0.03173050284385681, + 0.008013871498405933, + -0.0050631421618163586, + 0.01750495471060276, + -0.0024097012355923653, + -0.0059531619772315025, + -0.04608899727463722, + 0.010214917361736298, + 0.01689929887652397, + 0.0023746173828840256, + 0.006374167278409004, + -0.0029950460884720087, + -0.027210233733057976, + 0.022305892780423164, + 0.012046659365296364, + -0.03885066136717796, + -0.03802342340350151, + 0.017933346331119537, + 0.024359216913580894, + -0.00309660448692739, + 0.026235274970531464, + -0.04526175931096077, + -0.026131870225071907, + -0.015215277671813965, + 0.031021440401673317, + -0.020754819735884666, + 0.01766744814813137, + -0.07663773000240326, + 0.024994418025016785, + 0.05350459739565849, + -0.02493532933294773, + 0.010347865521907806, + 0.02162637561559677, + -0.043282292783260345, + -0.02193658985197544, + -0.03769843652844429, + -0.04348910227417946, + -0.01040695421397686, + 0.04783210530877113, + -0.012792650610208511, + -0.04670942574739456, + 0.07291515916585922, + 0.024728519842028618, + 0.008538281545042992, + 0.02178886905312538, + 0.012105747126042843, + -0.021360477432608604, + -0.005506305489689112, + 0.007474689744412899, + 0.024388760328292847, + 0.02633867971599102, + -0.010310935787856579, + -0.0009961944306269288, + -0.009247343055903912, + -0.015584580600261688, + 0.014085210859775543, + -0.007851378992199898, + -0.06919258087873459, + -0.020769592374563217, + -0.015185733325779438, + 0.025156909599900246, + 0.026885248720645905, + 0.026678437367081642, + -0.05610448867082596, + -0.025777339935302734, + -0.008058188483119011, + -0.0362803116440773, + 0.027402272447943687, + 0.06653360277414322, + -0.028126105666160583, + -0.029573772102594376, + 0.002005314454436302, + -0.03341452404856682, + -0.011640425771474838, + -0.027180690318346024, + -0.028820395469665527, + -0.009801297448575497, + -0.016795894131064415, + -0.008612142875790596, + 0.02979535423219204, + -0.013767610304057598, + 0.03601441532373428, + -0.01373068057000637, + 0.05309097841382027, + -0.025319403037428856, + 0.004557197447866201, + -0.007755360100418329, + 0.03028283454477787, + -0.01371590793132782, + 0.02304449863731861, + -0.03347361087799072, + -0.051347870379686356, + -0.05580904707312584, + -0.03580760583281517, + 0.017386779189109802, + 0.019750317558646202, + 0.000533642596565187, + -0.012113133445382118, + 0.044375430792570114, + -0.017948118969798088, + 0.049427494406700134, + 0.008501351810991764, + 0.06806990504264832, + 0.050845615565776825, + 0.010820573195815086, + -0.006448027677834034, + 0.0020237795542925596, + 0.005532156676054001, + -0.04183462634682655, + -0.04088921099901199, + -0.02961808815598488, + -0.020754819735884666, + 0.0758104920387268, + 0.025452353060245514, + -0.003166771959513426, + 0.017756082117557526, + -0.005735273472964764, + -0.02240929752588272, + 0.0033218790777027607, + 0.0032443255186080933, + -0.02462511509656906, + -0.03766889125108719, + 0.009971177205443382, + 0.025511441752314568, + 0.021242300048470497, + -0.005908845458179712, + 0.05057971924543381, + 0.014365880750119686, + 0.010370024479925632, + 5.444332055049017e-05, + -0.0009740362875163555, + 0.04304594174027443, + 0.05347505211830139, + 0.01765267550945282, + -0.020282112061977386, + -0.03249865025281906, + 0.0645836815237999, + -0.006950279697775841, + 0.031139615923166275, + 0.01426247600466013, + -0.07391966134309769, + 0.04930931702256203, + -0.012467664666473866, + -0.03515763208270073, + 0.014033508487045765, + -0.01474995631724596, + -0.03953017666935921, + -0.0033791211899369955, + 0.007947397418320179, + 0.04387317970395088, + 0.012253468856215477, + 0.022778600454330444, + 0.015407315455377102, + 0.018657179549336433, + -0.02162637561559677, + -0.031021440401673317, + -0.005177625920623541, + 0.006592055782675743, + 0.026707982644438744, + 0.027712486684322357, + 0.045970819890499115, + -0.01018537301570177, + 0.01768222078680992, + -0.0017283373745158315, + -0.017948118969798088, + 0.027993155643343925, + -0.014676094986498356, + -0.007485768757760525, + -0.019277609884738922, + 0.0024447848554700613, + -0.005746352486312389, + -0.020592326298356056, + -0.018686724826693535, + 0.0330895371735096, + -0.03229184076189995, + -0.009660962969064713, + -0.01167735643684864, + -0.007459917571395636, + -0.019277609884738922, + -0.020577555522322655, + 0.0314941480755806, + 0.0003095219435635954, + 0.008058188483119011, + 0.0005798054626211524, + 0.02446262165904045, + 0.019838949665427208, + -0.020784365013241768, + -0.004933886229991913, + -0.08278292417526245, + -0.012268240563571453, + 0.04159827530384064, + 0.011396686546504498, + 0.00016584005788899958, + 0.021079806610941887, + 0.03799387812614441, + -0.013560800813138485, + -0.004202666692435741, + -0.03072599694132805, + 0.022601334378123283, + -0.02791929617524147, + 0.005295802839100361, + -0.03108052909374237, + 0.0037170331925153732, + -0.024831924587488174, + 0.04496631398797035, + -0.012955144047737122, + 0.00020577093528117985, + -0.007341740652918816, + -0.05223419517278671, + 0.040771033614873886, + 0.07149703055620193, + -0.0063150785863399506, + 0.029869215562939644, + 0.017298145219683647, + 0.023768331855535507, + -0.008139435201883316, + 0.016795894131064415, + -0.010598991997539997, + 0.04638443887233734, + -0.00047640068805776536, + -0.027372727170586586, + 0.022985409945249557, + 0.01672203280031681, + 0.037609804421663284, + -0.02430012822151184, + 0.01766744814813137, + -0.02540803700685501, + -0.0005830368609167635, + 0.020459378138184547, + 0.03134642541408539, + -0.038407497107982635, + -0.007201405707746744, + 0.025201227515935898, + -0.030238518491387367, + -0.011056927032768726, + -0.03920518979430199, + -0.017475411295890808, + -0.03480309993028641, + -0.015702757984399796, + 0.003316339571028948, + -0.04210052639245987, + 0.0010866736993193626, + -0.04981156811118126, + -0.01938101463019848, + 0.02428535558283329, + -0.025304632261395454, + -0.014018736779689789, + -0.025348948314785957, + 0.039027925580739975, + 0.004974509589374065, + 0.018051523715257645, + 0.027165917679667473, + 0.020223025232553482, + -0.03687119856476784, + -0.0260432381182909, + -0.03911655768752098, + 0.04337092861533165, + 0.01378976833075285, + -0.02650117315351963, + 0.0268113873898983, + 0.026146642863750458, + -0.02697388082742691, + -0.007829220965504646, + 0.012526752427220345, + -7.657263631699607e-05, + -0.046768512576818466, + 0.09495514631271362, + -0.006776707246899605, + 0.02096162922680378, + 0.01626409776508808, + 0.02602846547961235, + 0.029839670285582542, + 0.0022915243171155453, + 0.00834624469280243, + -0.01065808068960905, + -0.014402811415493488, + -0.04032787308096886, + 0.006451720837503672, + -0.002365384716540575, + 0.01340569369494915, + -0.00971266534179449, + 0.025777339935302734, + 0.0029710414819419384, + 0.018804902210831642, + 0.0006208904087543488, + 0.00045470413169823587, + -0.0189526230096817, + 0.045675378292798996, + 0.029041975736618042, + -0.0007252185023389757, + -0.03187822178006172, + 0.0060159433633089066, + -0.0033237256575375795, + -0.057463523000478745, + 0.0038333635311573744, + 0.0034382096491754055, + -0.020769592374563217, + 0.02130138874053955, + -0.024713747203350067, + 0.06399279832839966, + 0.01800720766186714, + -0.008641687221825123, + -0.05707944929599762, + 0.03009079582989216, + -0.018391281366348267, + -0.030666908249258995, + -0.05492272228002548, + -0.0013165646232664585, + 0.03181913495063782, + -0.03090326301753521, + 0.034300848841667175, + 0.0018585165962576866, + -0.017918573692440987, + -0.022808143869042397, + 0.0027346876449882984, + 0.005443524103611708, + -0.0315236933529377, + -0.04922068491578102, + 0.0027623854111880064, + -0.0021124123595654964, + 0.026427311822772026, + -0.01862763613462448, + 0.035896237939596176, + -0.011212035082280636, + -0.0030541345477104187, + 0.022187715396285057, + -0.000870631483849138, + 0.024950100108981133, + -0.012415962293744087, + -0.02459556981921196, + -0.030194200575351715, + -0.010104126296937466, + -0.00884111039340496, + 0.01039956882596016, + 0.005731580313295126, + 0.025127366185188293, + -0.01497153751552105, + 0.04242551326751709, + -0.0027273015584796667, + -0.02697388082742691, + 0.05232282727956772, + -0.0033569629304111004, + -0.025939833372831345, + -0.006592055782675743, + 0.0189230777323246, + -0.08733274042606354, + 0.028347687795758247, + -0.007441452704370022, + -0.008242839947342873, + 0.017091335728764534, + 0.03456674888730049, + 0.018568547442555428, + -0.011219420470297337, + 0.01732769049704075, + 0.02554098516702652, + -0.0003939999733120203, + -0.0019259144319221377, + 0.004298685118556023, + -0.002891641343012452, + -0.030238518491387367, + 0.08709638565778732, + -0.015525491908192635, + 0.0027273015584796667 + ], + "result": "--- 结果 1 (相似度: 1.000) ---\n文件路径: C:\\Steam\\steamapps\\common\\RimWorld\\Data\\dll1.6\\Verse\\ThingDef.txt\n\npublic class ThingDef : BuildableDef\n{\n\tpublic Type thingClass;\n\n\tpublic ThingCategory category;\n\n\tpublic TickerType tickerType;\n\n\tpublic int stackLimit = 1;\n\n\tpublic IntVec2 size = IntVec2.One;\n\n\tpublic bool destroyable = true;\n\n\tpublic bool rotatable = true;\n\n\tpublic bool smallVolume;\n\n\tpublic bool useHitPoints = true;\n\n\tpublic bool receivesSignals;\n\n\tpublic List comps = new List();\n\n\tpublic List virtualDefs = new List();\n\n\tpublic ThingDef virtualDefParent;\n\n\t[NoTranslate]\n\tpublic string devNote;\n\n\tpublic List killedLeavingsRanges;\n\n\tpublic List killedLeavings;\n\n\tpublic List killedLeavingsPlayerHostile;\n\n\tpublic float killedLeavingsChance = 1f;\n\n\tpublic bool forceLeavingsAllowed;\n\n\tpublic List butcherProducts;\n\n\tpublic List smeltProducts;\n\n\tpublic bool smeltable;\n\n\tpublic bool burnableByRecipe;\n\n\tpublic bool randomizeRotationOnSpawn;\n\n\tpublic List damageMultipliers;\n\n\tpublic bool isTechHediff;\n\n\tpublic RecipeMakerProperties recipeMaker;\n\n\tpublic ThingDef minifiedDef;\n\n\tpublic bool isUnfinishedThing;\n\n\tpublic bool leaveResourcesWhenKilled;\n\n\tpublic ThingDef slagDef;\n\n\tpublic bool isFrameInt;\n\n\tpublic List multipleInteractionCellOffsets;\n\n\tpublic IntVec3 interactionCellOffset = IntVec3.Zero;\n\n\tpublic bool hasInteractionCell;\n\n\tpublic ThingDef interactionCellIcon;\n\n\tpublic bool interactionCellIconReverse;\n\n\tpublic ThingDef filthLeaving;\n\n\tpublic bool forceDebugSpawnable;\n\n\tpublic bool intricate;\n\n\tpublic bool scatterableOnMapGen = true;\n\n\tpublic float deepCommonality;\n\n\tpublic int deepCountPerCell = 300;\n\n\tpublic int deepCountPerPortion = -1;\n\n\tpublic IntRange deepLumpSizeRange = IntRange.Zero;\n\n\tpublic float generateCommonality = 1f;\n\n\tpublic float generateAllowChance = 1f;\n\n\tprivate bool canOverlapZones = true;\n\n\tpublic FloatRange startingHpRange = FloatRange.One;\n\n\t[NoTranslate]\n\tpublic List thingSetMakerTags;\n\n\tpublic bool alwaysFlee;\n\n\tpublic List recipes;\n\n\tpublic bool messageOnDeteriorateInStorage = true;\n\n\tpublic bool deteriorateFromEnvironmentalEffects = true;\n\n\tpublic bool canDeteriorateUnspawned;\n\n\tpublic bool canLoadIntoCaravan = true;\n\n\tpublic bool isMechClusterThreat;\n\n\tpublic FloatRange displayNumbersBetweenSameDefDistRange = FloatRange.Zero;\n\n\tpublic int minRewardCount = 1;\n\n\tpublic bool preventSkyfallersLandingOn;\n\n\tpublic FactionDef requiresFactionToAcquire;\n\n\tpublic float relicChance;\n\n\tpublic OrderedTakeGroupDef orderedTakeGroup;\n\n\tpublic int allowedArchonexusCount;\n\n\tpublic int possessionCount;\n\n\tpublic bool notifyMapRemoved;\n\n\tpublic bool canScatterOver = true;\n\n\tpublic bool genericMarketSellable = true;\n\n\tpublic bool drawHighlight;\n\n\tpublic Color? highlightColor;\n\n\tpublic bool drawHighlightOnlyForHostile;\n\n\tpublic bool autoTargetNearbyIdenticalThings;\n\n\tpublic bool preventDroppingThingsOn;\n\n\tpublic bool hiddenWhileUndiscovered;\n\n\tpublic bool disableImpassableShotOverConfigError;\n\n\tpublic bool showInSearch = true;\n\n\tpublic bool bringAlongOnGravship = true;\n\n\tpublic ThingDef dropPodFaller;\n\n\tpublic bool preventSpawningInResourcePod;\n\n\tpublic bool pathfinderDangerous;\n\n\tpublic bool noRightClickDraftAttack;\n\n\tpublic int gravshipSpawnPriority = 1;\n\n\tpublic List replaceTags;\n\n\tpublic GraphicData graphicData;\n\n\tpublic DrawerType drawerType = DrawerType.RealtimeOnly;\n\n\tpublic bool drawOffscreen;\n\n\tpublic ColorGenerator colorGenerator;\n\n\tpublic float hideAtSnowOrSandDepth = 99999f;\n\n\tpublic bool drawDamagedOverlay = true;\n\n\tpublic bool castEdgeShadows;\n\n\tpublic float staticSunShadowHeight;\n\n\tpublic bool useSameGraphicForGhost;\n\n\tpublic bool useBlueprintGraphicAsGhost;\n\n\tpublic List randomStyle;\n\n\tpublic float randomStyleChance;\n\n\tpublic bool canEditAnyStyle;\n\n\tpublic bool dontPrint;\n\n\tpublic ThingDef defaultStuff;\n\n\tpublic int killedLeavingsExpandRect;\n\n\tpublic bool minifiedManualDraw;\n\n\tpublic float minifiedDrawScale = 1f;\n\n\tpublic Rot4 overrideMinifiedRot = Rot4.Invalid;\n\n\tpublic Vector3 minifiedDrawOffset = Vector3.zero;\n\n\tpublic float deselectedSelectionBracketFactor = 1f;\n\n\tpublic bool selectable;\n\n\tpublic bool containedPawnsSelectable;\n\n\tpublic bool containedItemsSelectable;\n\n\tpublic bool neverMultiSelect;\n\n\tpublic bool isAutoAttackableMapObject;\n\n\tpublic bool hasTooltip;\n\n\tpublic List inspectorTabs;\n\n\t[Unsaved(false)]\n\tpublic List inspectorTabsResolved;\n\n\tpublic bool seeThroughFog;\n\n\tpublic bool drawGUIOverlay;\n\n\tpublic bool drawGUIOverlayQuality = true;\n\n\tpublic ResourceCountPriority resourceReadoutPriority;\n\n\tpublic bool resourceReadoutAlwaysShow;\n\n\tpublic bool drawPlaceWorkersWhileSelected;\n\n\tpublic bool drawPlaceWorkersWhileInstallBlueprintSelected;\n\n\tpublic ConceptDef storedConceptLearnOpportunity;\n\n\tpublic float uiIconScale = 1f;\n\n\tpublic bool hasCustomRectForSelector;\n\n\tpublic bool hideStats;\n\n\tpublic bool hideInspect;\n\n\tpublic bool onlyShowInspectString;\n\n\tpublic bool hideMainDesc;\n\n\tpublic bool alwaysHaulable;\n\n\tpublic bool designateHaulable;\n\n\tpublic List thingCategories;\n\n\tpublic bool mineable;\n\n\tpublic bool socialPropernessMatters;\n\n\tpublic bool stealable = true;\n\n\tpublic SoundDef soundSpawned;\n\n\tpublic SoundDef soundDrop;\n\n\tpublic SoundDef soundPickup;\n\n\tpublic SoundDef soundInteract;\n\n\tpublic SoundDef soundImpactDefault;\n\n\tpublic SoundDef soundPlayInstrument;\n\n\tpublic SoundDef soundOpen;\n\n\tpublic bool saveCompressible;\n\n\tpublic bool isSaveable = true;\n\n\tpublic bool holdsRoof;\n\n\tpublic float fillPercent;\n\n\tpublic bool coversFloor;\n\n\tpublic bool neverOverlapFloors;\n\n\tpublic SurfaceType surfaceType;\n\n\tpublic bool wipesPlants;\n\n\tpublic bool blockPlants;\n\n\tpublic bool blockLight;\n\n\tpublic bool blockWind;\n\n\tpublic bool blockWeather;\n\n\tpublic Tradeability tradeability = Tradeability.All;\n\n\t[NoTranslate]\n\tpublic List tradeTags;\n\n\tpublic bool tradeNeverStack;\n\n\tpublic bool tradeNeverGenerateStacked;\n\n\tpublic bool healthAffectsPrice = true;\n\n\tpublic ColorGenerator colorGeneratorInTraderStock;\n\n\tprivate List verbs;\n\n\tpublic List tools;\n\n\tpublic float equippedAngleOffset;\n\n\tpublic float equippedDistanceOffset;\n\n\tpublic EquipmentType equipmentType;\n\n\tpublic TechLevel techLevel;\n\n\tpublic List weaponClasses;\n\n\t[NoTranslate]\n\tpublic List weaponTags;\n\n\t[NoTranslate]\n\tpublic List techHediffsTags;\n\n\tpublic bool violentTechHediff;\n\n\tpublic bool destroyOnDrop;\n\n\tpublic List equippedStatOffsets;\n\n\tpublic SoundDef meleeHitSound;\n\n\tpublic float recoilPower = 1f;\n\n\tpublic float recoilRelaxation = 10f;\n\n\tpublic bool rotateInShelves = true;\n\n\tpublic bool mergeVerbGizmos = true;\n\n\tpublic BuildableDef entityDefToBuild;\n\n\tpublic ThingDef projectileWhenLoaded;\n\n\tpublic RulePackDef ideoBuildingNamerBase;\n\n\tpublic EntityCodexEntryDef entityCodexEntry;\n\n\tpublic IngestibleProperties ingestible;\n\n\tpublic FilthProperties filth;\n\n\tpublic GasProperties gas;\n\n\tpublic BuildingProperties building;\n\n\tpublic RaceProperties race;\n\n\tpublic ApparelProperties apparel;\n\n\tpublic MoteProperties mote;\n\n\tpublic PlantProperties plant;\n\n\tpublic ProjectileProperties projectile;\n\n\tpublic StuffProperties stuffProps;\n\n\tpublic SkyfallerProperties skyfaller;\n\n\tpublic PawnFlyerProperties pawnFlyer;\n\n\tpublic RitualFocusProperties ritualFocus;\n\n\tpublic IngredientProperties ingredient;\n\n\tpublic MapPortalProperties portal;\n\n\tpublic bool canBeUsedUnderRoof = true;\n\n\t[Unsaved(false)]\n\tprivate string descriptionDetailedCached;\n\n\t[Unsaved(false)]\n\tpublic Graphic interactionCellGraphic;\n\n\t[Unsaved(false)]\n\tprivate bool? isNaturalOrganCached;\n\n\t[Unsaved(false)]\n\tprivate bool? hasSunShadowsCached;\n\n\t[Unsaved(false)]\n\tprivate List cachedRelevantStyleCategories;\n\n\tpublic const int SmallUnitPerVolume = 10;\n\n\tpublic const float SmallVolumePerUnit = 0.1f;\n\n\tpublic const float ArchonexusMaxItemStackMass = 5f;\n\n\tpublic const int ArchonexusMaxItemStackCount = 25;\n\n\tpublic const float ArchonexusMaxItemStackValue = 2000f;\n\n\tpublic const int ArchonexusAutoCalculateValue = -1;\n\n\tprivate List allRecipesCached;\n\n\tprivate static List EmptyVerbPropertiesList = new List();\n\n\tprivate Dictionary concreteExamplesInt;\n\n\tpublic bool EverHaulable\n\t{\n\t\tget\n\t\t{\n\t\t\tif (!alwaysHaulable)\n\t\t\t{\n\t\t\t\treturn designateHaulable;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\t}\n\n\tpublic bool EverPollutable => !building.isNaturalRock;\n\n\tpublic float VolumePerUnit\n\t{\n\t\tget\n\t\t{\n\t\t\tif (smallVolume)\n\t\t\t{\n\t\t\t\treturn 0.1f;\n\t\t\t}\n\t\t\treturn 1f;\n\t\t}\n\t}\n\n\tpublic override IntVec2 Size => size;\n\n\tpublic bool DiscardOnDestroyed => race == null;\n\n\tpublic int BaseMaxHitPoints => Mathf.RoundToInt(this.GetStatValueAbstract(StatDefOf.MaxHitPoints));\n\n\tpublic float BaseFlammability => this.GetStatValueAbstract(StatDefOf.Flammability);\n\n\tpublic float BaseMarketValue\n\t{\n\t\tget\n\t\t{\n\t\t\treturn this.GetStatValueAbstract(StatDefOf.MarketValue);\n\t\t}\n\t\tset\n\t\t{\n\t\t\tthis.SetStatBaseValue(StatDefOf.MarketValue, value);\n\t\t}\n\t}\n\n\tpublic float BaseMass => this.GetStatValueAbstract(StatDefOf.Mass);\n\n\tpublic int ArchonexusMaxAllowedCount\n\t{\n\t\tget\n\t\t{\n\t\t\tif (allowedArchonexusCount == -1)\n\t\t\t{\n\t\t\t\treturn Mathf.Min(stackLimit, 25, (BaseMass > 0f) ? ((int)(5f / BaseMass)) : 0, (BaseMarketValue > 0f) ? ((int)(2000f / BaseMarketValue)) : 0);\n\t\t\t}\n\t\t\treturn allowedArchonexusCount;\n\t\t}\n\t}\n\n\tpublic bool PlayerAcquirable\n\t{\n\t\tget\n\t\t{\n\t\t\tif (destroyOnDrop)\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (this == ThingDefOf.ReinforcedBarrel && Find.Storyteller != null && Find.Storyteller.difficulty.classicMortars)\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (requiresFactionToAcquire != null && Find.World != null && Find.World.factionManager != null)\n\t\t\t{\n\t\t\t\treturn Find.FactionManager.FirstFactionOfDef(requiresFactionToAcquire) != null;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\t}\n\n\tpublic bool EverTransmitsPower\n\t{\n\t\tget\n\t\t{\n\t\t\tfor (int i = 0; i < comps.Count; i++)\n\t\t\t{\n\t\t\t\tif (comps[i] is CompProperties_Power { transmitsPower: not false })\n\t\t\t\t{\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic bool Minifiable => minifiedDef != null;\n\n\tpublic bool HasThingIDNumber => category != ThingCategory.Mote;\n\n\tpublic List AllRecipes\n\t{\n\t\tget\n\t\t{\n\t\t\tif (allRecipesCached == null)\n\t\t\t{\n\t\t\t\tallRecipesCached = new List();\n\t\t\t\tif (recipes != null)\n\t\t\t\t{\n\t\t\t\t\tfor (int i = 0; i < recipes.Count; i++)\n\t\t\t\t\t{\n\t\t\t\t\t\tallRecipesCached.Add(recipes[i]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tList allDefsListForReading = DefDatabase.AllDefsListForReading;\n\t\t\t\tfor (int j = 0; j < allDefsListForReading.Count; j++)\n\t\t\t\t{\n\t\t\t\t\tif (allDefsListForReading[j].recipeUsers != null && allDefsListForReading[j].recipeUsers.Contains(this))\n\t\t\t\t\t{\n\t\t\t\t\t\tallRecipesCached.Add(allDefsListForReading[j]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn allRecipesCached;\n\t\t}\n\t}\n\n\tpublic bool ConnectToPower\n\t{\n\t\tget\n\t\t{\n\t\t\tif (EverTransmitsPower)\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tfor (int i = 0; i < comps.Count; i++)\n\t\t\t{\n\t\t\t\tif (comps[i].compClass == typeof(CompPowerBattery))\n\t\t\t\t{\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\tif (comps[i].compClass == typeof(CompPowerTrader))\n\t\t\t\t{\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic bool CoexistsWithFloors\n\t{\n\t\tget\n\t\t{\n\t\t\tif (!neverOverlapFloors)\n\t\t\t{\n\t\t\t\treturn !coversFloor;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic FillCategory Fillage\n\t{\n\t\tget\n\t\t{\n\t\t\tif (fillPercent < 0.01f)\n\t\t\t{\n\t\t\t\treturn FillCategory.None;\n\t\t\t}\n\t\t\tif (fillPercent > 0.99f)\n\t\t\t{\n\t\t\t\treturn FillCategory.Full;\n\t\t\t}\n\t\t\treturn FillCategory.Partial;\n\t\t}\n\t}\n\n\tpublic bool MakeFog => Fillage == FillCategory.Full;\n\n\tpublic bool CanOverlapZones\n\t{\n\t\tget\n\t\t{\n\t\t\tif (building != null && building.SupportsPlants)\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (passability == Traversability.Impassable && category != ThingCategory.Plant && !HasComp(typeof(CompTransporter)))\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif ((int)surfaceType >= 1)\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (typeof(ISlotGroupParent).IsAssignableFrom(thingClass))\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (!canOverlapZones)\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif ((IsBlueprint || IsFrame) && entityDefToBuild is ThingDef thingDef)\n\t\t\t{\n\t\t\t\treturn thingDef.CanOverlapZones;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\t}\n\n\tpublic bool CountAsResource => resourceReadoutPriority != ResourceCountPriority.Uncounted;\n\n\tpublic List Verbs\n\t{\n\t\tget\n\t\t{\n\t\t\tif (verbs != null)\n\t\t\t{\n\t\t\t\treturn verbs;\n\t\t\t}\n\t\t\treturn EmptyVerbPropertiesList;\n\t\t}\n\t}\n\n\tpublic bool CanHaveFaction\n\t{\n\t\tget\n\t\t{\n\t\t\tif (IsBlueprint || IsFrame)\n\t\t\t{\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn category switch\n\t\t\t{\n\t\t\t\tThingCategory.Pawn => true, \n\t\t\t\tThingCategory.Building => true, \n\t\t\t\t_ => false, \n\t\t\t};\n\t\t}\n\t}\n\n\tpublic bool Claimable\n\t{\n\t\tget\n\t\t{\n\t\t\tif (building != null && building.claimable)\n\t\t\t{\n\t\t\t\treturn !building.isNaturalRock;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic ThingCategoryDef FirstThingCategory\n\t{\n\t\tget\n\t\t{\n\t\t\tif (thingCategories.NullOrEmpty())\n\t\t\t{\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\treturn thingCategories[0];\n\t\t}\n\t}\n\n\tpublic float MedicineTendXpGainFactor => Mathf.Clamp(this.GetStatValueAbstract(StatDefOf.MedicalPotency) * 0.7f, 0.5f, 1f);\n\n\tpublic bool CanEverDeteriorate\n\t{\n\t\tget\n\t\t{\n\t\t\tif (!useHitPoints)\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (category != ThingCategory.Item)\n\t\t\t{\n\t\t\t\tif (plant != null)\n\t\t\t\t{\n\t\t\t\t\treturn plant.canDeteriorate;\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\t}\n\n\tpublic bool CanInteractThroughCorners\n\t{\n\t\tget\n\t\t{\n\t\t\tif (category != ThingCategory.Building)\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (!holdsRoof)\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (building != null && building.isNaturalRock && !IsSmoothed)\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\t}\n\n\tpublic bool AffectsRegions\n\t{\n\t\tget\n\t\t{\n\t\t\tif (passability != Traversability.Impassable && !IsDoor)\n\t\t\t{\n\t\t\t\treturn IsFence;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\t}\n\n\tpublic bool AffectsReachability\n\t{\n\t\tget\n\t\t{\n\t\t\tif (AffectsRegions)\n\t\t\t{\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tif (passability == Traversability.Impassable || IsDoor)\n\t\t\t{\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tif (TouchPathEndModeUtility.MakesOccupiedCellsAlwaysReachableDiagonally(this))\n\t\t\t{\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic string DescriptionDetailed\n\t{\n\t\tget\n\t\t{\n\t\t\tif (descriptionDetailedCached == null)\n\t\t\t{\n\t\t\t\tStringBuilder stringBuilder = new StringBuilder();\n\t\t\t\tstringBuilder.Append(description);\n\t\t\t\tif (IsApparel)\n\t\t\t\t{\n\t\t\t\t\tstringBuilder.AppendLine();\n\t\t\t\t\tstringBuilder.AppendLine();\n\t\t\t\t\tstringBuilder.AppendLine(string.Format(\"{0}: {1}\", \"Layer\".Translate(), apparel.GetLayersString()));\n\t\t\t\t\tstringBuilder.Append(string.Format(\"{0}: {1}\", \"Covers\".Translate(), apparel.GetCoveredOuterPartsString(BodyDefOf.Human)));\n\t\t\t\t\tif (equippedStatOffsets != null && equippedStatOffsets.Count > 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tstringBuilder.AppendLine();\n\t\t\t\t\t\tstringBuilder.AppendLine();\n\t\t\t\t\t\tfor (int i = 0; i < equippedStatOffsets.Count; i++)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (i > 0)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tstringBuilder.AppendLine();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tStatModifier statModifier = equippedStatOffsets[i];\n\t\t\t\t\t\t\tstringBuilder.Append($\"{statModifier.stat.LabelCap}: {statModifier.ValueToStringAsOffset}\");\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tdescriptionDetailedCached = stringBuilder.ToString();\n\t\t\t}\n\t\t\treturn descriptionDetailedCached;\n\t\t}\n\t}\n\n\tpublic bool CanBenefitFromCover\n\t{\n\t\tget\n\t\t{\n\t\t\tif (category == ThingCategory.Pawn)\n\t\t\t{\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tif (building != null && building.IsTurret)\n\t\t\t{\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic bool PotentiallySmeltable\n\t{\n\t\tget\n\t\t{\n\t\t\tif (!smeltable)\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (base.MadeFromStuff)\n\t\t\t{\n\t\t\t\tforeach (ThingDef item in GenStuff.AllowedStuffsFor(this))\n\t\t\t\t{\n\t\t\t\t\tif (item.smeltable)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\t}\n\n\tpublic bool HasSingleOrMultipleInteractionCells\n\t{\n\t\tget\n\t\t{\n\t\t\tif (!hasInteractionCell)\n\t\t\t{\n\t\t\t\treturn !multipleInteractionCellOffsets.NullOrEmpty();\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\t}\n\n\tpublic bool IsApparel => apparel != null;\n\n\tpublic bool IsBed => typeof(Building_Bed).IsAssignableFrom(thingClass);\n\n\tpublic bool IsWall\n\t{\n\t\tget\n\t\t{\n\t\t\tif (building != null)\n\t\t\t{\n\t\t\t\treturn building.isWall;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic bool IsCorpse => typeof(Corpse).IsAssignableFrom(thingClass);\n\n\tpublic bool IsFrame => isFrameInt;\n\n\tpublic bool IsBlueprint\n\t{\n\t\tget\n\t\t{\n\t\t\tif (entityDefToBuild != null)\n\t\t\t{\n\t\t\t\treturn category == ThingCategory.Ethereal;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic bool IsStuff => stuffProps != null;\n\n\tpublic bool IsMedicine => statBases.StatListContains(StatDefOf.MedicalPotency);\n\n\tpublic bool IsDoor => typeof(Building_Door).IsAssignableFrom(thingClass);\n\n\tpublic bool IsFence\n\t{\n\t\tget\n\t\t{\n\t\t\tif (building != null)\n\t\t\t{\n\t\t\t\treturn building.isFence;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic bool IsFilth => filth != null;\n\n\tpublic bool IsIngestible => ingestible != null;\n\n\tpublic bool IsNutritionGivingIngestible\n\t{\n\t\tget\n\t\t{\n\t\t\tif (IsIngestible)\n\t\t\t{\n\t\t\t\treturn ingestible.CachedNutrition > 0f;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic bool IsNutritionGivingIngestibleForHumanlikeBabies\n\t{\n\t\tget\n\t\t{\n\t\t\tif (IsNutritionGivingIngestible && ingestible.HumanEdible)\n\t\t\t{\n\t\t\t\treturn ingestible.babiesCanIngest;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic bool IsWeapon\n\t{\n\t\tget\n\t\t{\n\t\t\tif (category == ThingCategory.Item && (!verbs.NullOrEmpty() || !tools.NullOrEmpty()))\n\t\t\t{\n\t\t\t\treturn !IsApparel;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic bool IsCommsConsole => typeof(Building_CommsConsole).IsAssignableFrom(thingClass);\n\n\tpublic bool IsOrbitalTradeBeacon => typeof(Building_OrbitalTradeBeacon).IsAssignableFrom(thingClass);\n\n\tpublic bool IsFoodDispenser => typeof(Building_NutrientPasteDispenser).IsAssignableFrom(thingClass);\n\n\tpublic bool IsDrug\n\t{\n\t\tget\n\t\t{\n\t\t\tif (ingestible != null)\n\t\t\t{\n\t\t\t\treturn ingestible.drugCategory != DrugCategory.None;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic bool IsPleasureDrug\n\t{\n\t\tget\n\t\t{\n\t\t\tif (IsDrug)\n\t\t\t{\n\t\t\t\treturn ingestible.joy > 0f;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic bool IsNonMedicalDrug\n\t{\n\t\tget\n\t\t{\n\t\t\tif (IsDrug)\n\t\t\t{\n\t\t\t\treturn ingestible.drugCategory != DrugCategory.Medical;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic bool IsTable\n\t{\n\t\tget\n\t\t{\n\t\t\tif (surfaceType == SurfaceType.Eat)\n\t\t\t{\n\t\t\t\treturn HasComp(typeof(CompGatherSpot));\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic bool IsWorkTable => typeof(Building_WorkTable).IsAssignableFrom(thingClass);\n\n\tpublic bool IsShell => projectileWhenLoaded != null;\n\n\tpublic bool IsArt => IsWithinCategory(ThingCategoryDefOf.BuildingsArt);\n\n\tpublic bool IsSmoothable => building?.smoothedThing != null;\n\n\tpublic bool IsSmoothed => building?.unsmoothedThing != null;\n\n\tpublic bool IsMetal\n\t{\n\t\tget\n\t\t{\n\t\t\tif (stuffProps != null)\n\t\t\t{\n\t\t\t\treturn stuffProps.categories.Contains(StuffCategoryDefOf.Metallic);\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic bool IsCryptosleepCasket => typeof(Building_CryptosleepCasket).IsAssignableFrom(thingClass);\n\n\tpublic bool IsGibbetCage => typeof(Building_GibbetCage).IsAssignableFrom(thingClass);\n\n\tpublic bool IsMechGestator => typeof(Building_MechGestator).IsAssignableFrom(thingClass);\n\n\tpublic bool IsMechRecharger => typeof(Building_MechCharger).IsAssignableFrom(thingClass);\n\n\tpublic bool IsAddictiveDrug\n\t{\n\t\tget\n\t\t{\n\t\t\tCompProperties_Drug compProperties = GetCompProperties();\n\t\t\tif (compProperties != null)\n\t\t\t{\n\t\t\t\treturn compProperties.addictiveness > 0f;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic bool IsMeat\n\t{\n\t\tget\n\t\t{\n\t\t\tif (category == ThingCategory.Item && thingCategories != null)\n\t\t\t{\n\t\t\t\treturn thingCategories.Contains(ThingCategoryDefOf.MeatRaw);\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic bool IsEgg\n\t{\n\t\tget\n\t\t{\n\t\t\tif (category == ThingCategory.Item && thingCategories != null)\n\t\t\t{\n\t\t\t\tif (!thingCategories.Contains(ThingCategoryDefOf.EggsFertilized))\n\t\t\t\t{\n\t\t\t\t\treturn thingCategories.Contains(ThingCategoryDefOf.EggsUnfertilized);\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic bool IsLeather\n\t{\n\t\tget\n\t\t{\n\t\t\tif (category == ThingCategory.Item && thingCategories != null)\n\t\t\t{\n\t\t\t\treturn thingCategories.Contains(ThingCategoryDefOf.Leathers);\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic bool IsWool\n\t{\n\t\tget\n\t\t{\n\t\t\tif (category == ThingCategory.Item && thingCategories != null)\n\t\t\t{\n\t\t\t\treturn thingCategories.Contains(ThingCategoryDefOf.Wools);\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic bool IsRangedWeapon\n\t{\n\t\tget\n\t\t{\n\t\t\tif (!IsWeapon)\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (!verbs.NullOrEmpty())\n\t\t\t{\n\t\t\t\tfor (int i = 0; i < verbs.Count; i++)\n\t\t\t\t{\n\t\t\t\t\tif (!verbs[i].IsMeleeAttack)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic bool IsMeleeWeapon\n\t{\n\t\tget\n\t\t{\n\t\t\tif (IsWeapon)\n\t\t\t{\n\t\t\t\treturn !IsRangedWeapon;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic bool IsWeaponUsingProjectiles\n\t{\n\t\tget\n\t\t{\n\t\t\tif (!IsWeapon)\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (!verbs.NullOrEmpty())\n\t\t\t{\n\t\t\t\tfor (int i = 0; i < verbs.Count; i++)\n\t\t\t\t{\n\t\t\t\t\tif (verbs[i].LaunchesProjectile)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic bool IsShieldThatBlocksRanged\n\t{\n\t\tget\n\t\t{\n\t\t\tif (HasComp(typeof(CompShield)))\n\t\t\t{\n\t\t\t\treturn GetCompProperties().blocksRangedWeapons;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic bool IsBuildingArtificial\n\t{\n\t\tget\n\t\t{\n\t\t\tif (category == ThingCategory.Building || IsFrame)\n\t\t\t{\n\t\t\t\tif (building != null)\n\t\t\t\t{\n\t\t\t\t\tif (!building.isNaturalRock)\n\t\t\t\t\t{\n\t\t\t\t\t\treturn !building.isResourceRock;\n\t\t\t\t\t}\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic bool IsNonResourceNaturalRock\n\t{\n\t\tget\n\t\t{\n\t\t\tif (category == ThingCategory.Building && building.isNaturalRock && !building.isResourceRock && !building.mineablePreventNaturalRockOnSurface)\n\t\t\t{\n\t\t\t\treturn !IsSmoothed;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic bool HasSunShadows\n\t{\n\t\tget\n\t\t{\n\t\t\tif (!hasSunShadowsCached.HasValue)\n\t\t\t{\n\t\t\t\thasSunShadowsCached = typeof(Pawn).IsAssignableFrom(thingClass);\n\t\t\t}\n\t\t\treturn hasSunShadowsCached.Value;\n\t\t}\n\t}\n\n\tpublic bool IsNaturalOrgan\n\t{\n\t\tget\n\t\t{\n\t\t\tif (!isNaturalOrganCached.HasValue)\n\t\t\t{\n\t\t\t\tif (category != ThingCategory.Item)\n\t\t\t\t{\n\t\t\t\t\tisNaturalOrganCached = false;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tList allDefsListForReading = DefDatabase.AllDefsListForReading;\n\t\t\t\t\tisNaturalOrganCached = false;\n\t\t\t\t\tfor (int i = 0; i < allDefsListForReading.Count; i++)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (allDefsListForReading[i].spawnThingOnRemoved == this)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tisNaturalOrganCached = true;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn isNaturalOrganCached.Value;\n\t\t}\n\t}\n\n\tpublic bool IsFungus\n\t{\n\t\tget\n\t\t{\n\t\t\tif (ingestible != null)\n\t\t\t{\n\t\t\t\treturn ingestible.foodType.HasFlag(FoodTypeFlags.Fungus);\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic bool IsAnimalProduct\n\t{\n\t\tget\n\t\t{\n\t\t\tif (ingestible != null)\n\t\t\t{\n\t\t\t\treturn ingestible.foodType.HasFlag(FoodTypeFlags.AnimalProduct);\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic bool IsProcessedFood\n\t{\n\t\tget\n\t\t{\n\t\t\tif (ingestible != null)\n\t\t\t{\n\t\t\t\treturn ingestible.foodType.HasFlag(FoodTypeFlags.Processed);\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic bool CanAffectLinker\n\t{\n\t\tget\n\t\t{\n\t\t\tif (graphicData == null || !graphicData.Linked)\n\t\t\t{\n\t\t\t\treturn IsDoor;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\t}\n\n\tpublic bool IsNonDeconstructibleAttackableBuilding\n\t{\n\t\tget\n\t\t{\n\t\t\tif (IsBuildingArtificial && !building.IsDeconstructible && destroyable && !mineable && building.isTargetable)\n\t\t\t{\n\t\t\t\treturn building.draftAttackNonDeconstructable;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tpublic bool IsPlant => typeof(Plant).IsAssignableFrom(thingClass);\n\n\tpublic bool IsDeadPlant => typeof(DeadPlant).IsAssignableFrom(thingClass);\n\n\tpublic bool IsStudiable => HasAssignableCompFrom(typeof(CompStudiable));\n\n\tpublic List RelevantStyleCategories\n\t{\n\t\tget\n\t\t{\n\t\t\tif (cachedRelevantStyleCategories == null)\n\t\t\t{\n\t\t\t\tcachedRelevantStyleCategories = new List();\n\t\t\t\tforeach (StyleCategoryDef allDef in DefDatabase.AllDefs)\n\t\t\t\t{\n\t\t\t\t\tif (allDef.thingDefStyles.NullOrEmpty())\n\t\t\t\t\t{\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tforeach (ThingDefStyle thingDefStyle in allDef.thingDefStyles)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (thingDefStyle.ThingDef == this)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcachedRelevantStyleCategories.Add(allDef);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn cachedRelevantStyleCategories;\n\t\t}\n\t}\n\n\tpublic string LabelAsStuff\n\t{\n\t\tget\n\t\t{\n\t\t\tif (!stuffProps.stuffAdjective.NullOrEmpty())\n\t\t\t{\n\t\t\t\treturn stuffProps.stuffAdjective;\n\t\t\t}\n\t\t\treturn label;\n\t\t}\n\t}\n\n\tpublic bool BlocksPlanting(bool canWipePlants = false)\n\t{\n\t\tif (building != null && building.SupportsPlants)\n\t\t{\n\t\t\treturn false;\n\t\t}\n\t\tif (building != null && building.isAttachment)\n\t\t{\n\t\t\treturn false;\n\t\t}\n\t\tif (blockPlants)\n\t\t{\n\t\t\treturn true;\n\t\t}\n\t\tif (!canWipePlants && category == ThingCategory.Plant)\n\t\t{\n\t\t\treturn true;\n\t\t}\n\t\tif ((int)Fillage > 0)\n\t\t{\n\t\t\treturn true;\n\t\t}\n\t\tif (this.IsEdifice())\n\t\t{\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\tpublic virtual bool CanSpawnAt(IntVec3 pos, Rot4 rot, Map map)\n\t{\n\t\treturn true;\n\t}\n\n\tpublic bool EverStorable(bool willMinifyIfPossible)\n\t{\n\t\tif (typeof(MinifiedThing).IsAssignableFrom(thingClass))\n\t\t{\n\t\t\treturn true;\n\t\t}\n\t\tif (!thingCategories.NullOrEmpty())\n\t\t{\n\t\t\tif (category == ThingCategory.Item)\n\t\t\t{\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tif (willMinifyIfPossible && Minifiable)\n\t\t\t{\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n\n\tpublic Thing GetConcreteExample(ThingDef stuff = null)\n\t{\n\t\tif (concreteExamplesInt == null)\n\t\t{\n\t\t\tconcreteExamplesInt = new Dictionary();\n\t\t}\n\t\tif (stuff == null)\n\t\t{\n\t\t\tstuff = ThingDefOf.Steel;\n\t\t}\n\t\tif (!concreteExamplesInt.ContainsKey(stuff))\n\t\t{\n\t\t\tif (race == null)\n\t\t\t{\n\t\t\t\tconcreteExamplesInt[stuff] = ThingMaker.MakeThing(this, base.MadeFromStuff ? stuff : null);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tconcreteExamplesInt[stuff] = PawnGenerator.GeneratePawn(DefDatabase.AllDefsListForReading.FirstOrDefault((PawnKindDef pkd) => pkd.race == this));\n\t\t\t}\n\t\t}\n\t\treturn concreteExamplesInt[stuff];\n\t}\n\n\tpublic CompProperties CompDefFor() where T : ThingComp\n\t{\n\t\tfor (int i = 0; i < comps.Count; i++)\n\t\t{\n\t\t\tif (comps[i].compClass == typeof(T))\n\t\t\t{\n\t\t\t\treturn comps[i];\n\t\t\t}\n\t\t}\n\t\treturn null;\n\t}\n\n\tpublic CompProperties CompDefForAssignableFrom() where T : ThingComp\n\t{\n\t\tfor (int i = 0; i < comps.Count; i++)\n\t\t{\n\t\t\tif (typeof(T).IsAssignableFrom(comps[i].compClass))\n\t\t\t{\n\t\t\t\treturn comps[i];\n\t\t\t}\n\t\t}\n\t\treturn null;\n\t}\n\n\tpublic bool HasComp(Type compType)\n\t{\n\t\tfor (int i = 0; i < comps.Count; i++)\n\t\t{\n\t\t\tif (comps[i].compClass == compType)\n\t\t\t{\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n\n\tpublic bool HasComp() where T : ThingComp\n\t{\n\t\tfor (int i = 0; i < comps.Count; i++)\n\t\t{\n\t\t\tif (comps[i].compClass == typeof(T) || typeof(T).IsAssignableFrom(comps[i].compClass))\n\t\t\t{\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n\n\tpublic bool HasAssignableCompFrom(Type compType)\n\t{\n\t\tfor (int i = 0; i < comps.Count; i++)\n\t\t{\n\t\t\tif (compType.IsAssignableFrom(comps[i].compClass))\n\t\t\t{\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n\n\tpublic T GetCompProperties() where T : CompProperties\n\t{\n\t\tfor (int i = 0; i < comps.Count; i++)\n\t\t{\n\t\t\tif (comps[i] is T result)\n\t\t\t{\n\t\t\t\treturn result;\n\t\t\t}\n\t\t}\n\t\treturn null;\n\t}\n\n\tpublic override void PostLoad()\n\t{\n\t\tif (graphicData != null)\n\t\t{\n\t\t\tLongEventHandler.ExecuteWhenFinished(delegate\n\t\t\t{\n\t\t\t\tGraphicData graphicData = this.graphicData;\n\t\t\t\tif (graphicData.shaderType == null)\n\t\t\t\t{\n\t\t\t\t\tgraphicData.shaderType = ShaderTypeDefOf.Cutout;\n\t\t\t\t}\n\t\t\t\tContentFinderRequester.requester = this;\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tgraphic = this.graphicData.Graphic;\n\t\t\t\t\tif (drawerType != DrawerType.RealtimeOnly)\n\t\t\t\t\t{\n\t\t\t\t\t\tTextureAtlasGroup textureAtlasGroup = category.ToAtlasGroup();\n\t\t\t\t\t\tgraphic.TryInsertIntoAtlas(textureAtlasGroup);\n\t\t\t\t\t\tif (textureAtlasGroup == TextureAtlasGroup.Building && Minifiable)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tgraphic.TryInsertIntoAtlas(TextureAtlasGroup.Item);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tfinally\n\t\t\t\t{\n\t\t\t\t\tContentFinderRequester.requester = null;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\tif (tools != null)\n\t\t{\n\t\t\tfor (int i = 0; i < tools.Count; i++)\n\t\t\t{\n\t\t\t\ttools[i].id = i.ToString();\n\t\t\t}\n\t\t}\n\t\tif (verbs != null && verbs.Count == 1 && verbs[0].label.NullOrEmpty())\n\t\t{\n\t\t\tverbs[0].label = label;\n\t\t}\n\t\tbase.PostLoad();\n\t\tif (category == ThingCategory.Building && building == null)\n\t\t{\n\t\t\tbuilding = new BuildingProperties();\n\t\t}\n\t\tbuilding?.PostLoadSpecial(this);\n\t\tapparel?.PostLoadSpecial(this);\n\t\tplant?.PostLoadSpecial(this);\n\t\tif (comps == null)\n\t\t{\n\t\t\treturn;\n\t\t}\n\t\tforeach (CompProperties comp in comps)\n\t\t{\n\t\t\tcomp.PostLoadSpecial(this);\n\t\t}\n\t}\n\n\tprotected override void ResolveIcon()\n\t{\n\t\tbase.ResolveIcon();\n\t\tif (category == ThingCategory.Pawn)\n\t\t{\n\t\t\tif (!uiIconPath.NullOrEmpty())\n\t\t\t{\n\t\t\t\tuiIcon = ContentFinder.Get(uiIconPath);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (race.Humanlike)\n\t\t\t\t{\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tPawnKindDef anyPawnKind = race.AnyPawnKind;\n\t\t\t\tif (anyPawnKind != null)\n\t\t\t\t{\n\t\t\t\t\tMaterial material = ((ModsConfig.BiotechActive && anyPawnKind.RaceProps.IsMechanoid) ? anyPawnKind.lifeStages.First() : anyPawnKind.lifeStages.Last()).bodyGraphicData.Graphic.MatAt(Rot4.East);\n\t\t\t\t\tuiIcon = (Texture2D)material.mainTexture;\n\t\t\t\t\tuiIconColor = material.color;\n\t\t\t\t\tif (ShaderDatabase.TryGetUIShader(material.shader, out var uiShader) && MaterialPool.TryGetRequestForMat(material, out var request))\n\t\t\t\t\t{\n\t\t\t\t\t\trequest.shader = uiShader;\n\t\t\t\t\t\tuiIconMaterial = MaterialPool.MatFrom(request);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tThingDef thingDef = GenStuff.DefaultStuffFor(this);\n\t\t\tif (colorGenerator != null && (thingDef == null || thingDef.stuffProps.allowColorGenerators))\n\t\t\t{\n\t\t\t\tuiIconColor = colorGenerator.ExemplaryColor;\n\t\t\t}\n\t\t\telse if (thingDef != null)\n\t\t\t{\n\t\t\t\tuiIconColor = GetColorForStuff(thingDef);\n\t\t\t}\n\t\t\telse if (graphicData != null)\n\t\t\t{\n\t\t\t\tuiIconColor = graphicData.color;\n\t\t\t}\n\t\t\tif (rotatable && graphic != null && graphic != BaseContent.BadGraphic && graphic.ShouldDrawRotated && defaultPlacingRot == Rot4.South)\n\t\t\t{\n\t\t\t\tuiIconAngle = 180f + graphic.DrawRotatedExtraAngleOffset;\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic override void ResolveReferences()\n\t{\n\t\tbase.ResolveReferences();\n\t\tif (ingestible != null)\n\t\t{\n\t\t\tingestible.parent = this;\n\t\t}\n\t\tif (stuffProps != null)\n\t\t{\n\t\t\tstuffProps.parent = this;\n\t\t}\n\t\tbuilding?.ResolveReferencesSpecial();\n\t\tgraphicData?.ResolveReferencesSpecial();\n\t\trace?.ResolveReferencesSpecial();\n\t\tstuffProps?.ResolveReferencesSpecial();\n\t\tapparel?.ResolveReferencesSpecial();\n\t\tif (soundImpactDefault == null)\n\t\t{\n\t\t\tsoundImpactDefault = SoundDefOf.BulletImpact_Ground;\n\t\t}\n\t\tif (soundDrop == null)\n\t\t{\n\t\t\tsoundDrop = SoundDefOf.Standard_Drop;\n\t\t}\n\t\tif (soundPickup == null)\n\t\t{\n\t\t\tsoundPickup = SoundDefOf.Standard_Pickup;\n\t\t}\n\t\tif (soundInteract == null)\n\t\t{\n\t\t\tsoundInteract = SoundDefOf.Standard_Pickup;\n\t\t}\n\t\tif (inspectorTabs != null && inspectorTabs.Any())\n\t\t{\n\t\t\tinspectorTabsResolved = new List();\n\t\t\tfor (int i = 0; i < inspectorTabs.Count; i++)\n\t\t\t{\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tinspectorTabsResolved.Add(InspectTabManager.GetSharedInstance(inspectorTabs[i]));\n\t\t\t\t}\n\t\t\t\tcatch (Exception ex)\n\t\t\t\t{\n\t\t\t\t\tLog.Error(\"Could not instantiate inspector tab of type \" + inspectorTabs[i]?.ToString() + \": \" + ex);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (comps != null)\n\t\t{\n\t\t\tfor (int j = 0; j < comps.Count; j++)\n\t\t\t{\n\t\t\t\tcomps[j].ResolveReferences(this);\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic override IEnumerable ConfigErrors()\n\t{\n\t\tforeach (string item in base.ConfigErrors())\n\t\t{\n\t\t\tyield return item;\n\t\t}\n\t\tif (category != ThingCategory.Ethereal && label.NullOrEmpty())\n\t\t{\n\t\t\tyield return \"no label\";\n\t\t}\n\t\tif (category == ThingCategory.Building && !IsFrame && building.IsDeconstructible && thingClass != null && typeof(Building).IsSubclassOf(thingClass))\n\t\t{\n\t\t\tyield return \"has building category and is marked as deconstructible, but thing class is not a subclass of building (\" + thingClass.Name + \")\";\n\t\t}\n\t\tif (graphicData != null)\n\t\t{\n\t\t\tforeach (string item2 in graphicData.ConfigErrors(this))\n\t\t\t{\n\t\t\t\tyield return item2;\n\t\t\t}\n\t\t}\n\t\tif (projectile != null)\n\t\t{\n\t\t\tforeach (string item3 in projectile.ConfigErrors(this))\n\t\t\t{\n\t\t\t\tyield return item3;\n\t\t\t}\n\t\t}\n\t\tif (statBases != null)\n\t\t{\n\t\t\tforeach (StatModifier statBase in statBases)\n\t\t\t{\n\t\t\t\tif (statBases.Count((StatModifier st) => st.stat == statBase.stat) > 1)\n\t\t\t\t{\n\t\t\t\t\tyield return \"defines the stat base \" + statBase.stat?.ToString() + \" more than once.\";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (!BeautyUtility.BeautyRelevant(category) && this.StatBaseDefined(StatDefOf.Beauty))\n\t\t{\n\t\t\tyield return \"Beauty stat base is defined, but Things of category \" + category.ToString() + \" cannot have beauty.\";\n\t\t}\n\t\tif (!BeautyUtility.BeautyRelevant(category) && this.StatBaseDefined(StatDefOf.BeautyOutdoors))\n\t\t{\n\t\t\tyield return \"BeautyOutdoors stat base is defined, but Things of category \" + category.ToString() + \" cannot have beauty.\";\n\t\t}\n\t\tif (char.IsNumber(defName[defName.Length - 1]))\n\t\t{\n\t\t\tyield return \"ends with a numerical digit, which is not allowed on ThingDefs.\";\n\t\t}\n\t\tif (thingClass == null)\n\t\t{\n\t\t\tyield return \"has null thingClass.\";\n\t\t}\n\t\tif (comps.Count > 0 && !typeof(ThingWithComps).IsAssignableFrom(thingClass))\n\t\t{\n\t\t\tyield return \"has components but it's thingClass is not a ThingWithComps\";\n\t\t}\n\t\tif (ConnectToPower && drawerType == DrawerType.RealtimeOnly && IsFrame)\n\t\t{\n\t\t\tyield return \"connects to power but does not add to map mesh. Will not create wire meshes.\";\n\t\t}\n\t\tif (costList != null)\n\t\t{\n\t\t\tforeach (ThingDefCountClass cost in costList)\n\t\t\t{\n\t\t\t\tif (cost.count == 0)\n\t\t\t\t{\n\t\t\t\t\tyield return \"cost in \" + cost.thingDef?.ToString() + \" is zero.\";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tThingCategoryDef thingCategoryDef = thingCategories?.FirstOrDefault((ThingCategoryDef cat) => thingCategories.Count((ThingCategoryDef c) => c == cat) > 1);\n\t\tif (thingCategoryDef != null)\n\t\t{\n\t\t\tyield return \"has duplicate thingCategory \" + thingCategoryDef?.ToString() + \".\";\n\t\t}\n\t\tif (Fillage == FillCategory.Full && category != ThingCategory.Building)\n\t\t{\n\t\t\tyield return \"gives full cover but is not a building.\";\n\t\t}\n\t\tif (equipmentType != 0)\n\t\t{\n\t\t\tif (techLevel == TechLevel.Undefined && !destroyOnDrop)\n\t\t\t{\n\t\t\t\tyield return \"is equipment but has no tech level.\";\n\t\t\t}\n\t\t\tif (!comps.Any((CompProperties c) => typeof(CompEquippable).IsAssignableFrom(c.compClass)))\n\t\t\t{\n\t\t\t\tyield return \"is equipment but has no CompEquippable\";\n\t\t\t}\n\t\t}\n\t\tif (thingClass == typeof(Bullet) && projectile.damageDef == null)\n\t\t{\n\t\t\tyield return \" is a bullet but has no damageDef.\";\n\t\t}\n\t\tif (destroyOnDrop && tradeability != 0)\n\t\t{\n\t\t\tyield return \"destroyOnDrop but tradeability is \" + tradeability;\n\t\t}\n\t\tif (stackLimit > 1 && !drawGUIOverlay)\n\t\t{\n\t\t\tyield return \"has stackLimit > 1 but also has drawGUIOverlay = false.\";\n\t\t}\n\t\tif (damageMultipliers != null)\n\t\t{\n\t\t\tforeach (DamageMultiplier mult in damageMultipliers)\n\t\t\t{\n\t\t\t\tif (damageMultipliers.Count((DamageMultiplier m) => m.damageDef == mult.damageDef) > 1)\n\t\t\t\t{\n\t\t\t\t\tyield return \"has multiple damage multipliers for damageDef \" + mult.damageDef;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (Fillage == FillCategory.Full && !this.IsEdifice())\n\t\t{\n\t\t\tyield return \"fillPercent is 1.00 but is not edifice\";\n\t\t}\n\t\tif (base.MadeFromStuff && constructEffect != null)\n\t\t{\n\t\t\tyield return \"madeFromStuff but has a defined constructEffect (which will always be overridden by stuff's construct animation).\";\n\t\t}\n\t\tif (base.MadeFromStuff && stuffCategories.NullOrEmpty())\n\t\t{\n\t\t\tyield return \"madeFromStuff but has no stuffCategories.\";\n\t\t}\n\t\tif (costList.NullOrEmpty() && costStuffCount <= 0 && recipeMaker != null)\n\t\t{\n\t\t\tyield return \"has a recipeMaker but no costList or costStuffCount.\";\n\t\t}\n\t\tif (costStuffCount > 0 && stuffCategories.NullOrEmpty())\n\t\t{\n\t\t\tyield return \"has costStuffCount but no stuffCategories.\";\n\t\t}\n\t\tif (this.GetStatValueAbstract(StatDefOf.DeteriorationRate) > 1E-05f && !CanEverDeteriorate && !destroyOnDrop)\n\t\t{\n\t\t\tyield return \"has >0 DeteriorationRate but can't deteriorate.\";\n\t\t}\n\t\tif (smeltProducts != null && !smeltable)\n\t\t{\n\t\t\tyield return \"has smeltProducts but has smeltable=false\";\n\t\t}\n\t\tif (smeltable && smeltProducts.NullOrEmpty() && base.CostList.NullOrEmpty() && !IsStuff && !base.MadeFromStuff && !destroyOnDrop)\n\t\t{\n\t\t\tyield return \"is smeltable but does not give anything for smelting.\";\n\t\t}\n\t\tif (equipmentType != 0 && verbs.NullOrEmpty() && tools.NullOrEmpty())\n\t\t{\n\t\t\tyield return \"is equipment but has no verbs or tools\";\n\t\t}\n\t\tif (Minifiable && thingCategories.NullOrEmpty())\n\t\t{\n\t\t\tyield return \"is minifiable but not in any thing category\";\n\t\t}\n\t\tif (category == ThingCategory.Building && !Minifiable && !thingCategories.NullOrEmpty())\n\t\t{\n\t\t\tyield return \"is not minifiable yet has thing categories (could be confusing in thing filters because it can't be moved/stored anyway)\";\n\t\t}\n\t\tif (!destroyOnDrop && !typeof(MinifiedThing).IsAssignableFrom(thingClass) && (EverHaulable || Minifiable) && (statBases.NullOrEmpty() || !statBases.Any((StatModifier s) => s.stat == StatDefOf.Mass)))\n\t\t{\n\t\t\tyield return \"is haulable, but does not have an authored mass value\";\n\t\t}\n\t\tif (ingestible == null && this.GetStatValueAbstract(StatDefOf.Nutrition) != 0f)\n\t\t{\n\t\t\tyield return \"has nutrition but ingestible properties are null\";\n\t\t}\n\t\tif (BaseFlammability != 0f && !useHitPoints && category != ThingCategory.Pawn && !destroyOnDrop)\n\t\t{\n\t\t\tyield return \"flammable but has no hitpoints (will burn indefinitely)\";\n\t\t}\n\t\tif (graphicData?.shadowData != null && staticSunShadowHeight > 0f)\n\t\t{\n\t\t\tyield return \"graphicData defines a shadowInfo but staticSunShadowHeight > 0\";\n\t\t}\n\t\tif (saveCompressible && Claimable)\n\t\t{\n\t\t\tyield return \"claimable item is compressible; faction will be unset after load\";\n\t\t}\n\t\tif (deepCommonality > 0f != deepLumpSizeRange.TrueMax > 0)\n\t\t{\n\t\t\tyield return \"if deepCommonality or deepLumpSizeRange is set, the other also must be set\";\n\t\t}\n\t\tif (deepCommonality > 0f && deepCountPerPortion <= 0)\n\t\t{\n\t\t\tyield return \"deepCommonality > 0 but deepCountPerPortion is not set\";\n\t\t}\n\t\tif (verbs != null)\n\t\t{\n\t\t\tfor (int i = 0; i < verbs.Count; i++)\n\t\t\t{\n\t\t\t\tforeach (string item4 in verbs[i].ConfigErrors(this))\n\t\t\t\t{\n\t\t\t\t\tyield return $\"verb {i}: {item4}\";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (building != null)\n\t\t{\n\t\t\tforeach (string item5 in building.ConfigErrors(this))\n\t\t\t{\n\t\t\t\tyield return item5;\n\t\t\t}\n\t\t\tif ((building.isAirtight || building.isStuffableAirtight) && Fillage != FillCategory.Full)\n\t\t\t{\n\t\t\t\tyield return \"is airtight but Fillage is not Full\";\n\t\t\t}\n\t\t}\n\t\tif (apparel != null)\n\t\t{\n\t\t\tforeach (string item6 in apparel.ConfigErrors(this))\n\t\t\t{\n\t\t\t\tyield return item6;\n\t\t\t}\n\t\t}\n\t\tif (comps != null)\n\t\t{\n\t\t\tfor (int i = 0; i < comps.Count; i++)\n\t\t\t{\n\t\t\t\tforeach (string item7 in comps[i].ConfigErrors(this))\n\t\t\t\t{\n\t\t\t\t\tyield return item7;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (race != null)\n\t\t{\n\t\t\tforeach (string item8 in race.ConfigErrors(this))\n\t\t\t{\n\t\t\t\tyield return item8;\n\t\t\t}\n\t\t\tif (race.body != null && race != null && tools != null)\n\t\t\t{\n\t\t\t\tint i;\n\t\t\t\tfor (i = 0; i < tools.Count; i++)\n\t\t\t\t{\n\t\t\t\t\tif (tools[i].linkedBodyPartsGroup != null && !race.body.AllParts.Any((BodyPartRecord part) => part.groups.Contains(tools[i].linkedBodyPartsGroup)))\n\t\t\t\t\t{\n\t\t\t\t\t\tyield return \"has tool with linkedBodyPartsGroup \" + tools[i].linkedBodyPartsGroup?.ToString() + \" but body \" + race.body?.ToString() + \" has no parts with that group.\";\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (race.Animal && this.GetStatValueAbstract(StatDefOf.Wildness) < 0f)\n\t\t\t{\n\t\t\t\tyield return \"is animal but wildness is not defined\";\n\t\t\t}\n\t\t}\n\t\tif (ingestible != null)\n\t\t{\n\t\t\tforeach (string item9 in ingestible.ConfigErrors())\n\t\t\t{\n\t\t\t\tyield return item9;\n\t\t\t}\n\t\t}\n\t\tif (plant != null)\n\t\t{\n\t\t\tforeach (string item10 in plant.ConfigErrors())\n\t\t\t{\n\t\t\t\tyield return item10;\n\t\t\t}\n\t\t}\n\t\tif (tools != null)\n\t\t{\n\t\t\tTool tool = tools.SelectMany((Tool lhs) => tools.Where((Tool rhs) => lhs != rhs && lhs.id == rhs.id)).FirstOrDefault();\n\t\t\tif (tool != null)\n\t\t\t{\n\t\t\t\tyield return \"duplicate thingdef tool id \" + tool.id;\n\t\t\t}\n\t\t\tforeach (Tool tool2 in tools)\n\t\t\t{\n\t\t\t\tforeach (string item11 in tool2.ConfigErrors())\n\t\t\t\t{\n\t\t\t\t\tyield return item11;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (!randomStyle.NullOrEmpty())\n\t\t{\n\t\t\tforeach (ThingStyleChance item12 in randomStyle)\n\t\t\t{\n\t\t\t\tif (item12.Chance <= 0f)\n\t\t\t\t{\n\t\t\t\t\tyield return \"style chance <= 0.\";\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!comps.Any((CompProperties c) => c.compClass == typeof(CompStyleable)))\n\t\t\t{\n\t\t\t\tyield return \"random style assigned, but missing CompStyleable!\";\n\t\t\t}\n\t\t}\n\t\tif (relicChance > 0f && category != ThingCategory.Item)\n\t\t{\n\t\t\tyield return \"relic chance > 0 but category != item\";\n\t\t}\n\t\tif (hasInteractionCell && !multipleInteractionCellOffsets.NullOrEmpty())\n\t\t{\n\t\t\tyield return \"both single and multiple interaction cells are defined, it should be one or the other\";\n\t\t}\n\t\tif (Fillage != FillCategory.Full && passability == Traversability.Impassable && !IsDoor && base.BuildableByPlayer && !disableImpassableShotOverConfigError)\n\t\t{\n\t\t\tyield return \"impassable, player-buildable building that can be shot/seen over.\";\n\t\t}\n\t}\n\n\tpublic static ThingDef Named(string defName)\n\t{\n\t\treturn DefDatabase.GetNamed(defName);\n\t}\n\n\tpublic bool IsWithinCategory(ThingCategoryDef category)\n\t{\n\t\tif (thingCategories == null)\n\t\t{\n\t\t\treturn false;\n\t\t}\n\t\tfor (int i = 0; i < thingCategories.Count; i++)\n\t\t{\n\t\t\tfor (ThingCategoryDef thingCategoryDef = thingCategories[i]; thingCategoryDef != null; thingCategoryDef = thingCategoryDef.parent)\n\t\t\t{\n\t\t\t\tif (thingCategoryDef == category)\n\t\t\t\t{\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n\n\tpublic void Notify_UnlockedByResearch()\n\t{\n\t\tif (comps != null)\n\t\t{\n\t\t\tfor (int i = 0; i < comps.Count; i++)\n\t\t\t{\n\t\t\t\tcomps[i].Notify_PostUnlockedByResearch(this);\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic override IEnumerable SpecialDisplayStats(StatRequest req)\n\t{\n\t\tforeach (StatDrawEntry item in base.SpecialDisplayStats(req))\n\t\t{\n\t\t\tyield return item;\n\t\t}\n\t\tif (apparel != null)\n\t\t{\n\t\t\tstring coveredOuterPartsString = apparel.GetCoveredOuterPartsString(BodyDefOf.Human);\n\t\t\tyield return new StatDrawEntry(StatCategoryDefOf.Apparel, \"Covers\".Translate(), coveredOuterPartsString, \"Stat_Thing_Apparel_Covers_Desc\".Translate(), 2750);\n\t\t\tyield return new StatDrawEntry(StatCategoryDefOf.Apparel, \"Layer\".Translate(), apparel.GetLayersString(), \"Stat_Thing_Apparel_Layer_Desc\".Translate(), 2751);\n\t\t\tyield return new StatDrawEntry(StatCategoryDefOf.Apparel, \"Stat_Thing_Apparel_CountsAsClothingNudity_Name\".Translate(), apparel.countsAsClothingForNudity ? \"Yes\".Translate() : \"No\".Translate(), \"Stat_Thing_Apparel_CountsAsClothingNudity_Desc\".Translate(), 2753);\n\t\t\tif (ModsConfig.BiotechActive)\n\t\t\t{\n\t\t\t\tyield return new StatDrawEntry(StatCategoryDefOf.Apparel, \"Stat_Thing_Apparel_ValidLifestage\".Translate(), apparel.developmentalStageFilter.ToCommaList().CapitalizeFirst(), \"Stat_Thing_Apparel_ValidLifestage_Desc\".Translate(), 2748);\n\t\t\t}\n\t\t\tif (apparel.gender != 0)\n\t\t\t{\n\t\t\t\tyield return new StatDrawEntry(StatCategoryDefOf.Apparel, \"Stat_Thing_Apparel_Gender\".Translate(), apparel.gender.GetLabel().CapitalizeFirst(), \"Stat_Thing_Apparel_Gender_Desc\".Translate(), 2749);\n\t\t\t}\n\t\t}\n\t\tif (IsMedicine && MedicineTendXpGainFactor != 1f)\n\t\t{\n\t\t\tyield return new StatDrawEntry(StatCategoryDefOf.Basics, \"MedicineXpGainFactor\".Translate(), MedicineTendXpGainFactor.ToStringPercent(), \"Stat_Thing_Drug_MedicineXpGainFactor_Desc\".Translate(), 1000);\n\t\t}\n\t\tif (fillPercent > 0f && (category == ThingCategory.Item || category == ThingCategory.Building || category == ThingCategory.Plant))\n\t\t{\n\t\t\tyield return new StatDrawEntry(StatCategoryDefOf.Basics, \"CoverEffectiveness\".Translate(), this.BaseBlockChance().ToStringPercent(), \"CoverEffectivenessExplanation\".Translate(), 2000);\n\t\t}\n\t\tif (constructionSkillPrerequisite > 0)\n\t\t{\n\t\t\tyield return new StatDrawEntry(StatCategoryDefOf.Basics, \"SkillRequiredToBuild\".Translate(SkillDefOf.Construction.LabelCap), constructionSkillPrerequisite.ToString(), \"SkillRequiredToBuildExplanation\".Translate(SkillDefOf.Construction.LabelCap), 1100);\n\t\t}\n\t\tif (artisticSkillPrerequisite > 0)\n\t\t{\n\t\t\tyield return new StatDrawEntry(StatCategoryDefOf.Basics, \"SkillRequiredToBuild\".Translate(SkillDefOf.Artistic.LabelCap), artisticSkillPrerequisite.ToString(), \"SkillRequiredToBuildExplanation\".Translate(SkillDefOf.Artistic.LabelCap), 1100);\n\t\t}\n\t\tIEnumerable recipes = DefDatabase.AllDefsListForReading.Where((RecipeDef r) => r.products.Count == 1 && r.products.Any((ThingDefCountClass p) => p.thingDef == this) && !r.IsSurgery);\n\t\tif (recipes.Any())\n\t\t{\n\t\t\tIEnumerable enumerable = (from u in recipes.Where((RecipeDef x) => x.recipeUsers != null).SelectMany((RecipeDef r) => r.recipeUsers)\n\t\t\t\tselect u.label).Concat(from x in DefDatabase.AllDefsListForReading\n\t\t\t\twhere x.recipes != null && x.recipes.Any((RecipeDef y) => y.products.Any((ThingDefCountClass z) => z.thingDef == this))\n\t\t\t\tselect x.label).Distinct();\n\t\t\tif (enumerable.Any())\n\t\t\t{\n\t\t\t\tyield return new StatDrawEntry(StatCategoryDefOf.Basics, \"CreatedAt\".Translate(), enumerable.ToCommaList().CapitalizeFirst(), \"Stat_Thing_CreatedAt_Desc\".Translate(), 1103);\n\t\t\t}\n\t\t\tRecipeDef recipeDef = recipes.FirstOrDefault();\n\t\t\tif (recipeDef != null && !recipeDef.ingredients.NullOrEmpty())\n\t\t\t{\n\t\t\t\tBuildableDef.tmpCostList.Clear();\n\t\t\t\tBuildableDef.tmpHyperlinks.Clear();\n\t\t\t\tfor (int j = 0; j < recipeDef.ingredients.Count; j++)\n\t\t\t\t{\n\t\t\t\t\tIngredientCount ingredientCount = recipeDef.ingredients[j];\n\t\t\t\t\tif (ingredientCount.filter.Summary.NullOrEmpty())\n\t\t\t\t\t{\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tIEnumerable allowedThingDefs = ingredientCount.filter.AllowedThingDefs;\n\t\t\t\t\tif (allowedThingDefs.Any())\n\t\t\t\t\t{\n\t\t\t\t\t\tforeach (ThingDef p in allowedThingDefs)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (!BuildableDef.tmpHyperlinks.Any((Dialog_InfoCard.Hyperlink x) => x.def == p))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tBuildableDef.tmpHyperlinks.Add(new Dialog_InfoCard.Hyperlink(p));\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tBuildableDef.tmpCostList.Add(recipeDef.IngredientValueGetter.BillRequirementsDescription(recipeDef, ingredientCount));\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (BuildableDef.tmpCostList.Any())\n\t\t\t{\n\t\t\t\tyield return new StatDrawEntry(StatCategoryDefOf.Basics, \"Ingredients\".Translate(), BuildableDef.tmpCostList.ToCommaList(), \"Stat_Thing_Ingredients\".Translate(), 1102, null, BuildableDef.tmpHyperlinks);\n\t\t\t}\n\t\t}\n\t\tif (thingClass != null && typeof(Building_Bed).IsAssignableFrom(thingClass) && !statBases.StatListContains(StatDefOf.BedRestEffectiveness))\n\t\t{\n\t\t\tyield return new StatDrawEntry(StatCategoryDefOf.Building, StatDefOf.BedRestEffectiveness, StatDefOf.BedRestEffectiveness.valueIfMissing, StatRequest.ForEmpty());\n\t\t}\n\t\tif (!verbs.NullOrEmpty())\n\t\t{\n\t\t\tVerbProperties verb = verbs.First((VerbProperties x) => x.isPrimary);\n\t\t\tStatCategoryDef verbStatCategory = ((category == ThingCategory.Pawn) ? StatCategoryDefOf.PawnCombat : null);\n\t\t\tfloat num = verb.warmupTime;\n\t\t\tStringBuilder stringBuilder = new StringBuilder(\"Stat_Thing_Weapon_RangedWarmupTime_Desc\".Translate());\n\t\t\tstringBuilder.AppendLine();\n\t\t\tstringBuilder.AppendLine();\n\t\t\tstringBuilder.AppendLine(\"StatsReport_BaseValue\".Translate() + \": \" + num.ToString(\"0.##\") + \" \" + \"LetterSecond\".Translate());\n\t\t\tif (num > 0f)\n\t\t\t{\n\t\t\t\tif (req.HasThing)\n\t\t\t\t{\n\t\t\t\t\tfloat statValue = req.Thing.GetStatValue(StatDefOf.RangedWeapon_WarmupMultiplier);\n\t\t\t\t\tnum *= statValue;\n\t\t\t\t\tif (!Mathf.Approximately(statValue, 1f))\n\t\t\t\t\t{\n\t\t\t\t\t\tstringBuilder.AppendLine();\n\t\t\t\t\t\tstringBuilder.AppendLine(\"Stat_Thing_Weapon_WarmupTime_Multiplier\".Translate() + \": x\" + statValue.ToStringPercent());\n\t\t\t\t\t\tstringBuilder.Append(StatUtility.GetOffsetsAndFactorsFor(StatDefOf.RangedWeapon_WarmupMultiplier, req.Thing));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tstringBuilder.AppendLine();\n\t\t\t\tstringBuilder.AppendLine(\"StatsReport_FinalValue\".Translate() + \": \" + num.ToString(\"0.##\") + \" \" + \"LetterSecond\".Translate());\n\t\t\t\tyield return new StatDrawEntry(verbStatCategory ?? StatCategoryDefOf.Weapon_Ranged, \"RangedWarmupTime\".Translate(), num.ToString(\"0.##\") + \" \" + \"LetterSecond\".Translate(), stringBuilder.ToString(), 3555);\n\t\t\t}\n\t\t\tif (verb.defaultProjectile?.projectile.damageDef != null && verb.defaultProjectile.projectile.damageDef.harmsHealth)\n\t\t\t{\n\t\t\t\tStatCategoryDef statCat = verbStatCategory ?? StatCategoryDefOf.Weapon_Ranged;\n\t\t\t\tStringBuilder stringBuilder2 = new StringBuilder();\n\t\t\t\tstringBuilder2.AppendLine(\"Stat_Thing_Damage_Desc\".Translate());\n\t\t\t\tstringBuilder2.AppendLine();\n\t\t\t\tfloat num2 = verb.defaultProjectile.projectile.GetDamageAmount(req.Thing, stringBuilder2);\n\t\t\t\tyield return new StatDrawEntry(statCat, \"Damage\".Translate(), num2.ToString(), stringBuilder2.ToString(), 5500);\n\t\t\t\tif (verb.defaultProjectile.projectile.damageDef.armorCategory != null)\n\t\t\t\t{\n\t\t\t\t\tStringBuilder stringBuilder3 = new StringBuilder();\n\t\t\t\t\tfloat armorPenetration = verb.defaultProjectile.projectile.GetArmorPenetration(req.Thing, stringBuilder3);\n\t\t\t\t\tTaggedString taggedString = \"ArmorPenetrationExplanation\".Translate();\n\t\t\t\t\tif (stringBuilder3.Length != 0)\n\t\t\t\t\t{\n\t\t\t\t\t\ttaggedString += \"\\n\\n\" + stringBuilder3;\n\t\t\t\t\t}\n\t\t\t\t\tyield return new StatDrawEntry(statCat, \"ArmorPenetration\".Translate(), armorPenetration.ToStringPercent(), taggedString, 5400);\n\t\t\t\t}\n\t\t\t\tfloat buildingDamageFactor = verb.defaultProjectile.projectile.damageDef.buildingDamageFactor;\n\t\t\t\tfloat dmgBuildingsImpassable = verb.defaultProjectile.projectile.damageDef.buildingDamageFactorImpassable;\n\t\t\t\tfloat dmgBuildingsPassable = verb.defaultProjectile.projectile.damageDef.buildingDamageFactorPassable;\n\t\t\t\tif (buildingDamageFactor != 1f)\n\t\t\t\t{\n\t\t\t\t\tyield return new StatDrawEntry(statCat, \"BuildingDamageFactor\".Translate(), buildingDamageFactor.ToStringPercent(), \"BuildingDamageFactorExplanation\".Translate(), 5410);\n\t\t\t\t}\n\t\t\t\tif (dmgBuildingsImpassable != 1f)\n\t\t\t\t{\n\t\t\t\t\tyield return new StatDrawEntry(statCat, \"BuildingDamageFactorImpassable\".Translate(), dmgBuildingsImpassable.ToStringPercent(), \"BuildingDamageFactorImpassableExplanation\".Translate(), 5420);\n\t\t\t\t}\n\t\t\t\tif (dmgBuildingsPassable != 1f)\n\t\t\t\t{\n\t\t\t\t\tyield return new StatDrawEntry(statCat, \"BuildingDamageFactorPassable\".Translate(), dmgBuildingsPassable.ToStringPercent(), \"BuildingDamageFactorPassableExplanation\".Translate(), 5430);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (verb.defaultProjectile == null && verb.beamDamageDef != null)\n\t\t\t{\n\t\t\t\tyield return new StatDrawEntry(verbStatCategory ?? StatCategoryDefOf.Weapon_Ranged, \"ArmorPenetration\".Translate(), verb.beamDamageDef.defaultArmorPenetration.ToStringPercent(), \"ArmorPenetrationExplanation\".Translate(), 5400);\n\t\t\t}\n\t\t\tif (verb.Ranged)\n\t\t\t{\n\t\t\t\tfloat num3 = verb.burstShotCount;\n\t\t\t\tfloat num4 = verb.ticksBetweenBurstShots;\n\t\t\t\tfloat dmgBuildingsPassable = (verb?.defaultProjectile?.projectile?.stoppingPower).GetValueOrDefault();\n\t\t\t\tStringBuilder stringBuilder4 = new StringBuilder(\"Stat_Thing_Weapon_BurstShotFireRate_Desc\".Translate());\n\t\t\t\tstringBuilder4.AppendLine();\n\t\t\t\tstringBuilder4.AppendLine();\n\t\t\t\tstringBuilder4.AppendLine(\"StatsReport_BaseValue\".Translate() + \": \" + verb.burstShotCount.ToString());\n\t\t\t\tstringBuilder4.AppendLine();\n\t\t\t\tStringBuilder ticksBetweenBurstShotsExplanation = new StringBuilder(\"Stat_Thing_Weapon_BurstShotFireRate_Desc\".Translate());\n\t\t\t\tticksBetweenBurstShotsExplanation.AppendLine();\n\t\t\t\tticksBetweenBurstShotsExplanation.AppendLine();\n\t\t\t\tticksBetweenBurstShotsExplanation.AppendLine(\"StatsReport_BaseValue\".Translate() + \": \" + (60f / verb.ticksBetweenBurstShots.TicksToSeconds()).ToString(\"0.##\") + \" rpm\");\n\t\t\t\tticksBetweenBurstShotsExplanation.AppendLine();\n\t\t\t\tStringBuilder stoppingPowerExplanation = new StringBuilder(\"StoppingPowerExplanation\".Translate());\n\t\t\t\tstoppingPowerExplanation.AppendLine();\n\t\t\t\tstoppingPowerExplanation.AppendLine();\n\t\t\t\tstoppingPowerExplanation.AppendLine(\"StatsReport_BaseValue\".Translate() + \": \" + dmgBuildingsPassable.ToString(\"F1\"));\n\t\t\t\tstoppingPowerExplanation.AppendLine();\n\t\t\t\tif (req.HasThing && req.Thing.TryGetComp(out CompUniqueWeapon comp))\n\t\t\t\t{\n\t\t\t\t\tbool flag = false;\n\t\t\t\t\tbool flag2 = false;\n\t\t\t\t\tbool flag3 = false;\n\t\t\t\t\tforeach (WeaponTraitDef item2 in comp.TraitsListForReading)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (!Mathf.Approximately(item2.burstShotCountMultiplier, 1f))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (!flag)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tstringBuilder4.AppendLine(\"StatsReport_WeaponTraits\".Translate() + \":\");\n\t\t\t\t\t\t\t\tflag = true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tnum3 *= item2.burstShotCountMultiplier;\n\t\t\t\t\t\t\tstringBuilder4.AppendLine(\" \" + item2.LabelCap + \": \" + item2.burstShotCountMultiplier.ToStringByStyle(ToStringStyle.PercentOne, ToStringNumberSense.Factor));\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (!Mathf.Approximately(item2.burstShotSpeedMultiplier, 1f))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (!flag2)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tticksBetweenBurstShotsExplanation.AppendLine(\"StatsReport_WeaponTraits\".Translate() + \":\");\n\t\t\t\t\t\t\t\tflag2 = true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tnum4 /= item2.burstShotSpeedMultiplier;\n\t\t\t\t\t\t\tticksBetweenBurstShotsExplanation.AppendLine(\" \" + item2.LabelCap + \": \" + item2.burstShotSpeedMultiplier.ToStringByStyle(ToStringStyle.PercentOne, ToStringNumberSense.Factor));\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (!Mathf.Approximately(item2.additionalStoppingPower, 0f))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (!flag3)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tstoppingPowerExplanation.AppendLine(\"StatsReport_WeaponTraits\".Translate() + \":\");\n\t\t\t\t\t\t\t\tflag3 = true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tdmgBuildingsPassable += item2.additionalStoppingPower;\n\t\t\t\t\t\t\tstoppingPowerExplanation.AppendLine(\" \" + item2.LabelCap + \": \" + item2.additionalStoppingPower.ToStringByStyle(ToStringStyle.FloatOne, ToStringNumberSense.Offset));\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tstringBuilder4.AppendLine();\n\t\t\t\tstringBuilder4.AppendLine(\"StatsReport_FinalValue\".Translate() + \": \" + Mathf.CeilToInt(num3).ToString());\n\t\t\t\tfloat dmgBuildingsImpassable = 60f / ((int)num4).TicksToSeconds();\n\t\t\t\tticksBetweenBurstShotsExplanation.AppendLine();\n\t\t\t\tticksBetweenBurstShotsExplanation.AppendLine(\"StatsReport_FinalValue\".Translate() + \": \" + dmgBuildingsImpassable.ToString(\"0.##\") + \" rpm\");\n\t\t\t\tstoppingPowerExplanation.AppendLine();\n\t\t\t\tstoppingPowerExplanation.AppendLine(\"StatsReport_FinalValue\".Translate() + \": \" + dmgBuildingsPassable.ToString(\"F1\"));\n\t\t\t\tStatCategoryDef statCat = verbStatCategory ?? StatCategoryDefOf.Weapon_Ranged;\n\t\t\t\tif (verb.showBurstShotStats && verb.burstShotCount > 1)\n\t\t\t\t{\n\t\t\t\t\tyield return new StatDrawEntry(statCat, \"BurstShotCount\".Translate(), Mathf.CeilToInt(num3).ToString(), stringBuilder4.ToString(), 5391);\n\t\t\t\t\tyield return new StatDrawEntry(statCat, \"BurstShotFireRate\".Translate(), dmgBuildingsImpassable.ToString(\"0.##\") + \" rpm\", ticksBetweenBurstShotsExplanation.ToString(), 5395);\n\t\t\t\t}\n\t\t\t\tif (dmgBuildingsPassable > 0f)\n\t\t\t\t{\n\t\t\t\t\tyield return new StatDrawEntry(statCat, \"StoppingPower\".Translate(), dmgBuildingsPassable.ToString(\"F1\"), stoppingPowerExplanation.ToString(), 5402);\n\t\t\t\t}\n\t\t\t\tfloat num5 = verb.range;\n\t\t\t\tStringBuilder stringBuilder5 = new StringBuilder(\"Stat_Thing_Weapon_Range_Desc\".Translate());\n\t\t\t\tstringBuilder5.AppendLine();\n\t\t\t\tstringBuilder5.AppendLine();\n\t\t\t\tstringBuilder5.AppendLine(\"StatsReport_BaseValue\".Translate() + \": \" + num5.ToString(\"F0\"));\n\t\t\t\tif (req.HasThing)\n\t\t\t\t{\n\t\t\t\t\tfloat statValue2 = req.Thing.GetStatValue(StatDefOf.RangedWeapon_RangeMultiplier);\n\t\t\t\t\tnum5 *= statValue2;\n\t\t\t\t\tif (!Mathf.Approximately(statValue2, 1f))\n\t\t\t\t\t{\n\t\t\t\t\t\tstringBuilder5.AppendLine();\n\t\t\t\t\t\tstringBuilder5.AppendLine(\"Stat_Thing_Weapon_Range_Multiplier\".Translate() + \": x\" + statValue2.ToStringPercent());\n\t\t\t\t\t\tstringBuilder5.Append(StatUtility.GetOffsetsAndFactorsFor(StatDefOf.RangedWeapon_RangeMultiplier, req.Thing));\n\t\t\t\t\t}\n\t\t\t\t\tMap obj = req.Thing.Map ?? req.Thing.MapHeld;\n\t\t\t\t\tif (obj != null && obj.weatherManager.CurWeatherMaxRangeCap >= 0f)\n\t\t\t\t\t{\n\t\t\t\t\t\tWeatherManager weatherManager = (req.Thing.Map ?? req.Thing.MapHeld).weatherManager;\n\t\t\t\t\t\tbool num6 = num5 > weatherManager.CurWeatherMaxRangeCap;\n\t\t\t\t\t\tfloat num7 = num5;\n\t\t\t\t\t\tnum5 = Mathf.Min(num5, weatherManager.CurWeatherMaxRangeCap);\n\t\t\t\t\t\tif (num6)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tstringBuilder5.AppendLine();\n\t\t\t\t\t\t\tstringBuilder5.AppendLine(\" \" + \"Stat_Thing_Weapon_Range_Clamped\".Translate(num5.ToString(\"F0\").Named(\"CAP\"), num7.ToString(\"F0\").Named(\"ORIGINAL\")));\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tstringBuilder5.AppendLine();\n\t\t\t\tstringBuilder5.AppendLine(\"StatsReport_FinalValue\".Translate() + \": \" + num5.ToString(\"F0\"));\n\t\t\t\tyield return new StatDrawEntry(statCat, \"Range\".Translate(), num5.ToString(\"F0\"), stringBuilder5.ToString(), 5390);\n\t\t\t}\n\t\t\tif (verb.ForcedMissRadius > 0f)\n\t\t\t{\n\t\t\t\tStatCategoryDef statCat = verbStatCategory ?? StatCategoryDefOf.Weapon_Ranged;\n\t\t\t\tyield return new StatDrawEntry(statCat, \"MissRadius\".Translate(), verb.ForcedMissRadius.ToString(\"0.#\"), \"Stat_Thing_Weapon_MissRadius_Desc\".Translate(), 3557);\n\t\t\t\tyield return new StatDrawEntry(statCat, \"DirectHitChance\".Translate(), (1f / (float)GenRadial.NumCellsInRadius(verb.ForcedMissRadius)).ToStringPercent(), \"Stat_Thing_Weapon_DirectHitChance_Desc\".Translate(), 3560);\n\t\t\t}\n\t\t}\n\t\tif (plant != null)\n\t\t{\n\t\t\tforeach (StatDrawEntry item3 in plant.SpecialDisplayStats())\n\t\t\t{\n\t\t\t\tyield return item3;\n\t\t\t}\n\t\t}\n\t\tif (ingestible != null)\n\t\t{\n\t\t\tforeach (StatDrawEntry item4 in ingestible.SpecialDisplayStats())\n\t\t\t{\n\t\t\t\tyield return item4;\n\t\t\t}\n\t\t}\n\t\tif (race != null)\n\t\t{\n\t\t\tforeach (StatDrawEntry item5 in race.SpecialDisplayStats(this, req))\n\t\t\t{\n\t\t\t\tyield return item5;\n\t\t\t}\n\t\t}\n\t\tif (building != null)\n\t\t{\n\t\t\tforeach (StatDrawEntry item6 in building.SpecialDisplayStats(this, req))\n\t\t\t{\n\t\t\t\tyield return item6;\n\t\t\t}\n\t\t}\n\t\tif (isTechHediff)\n\t\t{\n\t\t\tIEnumerable enumerable2 = DefDatabase.AllDefs.Where((RecipeDef x) => x.addsHediff != null && x.IsIngredient(this));\n\t\t\tforeach (StatDrawEntry medicalStatsFromRecipeDef in MedicalRecipesUtility.GetMedicalStatsFromRecipeDefs(enumerable2))\n\t\t\t{\n\t\t\t\tyield return medicalStatsFromRecipeDef;\n\t\t\t}\n\t\t}\n\t\tfor (int i = 0; i < comps.Count; i++)\n\t\t{\n\t\t\tforeach (StatDrawEntry item7 in comps[i].SpecialDisplayStats(req))\n\t\t\t{\n\t\t\t\tyield return item7;\n\t\t\t}\n\t\t}\n\t\tif (building != null)\n\t\t{\n\t\t\tif (building.mineableThing != null)\n\t\t\t{\n\t\t\t\tDialog_InfoCard.Hyperlink[] hyperlinks = new Dialog_InfoCard.Hyperlink[1]\n\t\t\t\t{\n\t\t\t\t\tnew Dialog_InfoCard.Hyperlink(building.mineableThing)\n\t\t\t\t};\n\t\t\t\tyield return new StatDrawEntry(StatCategoryDefOf.BasicsImportant, \"Stat_MineableThing_Name\".Translate(), building.mineableThing.LabelCap, \"Stat_MineableThing_Desc\".Translate(), 2200, null, hyperlinks);\n\t\t\t\tStringBuilder stringBuilder6 = new StringBuilder();\n\t\t\t\tstringBuilder6.AppendLine(\"Stat_MiningYield_Desc\".Translate());\n\t\t\t\tstringBuilder6.AppendLine();\n\t\t\t\tstringBuilder6.AppendLine(\"StatsReport_DifficultyMultiplier\".Translate(Find.Storyteller.difficultyDef.label) + \": \" + Find.Storyteller.difficulty.mineYieldFactor.ToStringByStyle(ToStringStyle.PercentZero, ToStringNumberSense.Factor));\n\t\t\t\tyield return new StatDrawEntry(StatCategoryDefOf.Basics, \"Stat_MiningYield_Name\".Translate(), Mathf.CeilToInt(building.EffectiveMineableYield).ToString(\"F0\"), stringBuilder6.ToString(), 2200, null, hyperlinks);\n\t\t\t}\n\t\t\tif (building.IsTurret)\n\t\t\t{\n\t\t\t\tThingDef turret = building.turretGunDef;\n\t\t\t\tyield return new StatDrawEntry(StatCategoryDefOf.BasicsImportant, \"Stat_Weapon_Name\".Translate(), turret.LabelCap, \"Stat_Weapon_Desc\".Translate(), 5389, null, new Dialog_InfoCard.Hyperlink[1]\n\t\t\t\t{\n\t\t\t\t\tnew Dialog_InfoCard.Hyperlink(turret)\n\t\t\t\t});\n\t\t\t\tStatRequest request = StatRequest.For(turret, null);\n\t\t\t\tforeach (StatDrawEntry item8 in turret.SpecialDisplayStats(request))\n\t\t\t\t{\n\t\t\t\t\tif (item8.category == StatCategoryDefOf.Weapon_Ranged)\n\t\t\t\t\t{\n\t\t\t\t\t\tyield return item8;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tfor (int i = 0; i < turret.statBases.Count; i++)\n\t\t\t\t{\n\t\t\t\t\tStatModifier statModifier = turret.statBases[i];\n\t\t\t\t\tif (statModifier.stat.category == StatCategoryDefOf.Weapon_Ranged)\n\t\t\t\t\t{\n\t\t\t\t\t\tyield return new StatDrawEntry(StatCategoryDefOf.Weapon_Ranged, statModifier.stat, statModifier.value, request);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (ModsConfig.OdysseyActive && Fillage == FillCategory.Full)\n\t\t\t{\n\t\t\t\tbool b = building.isAirtight || (building.isStuffableAirtight && req.StuffDef.stuffProps.isAirtight);\n\t\t\t\tyield return new StatDrawEntry(StatCategoryDefOf.Building, \"Stat_Airtight\".Translate(), b.ToStringYesNo(), \"Stat_Airtight_Desc\".Translate(), 6100);\n\t\t\t}\n\t\t}\n\t\tif (IsMeat)\n\t\t{\n\t\t\tList list = new List();\n\t\t\tbool flag4 = false;\n\t\t\tforeach (ThingDef allDef in DefDatabase.AllDefs)\n\t\t\t{\n\t\t\t\tif (allDef.race != null && allDef.race.meatDef == this && !allDef.IsCorpse)\n\t\t\t\t{\n\t\t\t\t\tif (!Find.HiddenItemsManager.Hidden(allDef))\n\t\t\t\t\t{\n\t\t\t\t\t\tflag4 = true;\n\t\t\t\t\t}\n\t\t\t\t\tlist.Add(allDef);\n\t\t\t\t}\n\t\t\t}\n\t\t\tyield return new StatDrawEntry(valueString: (!flag4) ? string.Format(\"({0})\", \"NotYetDiscovered\".Translate()) : string.Join(\", \", (from x in list\n\t\t\t\twhere !Find.HiddenItemsManager.Hidden(x)\n\t\t\t\tselect x into p\n\t\t\t\tselect p.label).ToArray()).CapitalizeFirst(), category: StatCategoryDefOf.BasicsPawn, label: \"Stat_SourceSpecies_Name\".Translate(), reportText: \"Stat_SourceSpecies_Desc\".Translate(), displayPriorityWithinCategory: 1200, overrideReportTitle: null, hyperlinks: Dialog_InfoCard.DefsToHyperlinks(list));\n\t\t}\n\t\tif (IsLeather)\n\t\t{\n\t\t\tList list2 = new List();\n\t\t\tbool flag5 = false;\n\t\t\tforeach (ThingDef allDef2 in DefDatabase.AllDefs)\n\t\t\t{\n\t\t\t\tif (allDef2.race != null && allDef2.race.leatherDef == this && !allDef2.IsCorpse)\n\t\t\t\t{\n\t\t\t\t\tif (!Find.HiddenItemsManager.Hidden(allDef2))\n\t\t\t\t\t{\n\t\t\t\t\t\tflag5 = true;\n\t\t\t\t\t}\n\t\t\t\t\tlist2.Add(allDef2);\n\t\t\t\t}\n\t\t\t}\n\t\t\tyield return new StatDrawEntry(valueString: (!flag5) ? string.Format(\"({0})\", \"NotYetDiscovered\".Translate()) : string.Join(\", \", (from x in list2\n\t\t\t\twhere !Find.HiddenItemsManager.Hidden(x)\n\t\t\t\tselect x into p\n\t\t\t\tselect p.label).ToArray()).CapitalizeFirst(), category: StatCategoryDefOf.BasicsPawn, label: \"Stat_SourceSpecies_Name\".Translate(), reportText: \"Stat_SourceSpecies_Desc\".Translate(), displayPriorityWithinCategory: 1200, overrideReportTitle: null, hyperlinks: Dialog_InfoCard.DefsToHyperlinks(list2));\n\t\t}\n\t\tif (!equippedStatOffsets.NullOrEmpty())\n\t\t{\n\t\t\tfor (int i = 0; i < equippedStatOffsets.Count; i++)\n\t\t\t{\n\t\t\t\tStatDef stat = equippedStatOffsets[i].stat;\n\t\t\t\tfloat num8 = equippedStatOffsets[i].value;\n\t\t\t\tStringBuilder stringBuilder7 = new StringBuilder(stat.description);\n\t\t\t\tif (req.HasThing && stat.Worker != null)\n\t\t\t\t{\n\t\t\t\t\tstringBuilder7.AppendLine();\n\t\t\t\t\tstringBuilder7.AppendLine();\n\t\t\t\t\tstringBuilder7.AppendLine(\"StatsReport_BaseValue\".Translate() + \": \" + stat.ValueToString(num8, ToStringNumberSense.Offset, stat.finalizeEquippedStatOffset));\n\t\t\t\t\tnum8 = StatWorker.StatOffsetFromGear(req.Thing, stat);\n\t\t\t\t\tif (!stat.parts.NullOrEmpty())\n\t\t\t\t\t{\n\t\t\t\t\t\tstringBuilder7.AppendLine();\n\t\t\t\t\t\tfor (int k = 0; k < stat.parts.Count; k++)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tstring text = stat.parts[k].ExplanationPart(req);\n\t\t\t\t\t\t\tif (!text.NullOrEmpty())\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tstringBuilder7.AppendLine(text);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tstringBuilder7.AppendLine();\n\t\t\t\t\tstringBuilder7.AppendLine(\"StatsReport_FinalValue\".Translate() + \": \" + stat.ValueToString(num8, ToStringNumberSense.Offset, !stat.formatString.NullOrEmpty()));\n\t\t\t\t}\n\t\t\t\tyield return new StatDrawEntry(StatCategoryDefOf.EquippedStatOffsets, equippedStatOffsets[i].stat, num8, StatRequest.ForEmpty(), ToStringNumberSense.Offset, null, forceUnfinalizedMode: true).SetReportText(stringBuilder7.ToString());\n\t\t\t}\n\t\t}\n\t\tif (!IsDrug)\n\t\t{\n\t\t\tyield break;\n\t\t}\n\t\tforeach (StatDrawEntry item9 in DrugStatsUtility.SpecialDisplayStats(this))\n\t\t{\n\t\t\tyield return item9;\n\t\t}\n\t}\n}\n\n", + "timestamp": "2025-08-22 16:02:42,858" + } +} \ No newline at end of file From 7597cfa5fd5ade7d6f3d07d9583547d176314884 Mon Sep 17 00:00:00 2001 From: "ProjectKoi-Kalo\\Kalo" Date: Fri, 22 Aug 2025 16:21:23 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E5=A5=87=E6=80=AA=E7=9A=84=E7=BA=A2?= =?UTF-8?q?=E5=AD=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ThingDefs_Misc/Weapons/WULA_FE_Materialist_Weapon.xml | 7 ++++--- 1.6/1.6/Defs/ThingDefs_Misc/Weapons/WULA_Weapon.xml | 1 + .../Weapons/WULA_Weapon_Homing_Examples_Bullet_Homing.xml | 2 +- .../ThingDefs_Races/Races_Wulaspecies_FE_Materialist.xml | 1 - 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/1.6/1.6/Defs/ThingDefs_Misc/Weapons/WULA_FE_Materialist_Weapon.xml b/1.6/1.6/Defs/ThingDefs_Misc/Weapons/WULA_FE_Materialist_Weapon.xml index 69b23132..87c6ac2c 100644 --- a/1.6/1.6/Defs/ThingDefs_Misc/Weapons/WULA_FE_Materialist_Weapon.xml +++ b/1.6/1.6/Defs/ThingDefs_Misc/Weapons/WULA_FE_Materialist_Weapon.xml @@ -34,6 +34,7 @@ Bullet_WULA_WM_Alpha_Wolf_Plasma_Gun 1 18 + 1.0 4 3 ChargeLance_Fire @@ -96,8 +97,7 @@ WULA_RW_Unlimit_Penetrating_Beam_Cannon - - 乌拉帝国军械部在黄金时期所设计的暗物质武器,时至今日仍未被确认其实际代号。这种武器装填缓慢、体积巨大,只能由最庞大的机械体所配备,所发射的切割束几乎可以贯穿战场,并抹除落点上所有的敌人。 + 乌拉帝国军械部在黄金时期所设计的暗物质武器,时至今日仍未被确认其实际代号。这种武器装填缓慢、体积巨大,只能由最庞大的机械体所配备,所发射的切割束几乎可以贯穿战场,并抹除落点上所有的敌人。 Archotech Wula/Weapon/WULA_RW_Fractal_RF @@ -112,6 +112,7 @@ 1 16 + false
  • @@ -301,7 +302,7 @@ BeamGraser_Shooting Fleck_BeamBurn 0.32 - Mote_Wula_Dark_Magnetic_Beam + GraserBeam_End 0.35 diff --git a/1.6/1.6/Defs/ThingDefs_Misc/Weapons/WULA_Weapon.xml b/1.6/1.6/Defs/ThingDefs_Misc/Weapons/WULA_Weapon.xml index ec7a38c6..fc0df624 100644 --- a/1.6/1.6/Defs/ThingDefs_Misc/Weapons/WULA_Weapon.xml +++ b/1.6/1.6/Defs/ThingDefs_Misc/Weapons/WULA_Weapon.xml @@ -1752,6 +1752,7 @@ 5.9 75 1 + 0.1 Shot_TurretSniper GunTail_Heavy 18 diff --git a/1.6/1.6/Defs/ThingDefs_Misc/Weapons/WULA_Weapon_Homing_Examples_Bullet_Homing.xml b/1.6/1.6/Defs/ThingDefs_Misc/Weapons/WULA_Weapon_Homing_Examples_Bullet_Homing.xml index 80c81332..1e55d44c 100644 --- a/1.6/1.6/Defs/ThingDefs_Misc/Weapons/WULA_Weapon_Homing_Examples_Bullet_Homing.xml +++ b/1.6/1.6/Defs/ThingDefs_Misc/Weapons/WULA_Weapon_Homing_Examples_Bullet_Homing.xml @@ -125,7 +125,7 @@
  • Verb_Shoot true - Bullet_WULA_RW_Plasma_HomingExplosive + Bullet_WULA_RW_Plasma_HomingExplosive_Old 1.25 48 6 diff --git a/1.6/1.6/Defs/ThingDefs_Races/Races_Wulaspecies_FE_Materialist.xml b/1.6/1.6/Defs/ThingDefs_Races/Races_Wulaspecies_FE_Materialist.xml index bd4300e2..532b147e 100644 --- a/1.6/1.6/Defs/ThingDefs_Races/Races_Wulaspecies_FE_Materialist.xml +++ b/1.6/1.6/Defs/ThingDefs_Races/Races_Wulaspecies_FE_Materialist.xml @@ -336,7 +336,6 @@
  • - 9999~9999 1 9999~9999