Decompiled source of VeeItemInfo v2.0.1
plugins/com.github.vergir.VeeItemInfo.dll
Decompiled a week ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Net; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Peak; using Peak.Afflictions; using TMPro; using UnityEngine; using UnityEngine.SceneManagement; using UnityEngine.TextCore; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("com.github.vergir.VeeItemInfo")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("2.0.1.0")] [assembly: AssemblyInformationalVersion("2.0.1+d7856ba856df6d67b066c5d2dae14cb7e964e802")] [assembly: AssemblyProduct("com.github.vergir.VeeItemInfo")] [assembly: AssemblyTitle("VeeItemInfo")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("2.0.1.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace BepInEx { [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] [Conditional("CodeGeneration")] internal sealed class BepInAutoPluginAttribute : Attribute { public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null) { } } } namespace BepInEx.Preloader.Core.Patching { [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] [Conditional("CodeGeneration")] internal sealed class PatcherAutoPluginAttribute : Attribute { public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null) { } } } namespace VeeItemInfo { internal static class Blast { private const float PointBlankDistance = 0.64f; internal static bool Reachable(float radius) { return radius > 0.64f; } internal static float AntiSphereRadius(GameObject? prefab) { if ((Object)(object)prefab == (Object)null) { return 0f; } AntiSphere componentInChildren = prefab.GetComponentInChildren<AntiSphere>(true); if ((Object)(object)componentInChildren == (Object)null) { return 0f; } SphereCollider val = (((Object)(object)componentInChildren.coll != (Object)null) ? componentInChildren.coll : ((Component)componentInChildren).GetComponent<SphereCollider>()); if ((Object)(object)val == (Object)null || val.radius <= 0f) { return 0f; } GrowOverTime component = ((Component)componentInChildren).GetComponent<GrowOverTime>(); return val.radius * (((Object)(object)component != (Object)null && component.endScale > 0f) ? component.endScale : 1f); } internal static float Delivered(AOE aoe, float amount) { float num = Factor(aoe); if (num <= 0f) { return 0f; } float num2 = Mathf.Abs(amount) * num; float num3 = Mathf.Floor(num2 * GameValues.StepsPerBar) * GameValues.StatusStep; return ((amount < 0f) ? (0f - num3) : num3) * (float)Firings(aoe); } private static int Firings(AOE aoe) { return (aoe.auto ? 1 : 0) + (aoe.onEnable ? 1 : 0); } private static float Factor(AOE aoe) { if (aoe.ignoreFactor) { return 1f; } if (aoe.range <= 0f || 0.64f >= aoe.range) { return 0f; } float num = Mathf.Pow(1f - 0.64f / aoe.range, aoe.factorPow); if (!(num < aoe.minFactor)) { return num; } return 0f; } } internal static class CookingHint { private static string Fire => StatusIcons.Tag("Cook"); internal static string Good(int strength = 1) { return "<#5FD35F>" + new string('+', Mathf.Clamp(strength, 1, 3)) + "</color> " + EffectColors.Get("Cook") + Fire + "</color>"; } internal static string Bad(int strength = 1) { return "<#F55C5C>" + new string('-', Mathf.Clamp(strength, 1, 3)) + "</color> " + EffectColors.Get("Cook") + Fire + "</color>"; } private static string Destroyed() { return Bad(3); } internal static string Explodes(float radius, float injury = -1f) { string text = EffectColors.Get("Cook") + Fire + "</color><#CCCCCC> → " + EffectFormatter.PeakMetres(radius) + "</color>"; if (injury > 0f) { text = text + " " + EffectFormatter.Token(injury, "Injury"); } return text; } internal static string? Describe(GameObject item, ItemCooking? cooking) { bool consumed = IsConsumed(item); if ((Object)(object)cooking == (Object)null) { return Ladder(item, consumed, 1); } if (!cooking.canBeCooked) { return null; } int num = Mathf.Max(cooking.timesCookedLocal, cooking.preCooked); int num2 = num + 1; if (num2 > GameValues.CookingMax) { return null; } if (cooking.wreckWhenCooked) { if (num <= 0) { return Destroyed(); } return null; } int num3 = 0; AdditionalCookingBehavior[] additionalCookingBehaviors = cooking.additionalCookingBehaviors; foreach (AdditionalCookingBehavior val in additionalCookingBehaviors) { if (val == null || num2 < val.cookedAmountToTrigger || (val.onlyOnce && num >= val.cookedAmountToTrigger)) { continue; } if (!(val is CookingBehavior_Explode)) { if (!(val is CookingBehavior_Wreck)) { if (!(val is CookingBehavior_ReplaceItem)) { CookingBehavior_EnableScripts val2 = (CookingBehavior_EnableScripts)(object)((val is CookingBehavior_EnableScripts) ? val : null); if (val2 == null) { CookingBehavior_ChangeAfflictionTime val3 = (CookingBehavior_ChangeAfflictionTime)(object)((val is CookingBehavior_ChangeAfflictionTime) ? val : null); if (val3 != null) { num3 = Mathf.Max(num3, (val3.change > 0f) ? 1 : 0); } } else { num3 = Mathf.Max(num3, EnableStrength(val2)); } } else { num3 = Mathf.Max(num3, 1); } continue; } return Destroyed(); } return DescribeExplosion(cooking); } if (cooking.ignoreDefaultCookBehavior) { if (num3 <= 0) { return null; } return Good(num3); } string text = Ladder(item, consumed, num2); if (num3 > 1) { return Good(num3); } string text2 = text; if (text2 == null) { if (num3 <= 0) { return null; } text2 = Good(); } return text2; } private static string? Ladder(GameObject item, bool consumed, int next) { if (!LadderApplies(item, consumed)) { return null; } return next switch { 1 => Good(), 2 => null, _ => Bad(), }; } private static bool LadderApplies(GameObject item, bool consumed) { if (consumed) { return true; } Action_RestoreHunger[] components = item.GetComponents<Action_RestoreHunger>(); foreach (Action_RestoreHunger val in components) { if (!((ItemAction)val).OnConsumed) { return true; } } Action_GiveExtraStamina[] components2 = item.GetComponents<Action_GiveExtraStamina>(); foreach (Action_GiveExtraStamina val2 in components2) { if (!((ItemAction)val2).OnConsumed) { return true; } } return false; } internal static bool IsConsumed(GameObject item) { if (!((Object)(object)item.GetComponent<Action_Consume>() != (Object)null) && !((Object)(object)item.GetComponent<Action_ConsumeAndSpawn>() != (Object)null) && !((Object)(object)item.GetComponent<Action_SpawnGuidebookPage>() != (Object)null)) { return (Object)(object)item.GetComponent<AmuletBase>() != (Object)null; } return true; } private static int EnableStrength(CookingBehavior_EnableScripts enable) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Invalid comparison between Unknown and I4 if (enable.scriptsToEnable == null) { return 0; } int num = 0; MonoBehaviour[] scriptsToEnable = enable.scriptsToEnable; foreach (MonoBehaviour val in scriptsToEnable) { if (val is ItemAction && !((Behaviour)val).enabled) { Action_ModifyStatus val2 = (Action_ModifyStatus)(object)((val is Action_ModifyStatus) ? val : null); bool flag = val2 != null && (int)val2.statusType == 5 && val2.changeAmount < 0f; num = Mathf.Max(num, (!flag) ? 1 : 3); } } return num; } private static string DescribeExplosion(ItemCooking cooking) { //IL_0050: Unknown result type (might be due to invalid IL or missing references) GameObject explosionPrefab = cooking.explosionPrefab; if ((Object)(object)explosionPrefab == (Object)null) { return Destroyed(); } AOE val = null; float num = -1f; AOE[] componentsInChildren = explosionPrefab.GetComponentsInChildren<AOE>(true); foreach (AOE val2 in componentsInChildren) { if (!(val2.range <= 0f) && Affects(val2)) { if (val == null) { val = val2; } if ((int)val2.statusType == 0 && val2.statusAmount > 0f) { num = Mathf.Max(num, Blast.Delivered(val2, val2.statusAmount)); } } } if ((Object)(object)val == (Object)null) { StatusField componentInChildren = explosionPrefab.GetComponentInChildren<StatusField>(true); if ((Object)(object)componentInChildren != (Object)null) { return Explodes(componentInChildren.radius); } float num2 = Blast.AntiSphereRadius(explosionPrefab); if (num2 > 0f) { return Explodes(num2); } return Destroyed(); } return Explodes(val.range, num); } private static bool Affects(AOE aoe) { if (aoe.statusAmount == 0f && (aoe.addtlStatus == null || aoe.addtlStatus.Length == 0)) { if (aoe.hasAffliction) { return aoe.affliction != null; } return false; } return true; } } internal enum Block { Custom, Effects, Cooking, Weight } internal sealed class DescriptionLayout { private static readonly Block[] Order = new Block[4] { Block.Custom, Block.Effects, Block.Cooking, Block.Weight }; private readonly Dictionary<Block, List<string>> entries = new Dictionary<Block, List<string>>(); internal void Add(Block block, string? text) { if (string.IsNullOrEmpty(text) || !PluginConfig.ShowBlock(block)) { return; } string text2 = text.Trim('\n'); if (text2.Length != 0) { if (!entries.TryGetValue(block, out List<string> value)) { value = new List<string>(); entries[block] = value; } value.Add(text2); } } internal string Render() { StringBuilder stringBuilder = new StringBuilder(); Block block = Block.Custom; bool flag = true; string text = (PluginConfig.SectionSpacing.Value ? "\n\n" : "\n"); Block[] order = Order; foreach (Block block2 in order) { if (entries.TryGetValue(block2, out List<string> value) && value.Count != 0) { if (!flag) { stringBuilder.Append((block2 == Block.Weight && block == Block.Cooking) ? "\n" : text); } stringBuilder.Append(string.Join("\n", value)); block = block2; flag = false; } } return stringBuilder.ToString(); } internal static string JoinList(List<string> parts) { List<string> list = new List<string>(); foreach (string part in parts) { string text = part.Trim('\n'); if (text.Length > 0) { list.Add(text); } } return string.Join(",\n", list); } } internal static class EffectFormatter { internal const string Arrow = " → "; internal const string Infinity = "∞"; private static string[]? clearable; private static readonly STATUSTYPE[] TooRareToList; private const int IconsPerLine = 3; private static readonly Dictionary<AfflictionType, Action<Affliction, List<EffectLine>>> AfflictionHandlers; private static float StatusScale => PluginConfig.StatusScale.Value; private static int ScaleDecimals { get { float num = GameValues.StatusStep * StatusScale; for (int i = 0; i < 3; i++) { float num2 = num * Mathf.Pow(10f, (float)i); if (Mathf.Abs(num2 - Mathf.Round(num2)) < 0.001f) { return i; } } return 3; } } internal static IReadOnlyList<string> Clearable => clearable ?? (clearable = ReadClearable()); private static float UnityUnitsToMetres { get { if (!(CharacterStats.unitsToMeters > 0f)) { return 1.6f; } return CharacterStats.unitsToMeters; } } internal static string Num(float value) { return Fixed(value, 1); } private static string Fixed(float value, int decimals) { string text = value.ToString("F" + decimals, CultureInfo.InvariantCulture); if (!text.Contains('.')) { return text; } return text.TrimEnd('0').TrimEnd('.'); } internal static string Scaled(float value) { return Fixed(value * StatusScale, ScaleDecimals); } internal static string WholePoints(float fraction) { return Scaled(Mathf.Floor(fraction * 100f) / 100f); } internal static string Token(float amount, string effect) { return Colored(((amount > 0f) ? "+" : "-") + Scaled(Mathf.Abs(amount)), effect); } internal static string ConditionalOverTime(float total, float seconds, string effect) { if (total == 0f || seconds <= 0f) { return ""; } return Colored(((total > 0f) ? "+" : "-") + " 0/" + Scaled(Mathf.Abs(total)), effect) + "<#CCCCCC> / " + Seconds(seconds) + "</color>"; } internal static string Plain(float amount, string effect) { return Colored(Scaled(amount), effect); } internal static string Colored(string value, string effect) { return EffectColors.Get(effect) + value + " " + StatusIcons.Tag(effect) + "</color>"; } internal static void ForgetClearable() { clearable = null; } private static string[] ReadClearable() { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) CharacterAfflictions val = (((Object)(object)Character.observedCharacter == (Object)null) ? null : Character.observedCharacter.refs.afflictions); List<string> list = new List<string>(); foreach (STATUSTYPE value in Enum.GetValues(typeof(STATUSTYPE))) { if ((!((Object)(object)val != (Object)null) || val.StatusIsCurable(value, false, false)) && Array.IndexOf(TooRareToList, value) < 0) { string text = ((object)value/*cast due to .constrained prefix*/).ToString(); if (StatusIcons.HasIcon(text)) { list.Add(text); } } } return list.ToArray(); } internal static string Metres(float value) { return Num(value) + "m"; } internal static string PeakMetres(float unityUnits) { return Metres(PluginConfig.UnityMetres.Value ? unityUnits : (unityUnits * UnityUnitsToMetres)); } internal static string Seconds(float value) { return Num(value) + "s"; } internal static string InfiniteStamina(float seconds) { return "<#CCCCCC>" + Seconds(seconds) + "</color> " + EffectColors.Get("Extra Stamina") + "∞ " + StatusIcons.Tag("Extra Stamina") + "</color>"; } private static string Figure(float amount) { return "<#F2ECDE>" + ((amount > 0f) ? "+" : "-") + Scaled(Mathf.Abs(amount)) + "</color>"; } internal static string SharedBudget(float amount, params string[] statuses) { if (amount == 0f || statuses.Length == 0) { return ""; } return Figure(amount) + " " + IconRun(statuses, "<#F2ECDE>/</color>"); } internal static string IconRun(string[] statuses, string separator = " ") { StringBuilder stringBuilder = new StringBuilder(); for (int i = 0; i < statuses.Length; i++) { if (i > 0) { stringBuilder.Append((i % 3 == 0) ? "\n" : separator); } stringBuilder.Append(EffectColors.Get(statuses[i])).Append(StatusIcons.Tag(statuses[i])).Append("</color>"); } return stringBuilder.ToString(); } internal static string PerSecond(float amountPerSecond, string effect) { if (amountPerSecond == 0f) { return ""; } return Token(amountPerSecond, effect) + "<#CCCCCC> /s</color>"; } internal static List<EffectLine> ClearedStatuses(bool excludeCurse, IEnumerable<STATUSTYPE>? exclusions) { //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) List<string> list = new List<string>(); foreach (string item in Clearable) { bool flag = false; if (exclusions != null) { foreach (STATUSTYPE exclusion in exclusions) { if (((object)exclusion/*cast due to .constrained prefix*/).ToString() == item) { flag = true; break; } } } if (!flag) { list.Add(item); } } if (!excludeCurse) { list.Add(((object)(STATUSTYPE)5/*cast due to .constrained prefix*/).ToString()); } List<EffectLine> list2 = new List<EffectLine>(); foreach (string item2 in list) { list2.Add(new EffectLine(Token(-1f, item2), Onset.Instant, item2, -1f, 0, clears: true)); } return list2; } internal static string Effect(float amount, string effect) { if (amount == 0f) { return ""; } return Token(amount, effect) + "\n"; } internal static string OverTime(float total, float seconds, string effect) { if (total == 0f || seconds <= 0f) { return ""; } if (Mathf.Abs(total) > 1f) { return PerSecond(total / seconds, effect) + "<#CCCCCC> → " + Seconds(seconds) + "</color>"; } return Token(total, effect) + "<#CCCCCC> / " + Seconds(seconds) + "</color>"; } internal static List<EffectLine> Affliction(Affliction? affliction) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) List<EffectLine> list = new List<EffectLine>(); if (affliction != null && AfflictionHandlers.TryGetValue(affliction.GetAfflictionType(), out Action<Affliction, List<EffectLine>> value)) { value(affliction, list); } return list; } private static void DescribeFasterBoi(Affliction affliction, List<EffectLine> lines) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown Affliction_FasterBoi val = (Affliction_FasterBoi)affliction; string text = "<#CCCCCC>" + Seconds(((Affliction)val).totalTime) + "</color> " + IconRun(new string[3] { "Extra Stamina", "Extra Stamina", "Extra Stamina" }); if (val.drowsyOnEnd > 0f) { text = text + "<#CCCCCC> → </color>" + Token(val.drowsyOnEnd, "Drowsy"); } lines.Add(new EffectLine(text, Onset.OverTime, "Extra Stamina", 1f)); } private static void DescribeClearAll(Affliction affliction, List<EffectLine> lines) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown Affliction_ClearAllStatus val = (Affliction_ClearAllStatus)affliction; lines.AddRange(ClearedStatuses(val.excludeCurse, null)); } private static void DescribeAddBonusStamina(Affliction affliction, List<EffectLine> lines) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown Affliction_AddBonusStamina val = (Affliction_AddBonusStamina)affliction; lines.Add(new EffectLine(Token(val.staminaAmount, "Extra Stamina"), Onset.Instant, "Extra Stamina", val.staminaAmount)); } private static void DescribeInfiniteStamina(Affliction affliction, List<EffectLine> lines) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown Affliction_InfiniteStamina val = (Affliction_InfiniteStamina)affliction; lines.Add(new EffectLine(InfiniteStamina(((Affliction)val).totalTime), Onset.OverTime, "Extra Stamina", 1f)); if (val.drowsyAffliction != null) { lines.AddRange(Affliction(val.drowsyAffliction)); } } private static void DescribeAdjustStatus(Affliction affliction, List<EffectLine> lines) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown Affliction_AdjustStatus val = (Affliction_AdjustStatus)affliction; lines.Add(new EffectLine(Token(val.statusAmount, ((object)Unsafe.As<STATUSTYPE, STATUSTYPE>(ref val.statusType)/*cast due to .constrained prefix*/).ToString()), Onset.Instant, ((object)Unsafe.As<STATUSTYPE, STATUSTYPE>(ref val.statusType)/*cast due to .constrained prefix*/).ToString(), val.statusAmount)); } private static void DescribeDrowsyOverTime(Affliction affliction, List<EffectLine> lines) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown Affliction_AdjustDrowsyOverTime val = (Affliction_AdjustDrowsyOverTime)affliction; string text = OverTime(val.statusPerSecond * ((Affliction)val).totalTime, ((Affliction)val).totalTime, "Drowsy"); if (text.Length > 0) { lines.Add(new EffectLine(text, Onset.OverTime, "Drowsy", val.statusPerSecond)); } } private static void DescribeColdOverTime(Affliction affliction, List<EffectLine> lines) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown Affliction_AdjustColdOverTime val = (Affliction_AdjustColdOverTime)affliction; string text = OverTime(val.statusPerSecond * ((Affliction)val).totalTime, ((Affliction)val).totalTime, "Cold"); if (text.Length > 0) { lines.Add(new EffectLine(text, Onset.OverTime, "Cold", val.statusPerSecond)); } } private static void DescribeChaos(Affliction affliction, List<EffectLine> lines) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) foreach (string item in Clearable) { lines.Add(new EffectLine(Reshuffled(item), Onset.Instant, item, -1f)); } string status = ((object)(STATUSTYPE)5/*cast due to .constrained prefix*/).ToString(); lines.Add(new EffectLine(Reshuffled(status), Onset.Instant, status, -1f)); } private static void DescribeInvincibility(Affliction affliction, List<EffectLine> lines) { lines.Add(new EffectLine("<#CCCCCC>" + Seconds(affliction.totalTime) + "</color> " + EffectColors.Get("Shield") + StatusIcons.Tag("Shield") + "</color>", Onset.OverTime, "Shield", 1f)); } private static void DescribeRadiateInfiniteStam(Affliction affliction, List<EffectLine> lines) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown Affliction_RadiateInfiniteStam val = (Affliction_RadiateInfiniteStam)affliction; lines.Add(new EffectLine(InfiniteStamina(((Affliction)val).totalTime) + "<#CCCCCC> " + PeakMetres(val.radius) + "</color>", Onset.OverTime, "Extra Stamina", 1f)); } private static void DescribeMassSuperJump(Affliction affliction, List<EffectLine> lines) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown Affliction_MassSuperJump val = (Affliction_MassSuperJump)affliction; string status = ((val.lowGravAmount >= 3 && StatusIcons.HasIcon("FloatBunch")) ? "FloatBunch" : "Float"); lines.Add(new EffectLine("<#CCCCCC>" + Seconds(val.lowGravTime) + "</color> " + EffectColors.Get("Float") + StatusIcons.Tag(status) + "</color><#CCCCCC> " + PeakMetres(val.radius) + "</color>", Onset.OverTime, "Float", 1f)); } private static void DescribeSunscreen(Affliction affliction, List<EffectLine> lines) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown Affliction_Sunscreen val = (Affliction_Sunscreen)affliction; lines.Add(new EffectLine("<#CCCCCC>" + Seconds(((Affliction)val).totalTime) + "</color>", Onset.OverTime)); } private static string Reshuffled(string status) { return Token(-1f, status) + "<#CCCCCC> → </color>" + EffectColors.Get(status) + "+? " + StatusIcons.Tag(status) + "</color>"; } static EffectFormatter() { STATUSTYPE[] array = new STATUSTYPE[3]; RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); TooRareToList = (STATUSTYPE[])(object)array; AfflictionHandlers = new Dictionary<AfflictionType, Action<Affliction, List<EffectLine>>> { { (AfflictionType)2, DescribeFasterBoi }, { (AfflictionType)8, DescribeClearAll }, { (AfflictionType)10, DescribeAddBonusStamina }, { (AfflictionType)1, DescribeInfiniteStamina }, { (AfflictionType)7, DescribeAdjustStatus }, { (AfflictionType)11, DescribeDrowsyOverTime }, { (AfflictionType)5, DescribeColdOverTime }, { (AfflictionType)6, DescribeChaos }, { (AfflictionType)16, DescribeInvincibility }, { (AfflictionType)24, DescribeRadiateInfiniteStam }, { (AfflictionType)25, DescribeMassSuperJump }, { (AfflictionType)13, DescribeSunscreen } }; } } internal enum Onset { Instant, OverTime } internal readonly struct EffectLine { internal string Text { get; } internal Onset Onset { get; } internal string Status { get; } internal float Amount { get; } internal int Source { get; } internal bool Clears { get; } internal EffectLine(string text, Onset onset, string status = "", float amount = 0f, int source = 0, bool clears = false) { Text = text; Onset = onset; Status = status; Amount = amount; Source = source; Clears = clears; } internal EffectLine WithSource(int source) { return new EffectLine(Text, Onset, Status, Amount, source, Clears); } } internal static class EffectOrder { private static readonly string[] Order = new string[19] { ((object)(STATUSTYPE)1/*cast due to .constrained prefix*/).ToString(), "Extra Stamina", ((object)(STATUSTYPE)0/*cast due to .constrained prefix*/).ToString(), ((object)(STATUSTYPE)3/*cast due to .constrained prefix*/).ToString(), ((object)(STATUSTYPE)10/*cast due to .constrained prefix*/).ToString(), ((object)(STATUSTYPE)2/*cast due to .constrained prefix*/).ToString(), ((object)(STATUSTYPE)8/*cast due to .constrained prefix*/).ToString(), ((object)(STATUSTYPE)6/*cast due to .constrained prefix*/).ToString(), ((object)(STATUSTYPE)9/*cast due to .constrained prefix*/).ToString(), ((object)(STATUSTYPE)11/*cast due to .constrained prefix*/).ToString(), ((object)(STATUSTYPE)14/*cast due to .constrained prefix*/).ToString(), ((object)(STATUSTYPE)4/*cast due to .constrained prefix*/).ToString(), ((object)(STATUSTYPE)12/*cast due to .constrained prefix*/).ToString(), "Shield", "Numb", "Float", ((object)(STATUSTYPE)5/*cast due to .constrained prefix*/).ToString(), ((object)(STATUSTYPE)13/*cast due to .constrained prefix*/).ToString(), ((object)(STATUSTYPE)7/*cast due to .constrained prefix*/).ToString() }; private static readonly Dictionary<string, int> Ranks = BuildRanks(); private static Dictionary<string, int> BuildRanks() { Dictionary<string, int> dictionary = new Dictionary<string, int>(); for (int i = 0; i < Order.Length; i++) { dictionary[Order[i]] = i; } return dictionary; } internal static int Rank(string status) { if (!Ranks.TryGetValue(status, out var value)) { return Order.Length; } return value; } internal static void Sort(List<EffectLine> lines) { DropRedundantClears(lines); List<(EffectLine, int)> list = new List<(EffectLine, int)>(lines.Count); for (int i = 0; i < lines.Count; i++) { list.Add((lines[i], i)); } list.Sort(delegate((EffectLine Line, int Index) a, (EffectLine Line, int Index) b) { int num2 = Compare(a.Line, b.Line); return (num2 == 0) ? a.Index.CompareTo(b.Index) : num2; }); for (int num = 0; num < lines.Count; num++) { lines[num] = list[num].Item1; } MergeRepeats(lines); } private static void MergeRepeats(List<EffectLine> lines) { for (int num = lines.Count - 2; num >= 0; num--) { if (CanMerge(lines[num], lines[num + 1])) { EffectLine effectLine = lines[num]; float amount = effectLine.Amount + lines[num + 1].Amount; lines[num] = new EffectLine(EffectFormatter.Token(amount, effectLine.Status), effectLine.Onset, effectLine.Status, amount, effectLine.Source); lines.RemoveAt(num + 1); } } } private static bool CanMerge(EffectLine a, EffectLine b) { if (a.Status.Length > 0 && a.Status == b.Status && a.Onset == b.Onset && a.Amount > 0f == b.Amount > 0f && !a.Clears && !b.Clears && IsPlainToken(a)) { return IsPlainToken(b); } return false; } private static bool IsPlainToken(EffectLine line) { if (line.Amount != 0f) { return line.Text == EffectFormatter.Token(line.Amount, line.Status); } return false; } private static void DropRedundantClears(List<EffectLine> lines) { HashSet<string> removedAnyway = new HashSet<string>(); foreach (EffectLine line in lines) { if (!line.Clears && line.Amount < 0f) { removedAnyway.Add(Key(line)); } } if (removedAnyway.Count > 0) { lines.RemoveAll((EffectLine line) => line.Clears && removedAnyway.Contains(Key(line))); } } private static string Key(EffectLine line) { return line.Onset.ToString() + "|" + line.Status; } private static int Compare(EffectLine a, EffectLine b) { int num = IsPrice(a).CompareTo(IsPrice(b)); if (num != 0) { return num; } int num2 = a.Onset.CompareTo(b.Onset); if (num2 != 0) { return num2; } int num3 = Rank(a.Status).CompareTo(Rank(b.Status)); if (num3 != 0) { return num3; } return a.Source.CompareTo(b.Source); } private static int IsPrice(EffectLine line) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) return (line.Status == ((object)(STATUSTYPE)13/*cast due to .constrained prefix*/).ToString()) ? 1 : 0; } } internal static class GameValues { internal static float StatusStep { get; } = Constant(typeof(CharacterAfflictions), "STATUS_INCREMENT", 0.025f, positive: true); internal static float StepsPerBar => 1f / StatusStep; internal static int CookingMax { get; } = Constant(typeof(ItemCooking), "COOKING_MAX", 12); private static int Constant(Type owner, string name, int compiled) { try { FieldInfo field = owner.GetField(name, BindingFlags.Static | BindingFlags.Public); if (field != null && field.IsLiteral && field.GetRawConstantValue() is int num && num > 0) { return num; } Warn(owner, name, compiled, (field == null) ? "no such constant" : "unusable value"); } catch (Exception ex) { Warn(owner, name, compiled, ex.Message); } return compiled; } private static float Constant(Type owner, string name, float compiled, bool positive) { try { FieldInfo field = owner.GetField(name, BindingFlags.Static | BindingFlags.Public); if (field != null && field.IsLiteral && field.GetRawConstantValue() is float num && (!positive || num > 0f)) { return num; } Warn(owner, name, compiled, (field == null) ? "no such constant" : "unusable value"); } catch (Exception ex) { Warn(owner, name, compiled, ex.Message); } return compiled; } private static void Warn(Type owner, string name, float compiled, string why) { Plugin.Log.LogWarning((object)("Could not read " + owner.Name + "." + name + " from the game (" + why + "); " + $"using the value this build was compiled against, {compiled}. " + "Numbers derived from it may be wrong if the game has changed it.")); } } internal static class ItemDescriptionBuilder { private sealed class Parts { internal Item Entity { get; } internal DescriptionLayout Layout { get; } internal List<EffectLine> Effects { get; } internal GameObject Item { get; } internal bool Consumed { get; } internal int Source { get; set; } internal Parts(DescriptionLayout layout, List<EffectLine> effects, Item entity, bool consumed) { Layout = layout; Effects = effects; Entity = entity; Item = ((Component)entity).gameObject; Consumed = consumed; } } private static readonly string[] HealAllStatuses = ReadHealAllStatuses(); private static readonly Dictionary<Type, Action<Component, Parts>> Handlers = new Dictionary<Type, Action<Component, Parts>> { { typeof(Action_RestoreHunger), DescribeRestoreHunger }, { typeof(Action_GiveExtraStamina), DescribeGiveExtraStamina }, { typeof(Action_InflictPoison), DescribeInflictPoison }, { typeof(Action_AddOrRemoveThorns), DescribeAddOrRemoveThorns }, { typeof(Action_ModifyStatus), DescribeModifyStatus }, { typeof(Action_ApplyAffliction), DescribeApplyAffliction }, { typeof(Action_Numb), DescribeNumb }, { typeof(Action_Die), DescribeDie }, { typeof(RitualDaggerFeedBehavior), DescribeRitualDaggerFeedBehavior }, { typeof(Action_RandomMushroomEffect), DescribeRandomMushroomEffect }, { typeof(Action_ClearAllStatus), DescribeClearAllStatus }, { typeof(Action_ApplyMassAffliction), DescribeApplyMassAffliction }, { typeof(Action_RaycastDart), DescribeRaycastDart }, { typeof(Lantern), DescribeLanternItem }, { typeof(Candle), DescribeLanternItem }, { typeof(Constructable), DescribeConstructable }, { typeof(RopeShooter), DescribeRopeShooter }, { typeof(VineShooter), DescribeVineShooter }, { typeof(Action_RaycastSpawnSomething), DescribeRaycastSpawnSomething }, { typeof(MagicBean), DescribeMagicBean }, { typeof(ShelfShroom), DescribeShelfShroom }, { typeof(Breakable), DescribeBreakable }, { typeof(Action_MoraleBoost), DescribeMoraleBoost }, { typeof(Dynamite), DescribeDynamite }, { typeof(Action_Spawn), DescribeSpawn }, { typeof(Scorpion), DescribeScorpion }, { typeof(StickyItemComponent), DescribeStickyItemComponent }, { typeof(BingBongShieldWhileHolding), DescribeBingBongShieldWhileHolding }, { typeof(Action_HealingGem), DescribeHealingGem }, { typeof(Action_CloneSelectedItem), DescribeCloneSelectedItem }, { typeof(Action_SuperJumpAmulet), DescribeSuperJumpAmulet } }; private static readonly Dictionary<Type, Action<Component, Parts>?> Resolved = new Dictionary<Type, Action<Component, Parts>>(); private const float MushroomStaminaPerRoll = 0.05f; private const float MaxMushroomStamina = 0.15f; private static Dictionary<string, List<Item>>? twinsByName; private const float HeldDynamiteInjury = 0.25f; internal static bool AssumeHuman { get; set; } private static string[] ReadHealAllStatuses() { STATUSTYPE[] statusesToHeal = Affliction_HealAll.statusesToHeal; string[] array = new string[statusesToHeal.Length]; for (int i = 0; i < statusesToHeal.Length; i++) { array[i] = ((object)Unsafe.As<STATUSTYPE, STATUSTYPE>(ref statusesToHeal[i])/*cast due to .constrained prefix*/).ToString(); } return array; } internal static string Build(Item item) { GameObject gameObject = ((Component)item).gameObject; Component[] components = gameObject.GetComponents(typeof(Component)); DescriptionLayout descriptionLayout = new DescriptionLayout(); bool flag = CookingHint.IsConsumed(gameObject); List<EffectLine> list = new List<EffectLine>(); float amount = (float)item.CarryWeight * GameValues.StatusStep; descriptionLayout.Add(Block.Weight, EffectFormatter.Plain(amount, "Weight")); Parts parts = new Parts(descriptionLayout, list, item, flag); for (int i = 0; i < components.Length; i++) { if ((Object)(object)components[i] == (Object)null) { continue; } Component obj = components[i]; Behaviour val = (Behaviour)(object)((obj is Behaviour) ? obj : null); if (val != null && !val.enabled) { continue; } if (!flag) { Component obj2 = components[i]; ItemAction val2 = (ItemAction)(object)((obj2 is ItemAction) ? obj2 : null); if (val2 != null && val2.OnConsumed) { continue; } } Action<Component, Parts> action = HandlerFor(((object)components[i]).GetType()); if (action != null) { parts.Source = i; action(components[i], parts); } } if (PluginConfig.HidePoisonTwins.Value && (Object)(object)gameObject.GetComponent<Action_InflictPoison>() == (Object)null) { Action_InflictPoison val3 = PoisonousTwin(item); if ((Object)(object)val3 != (Object)null) { Collect(list, components.Length, EffectFormatter.ConditionalOverTime(val3.poisonPerSecond * val3.inflictionTime, val3.inflictionTime, "Poison"), Onset.OverTime, "Poison", val3.poisonPerSecond); } } EmitEffects(descriptionLayout, list); ItemCooking component = gameObject.GetComponent<ItemCooking>(); if ((Object)(object)component == (Object)null || ((Behaviour)component).enabled) { descriptionLayout.Add(Block.Cooking, CookingHint.Describe(gameObject, component)); } return descriptionLayout.Render(); } private static Action<Component, Parts>? HandlerFor(Type type) { if (Resolved.TryGetValue(type, out Action<Component, Parts> value)) { return value; } Action<Component, Parts> action = null; Type type2 = type; while (type2 != null) { if (Handlers.TryGetValue(type2, out Action<Component, Parts> value2)) { action = value2; break; } type2 = type2.BaseType; } Resolved[type] = action; return action; } private static void Collect(List<EffectLine> into, int source, string? text, Onset onset, string status = "", float amount = 0f) { if (!string.IsNullOrEmpty(text)) { string text2 = text.Trim('\n'); if (text2.Length > 0) { into.Add(new EffectLine(text2, onset, status, amount, source)); } } } private static void Collect(List<EffectLine> into, int source, List<EffectLine> lines) { foreach (EffectLine line in lines) { into.Add(line.WithSource(source)); } } private static void EmitEffects(DescriptionLayout layout, List<EffectLine> effects) { EffectOrder.Sort(effects); foreach (EffectLine effect in effects) { layout.Add(Block.Effects, effect.Text); } } private static List<EffectLine> DescribeMushroom(Action_RandomMushroomEffect effect) { List<EffectLine> list = new List<EffectLine>(); MushroomManager instance = MushroomManager.instance; if ((Object)(object)instance == (Object)null || instance.mushroomEffects == null || instance.mushroomEffects.Length == 0) { list.Add(new EffectLine("<#F2ECDE>????</color>", Onset.Instant)); return list; } int num = effect.mushroomTypeIndex % instance.mushroomEffects.Length; if (PluginConfig.EnergySpoiler.Value && instance.mushroomStamAmt != null && num < instance.mushroomStamAmt.Length) { float amount = (float)instance.mushroomStamAmt[num] * 0.05f; Collect(list, 0, EffectFormatter.Effect(amount, "Extra Stamina"), Onset.Instant, "Extra Stamina", amount); } else { list.Add(new EffectLine(EffectFormatter.Colored("+0-" + EffectFormatter.Scaled(0.15f), "Extra Stamina"), Onset.Instant, "Extra Stamina", 0.15f)); } string text; if (!PluginConfig.ShroomberryHint.Value) { text = "<#F2ECDE>????</color>"; } else if (num < instance.minGoodEffects) { text = "<#5FD35F>????</color>"; } else if (num < instance.minGoodEffects + instance.minBadEffects) { text = "<#F55C5C>????</color>"; } else if (PluginConfig.PurpleSpoiler.Value) { int value = instance.mushroomEffects[num]; text = ((Array.IndexOf(Action_RandomMushroomEffect.GoodEffects, value) >= 0) ? "<#5FD35F>" : "<#F55C5C>") + "????</color>"; } else { text = "<#5FD35F>??</color><#F55C5C>??</color>"; } list.Add(new EffectLine(text, Onset.Instant)); return list; } private static void DescribeRestoreHunger(Component component, Parts parts) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown Action_RestoreHunger val = (Action_RestoreHunger)component; Collect(parts.Effects, parts.Source, EffectFormatter.Effect(val.restorationAmount * -1f, "Hunger"), Onset.Instant, "Hunger", val.restorationAmount * -1f); } private static void DescribeGiveExtraStamina(Component component, Parts parts) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown Action_GiveExtraStamina val = (Action_GiveExtraStamina)component; Collect(parts.Effects, parts.Source, EffectFormatter.Effect(val.amount, "Extra Stamina"), Onset.Instant, "Extra Stamina", val.amount); } private static void DescribeInflictPoison(Component component, Parts parts) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown Action_InflictPoison val = (Action_InflictPoison)component; float total = val.poisonPerSecond * val.inflictionTime; string text = ((PluginConfig.HidePoisonTwins.Value && HasSafeTwin(parts.Entity)) ? EffectFormatter.ConditionalOverTime(total, val.inflictionTime, "Poison") : EffectFormatter.OverTime(total, val.inflictionTime, "Poison")); Collect(parts.Effects, parts.Source, text, Onset.OverTime, "Poison", val.poisonPerSecond); } private static IEnumerable<Item> Twins(Item item) { if (twinsByName == null) { twinsByName = BuildTwins(); } string key = SafeName(item); if (!twinsByName.TryGetValue(key, out List<Item> value)) { yield break; } foreach (Item item2 in value) { if (((Object)((Component)item2).gameObject).name != ((Object)((Component)item).gameObject).name.Replace("(Clone)", "")) { yield return item2; } } } internal static void Forget() { twinsByName = null; } private static Dictionary<string, List<Item>> BuildTwins() { Dictionary<string, List<Item>> dictionary = new Dictionary<string, List<Item>>(StringComparer.Ordinal); foreach (Item item in StatusIcons.AllItems()) { string key = SafeName(item); if (!dictionary.TryGetValue(key, out var value)) { value = (dictionary[key] = new List<Item>()); } value.Add(item); } return dictionary; } private static string SafeName(Item item) { try { return item.GetName(); } catch (Exception) { return ((Object)((Component)item).gameObject).name; } } private static bool HasSafeTwin(Item item) { foreach (Item item2 in Twins(item)) { if ((Object)(object)((Component)item2).GetComponent<Action_InflictPoison>() == (Object)null) { return true; } } return false; } private static Action_InflictPoison? PoisonousTwin(Item item) { foreach (Item item2 in Twins(item)) { Action_InflictPoison component = ((Component)item2).GetComponent<Action_InflictPoison>(); if ((Object)(object)component != (Object)null) { return component; } } return null; } private static void DescribeAddOrRemoveThorns(Component component, Parts parts) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown Action_AddOrRemoveThorns val = (Action_AddOrRemoveThorns)component; float amount = (float)val.thornCount * ThornStatus(); Collect(parts.Effects, parts.Source, EffectFormatter.Effect(amount, "Thorns"), Onset.Instant, "Thorns", amount); } private static float ThornStatus() { if (RunSettings.GetValue((SETTINGTYPE)2200, false) == 0) { return 0f; } Character observedCharacter = Character.observedCharacter; if ((Object)(object)observedCharacter != (Object)null && observedCharacter.refs != null && (Object)(object)observedCharacter.refs.afflictions != (Object)null && observedCharacter.refs.afflictions.physicalThorns != null) { foreach (ThornOnMe physicalThorn in observedCharacter.refs.afflictions.physicalThorns) { if ((Object)(object)physicalThorn != (Object)null && physicalThorn.isThorn) { return (float)physicalThorn.GetThornDamage() * GameValues.StatusStep; } } } return 2f * GameValues.StatusStep; } private static void DescribeModifyStatus(Component component, Parts parts) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Invalid comparison between Unknown and I4 //IL_0052: Unknown result type (might be due to invalid IL or missing references) Action_ModifyStatus val = (Action_ModifyStatus)component; string status = ((object)Unsafe.As<STATUSTYPE, STATUSTYPE>(ref val.statusType)/*cast due to .constrained prefix*/).ToString(); Collect(parts.Effects, parts.Source, Change(val, status, parts), Onset.Instant, status, val.changeAmount); if ((int)val.statusType == 3 && val.changeAmount < 0f) { string status2 = ((object)(STATUSTYPE)10/*cast due to .constrained prefix*/).ToString(); Collect(parts.Effects, parts.Source, Change(val, status2, parts), Onset.Instant, status2, val.changeAmount); } } private static string Change(Action_ModifyStatus effect, string status, Parts parts) { if (!effect.ifSkeleton || SkeletonGateOpen(parts.Item)) { return EffectFormatter.Effect(effect.changeAmount, status); } return ""; } private static bool SkeletonGateOpen(GameObject item) { bool flag = (Object)(object)item.GetComponent<Action_BecomeSkeleton>() != (Object)null; return IsSkeleton() != flag; } private static bool IsSkeleton() { if (AssumeHuman) { return false; } Character observedCharacter = Character.observedCharacter; if ((Object)(object)observedCharacter != (Object)null && (Object)(object)observedCharacter.data != (Object)null) { return observedCharacter.data.isSkeleton; } return false; } private static void DescribeApplyAffliction(Component component, Parts parts) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown Action_ApplyAffliction val = (Action_ApplyAffliction)component; CollectAfflictions(parts, val.affliction, val.extraAfflictions); } private static void CollectAfflictions(Parts parts, Affliction? affliction, Affliction[]? extras) { Collect(parts.Effects, parts.Source, EffectFormatter.Affliction(affliction)); if (extras != null) { foreach (Affliction affliction2 in extras) { Collect(parts.Effects, parts.Source, EffectFormatter.Affliction(affliction2)); } } } private static void DescribeNumb(Component component, Parts parts) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown Action_Numb val = (Action_Numb)component; Collect(parts.Effects, parts.Source, EffectFormatter.Colored(EffectFormatter.Seconds(val.numbAmount), "Numb"), Onset.OverTime, "Numb", 1f); } private static void DescribeDie(Component component, Parts parts) { parts.Layout.Add(Block.Custom, "<#F55C5C>???</color>"); } private static void DescribeRitualDaggerFeedBehavior(Component component, Parts parts) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown RitualDaggerFeedBehavior val = (RitualDaggerFeedBehavior)component; Collect(parts.Effects, parts.Source, EffectFormatter.ClearedStatuses(excludeCurse: true, null)); Collect(parts.Effects, parts.Source, EffectFormatter.Effect(val.bonusStamina, "Extra Stamina"), Onset.Instant, "Extra Stamina", val.bonusStamina); if (val.infiniteStaminaTime > 0f) { Collect(parts.Effects, parts.Source, EffectFormatter.InfiniteStamina(val.infiniteStaminaTime), Onset.OverTime, "Extra Stamina", 1f); } } private static void DescribeRandomMushroomEffect(Component component, Parts parts) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown Collect(parts.Effects, parts.Source, DescribeMushroom((Action_RandomMushroomEffect)component)); } private static void DescribeClearAllStatus(Component component, Parts parts) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown Action_ClearAllStatus val = (Action_ClearAllStatus)component; Collect(parts.Effects, parts.Source, EffectFormatter.ClearedStatuses(val.excludeCurse, val.otherExclusions)); } private static void DescribeApplyMassAffliction(Component component, Parts parts) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown Action_ApplyMassAffliction val = (Action_ApplyMassAffliction)component; MagicBugle component2 = parts.Item.GetComponent<MagicBugle>(); if ((Object)(object)component2 != (Object)null && (Object)(object)component2.massAffliction == (Object)(object)val) { Collect(parts.Effects, parts.Source, EffectFormatter.Colored("∞", "Extra Stamina") + "<#CCCCCC> " + EffectFormatter.PeakMetres(val.radius) + "</color>", Onset.OverTime, "Extra Stamina", 1f); } else { CollectAfflictions(parts, ((Action_ApplyAffliction)val).affliction, ((Action_ApplyAffliction)val).extraAfflictions); } } private static void DescribeRaycastDart(Component component, Parts parts) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown Action_RaycastDart val = (Action_RaycastDart)component; for (int i = 0; i < val.afflictionsOnHit.Length; i++) { Collect(parts.Effects, parts.Source, EffectFormatter.Affliction(val.afflictionsOnHit[i])); } } private static void DescribeLanternItem(Component component, Parts parts) { Collect(parts.Effects, parts.Source, DescribeLantern(parts.Item)); } private static void DescribeConstructable(Component component, Parts parts) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown Constructable val = (Constructable)component; Campfire val2 = (((Object)(object)val.constructedPrefab == (Object)null) ? null : val.constructedPrefab.GetComponent<Campfire>()); if ((Object)(object)val2 != (Object)null) { parts.Layout.Add(Block.Custom, "<#CCCCCC>" + EffectFormatter.Seconds(val2.burnsFor) + "</color> " + EffectColors.Get("Cook") + StatusIcons.Tag("Cook") + "</color>"); } Collect(parts.Effects, parts.Source, DescribeEmitters(val.constructedPrefab)); } private static void DescribeRopeShooter(Component component, Parts parts) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown RopeShooter val = (RopeShooter)component; bool flag = (Object)(object)parts.Item.GetComponent<Antigrav>() != (Object)null; parts.Layout.Add(Block.Custom, EffectFormatter.Colored(EffectFormatter.PeakMetres(val.maxLength), flag ? "RopeCannonAnti" : "RopeCannon")); float num = RopeSegmentLength(val); string value = ((PluginConfig.RealRopeLength.Value && num > 0f) ? EffectFormatter.PeakMetres(val.length * num) : EffectFormatter.Metres(Rope.GetLengthInMeters(val.length))); parts.Layout.Add(Block.Custom, EffectFormatter.Colored(value, flag ? "RopeSpoolAnti" : "RopeSpool")); } private static void DescribeVineShooter(Component component, Parts parts) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown VineShooter val = (VineShooter)component; parts.Layout.Add(Block.Custom, ReachInUnits(val.maxLength)); } private static void DescribeRaycastSpawnSomething(Component component, Parts parts) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown Action_RaycastSpawnSomething val = (Action_RaycastSpawnSomething)component; if (!((Object)(object)val.prefabToSpawn == (Object)null)) { float num = Blast.AntiSphereRadius(val.prefabToSpawn); if (num > 0f) { parts.Layout.Add(Block.Custom, ReachInUnits(num)); } } } private static void DescribeMagicBean(Component component, Parts parts) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown MagicBean val = (MagicBean)component; if ((Object)(object)val.plantPrefab != (Object)null) { parts.Layout.Add(Block.Custom, ReachInUnits(val.plantPrefab.maxLength)); } } private static void DescribeShelfShroom(Component component, Parts parts) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) DescribeBlasts(((ShelfShroom)component).instantiateOnBreak, parts, showRange: false); } private static void DescribeBreakable(Component component, Parts parts) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown Breakable val = (Breakable)component; if (val.instantiateNonItemOnBreak == null || parts.Consumed || (Object)(object)parts.Item.GetComponent<Action_ReduceUses>() != (Object)null) { return; } foreach (GameObject item in val.instantiateNonItemOnBreak) { DescribeBlasts(item, parts, showRange: false); } } private static void DescribeMoraleBoost(Component component, Parts parts) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown Action_MoraleBoost val = (Action_MoraleBoost)component; Collect(parts.Effects, parts.Source, EffectFormatter.Effect(val.baselineStaminaBoost, "Extra Stamina"), Onset.Instant, "Extra Stamina", val.baselineStaminaBoost); } private static void DescribeDynamite(Component component, Parts parts) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown Dynamite val = (Dynamite)component; Collect(parts.Effects, parts.Source, EffectFormatter.Effect(0.25f, "Injury"), Onset.Instant, "Injury", 0.25f); DescribeBlasts(val.explosionPrefab, parts, showRange: true); } private static void DescribeSpawn(Component component, Parts parts) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) DescribeBlasts(((Action_Spawn)component).objectToSpawn, parts, showRange: false); } private static void DescribeBlasts(GameObject? prefab, Parts parts, bool showRange) { //IL_0090: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)prefab == (Object)null) { return; } AOE[] componentsInChildren = prefab.GetComponentsInChildren<AOE>(true); foreach (AOE val in componentsInChildren) { TimeEvent component = ((Component)val).GetComponent<TimeEvent>(); float seconds = (((Object)(object)component != (Object)null && component.repeating && component.rate > 0f) ? Lifetime(((Component)val).transform) : 0f); string suffix = (showRange ? ("<#CCCCCC> " + EffectFormatter.PeakMetres(val.range) + "</color>") : ""); List<EffectLine> list = new List<EffectLine>(); AddBlast(list, val, val.statusType, val.statusAmount, component, seconds, suffix); int num = 0; while (val.addtlStatus != null && num < val.addtlStatus.Length) { float amount = ((val.addlStatusAmountOverrides != null && num < val.addlStatusAmountOverrides.Count) ? val.addlStatusAmountOverrides[num] : val.statusAmount); AddBlast(list, val, val.addtlStatus[num], amount, component, seconds, suffix); num++; } if (val.hasAffliction && val.affliction != null) { list.AddRange(EffectFormatter.Affliction(val.affliction)); } Collect(parts.Effects, parts.Source, list); } } private static void DescribeScorpion(Component component, Parts parts) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown Scorpion val = (Scorpion)component; Collect(parts.Effects, parts.Source, EffectFormatter.Colored(EffectFormatter.Scaled(0.5f) + "-" + EffectFormatter.Scaled(1.05f), "Poison") + "<#CCCCCC> / " + EffectFormatter.Seconds(val.totalPoisonTime) + "</color>", Onset.OverTime, "Poison", 1f); } private static void DescribeStickyItemComponent(Component component, Parts parts) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown StickyItemComponent val = (StickyItemComponent)component; parts.Layout.Add(Block.Custom, EffectFormatter.Effect((float)val.addThornsToStuckPlayer * GameValues.StatusStep, "Thorns")); } private static void DescribeBingBongShieldWhileHolding(Component component, Parts parts) { parts.Layout.Add(Block.Custom, EffectFormatter.Colored("∞", "Shield")); } private static void DescribeHealingGem(Component component, Parts parts) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown Action_HealingGem val = (Action_HealingGem)component; Collect(parts.Effects, parts.Source, EffectFormatter.SharedBudget(0f - val.healingAffliction.maxHealing, HealAllStatuses), Onset.Instant, HealAllStatuses[0], -1f); if (val.invincibilityAffliction != null) { Collect(parts.Effects, parts.Source, "<#CCCCCC>" + EffectFormatter.Seconds(val.invincibilityAffliction.totalTime) + "</color> " + EffectColors.Get("Shield") + StatusIcons.Tag("Shield") + "</color>", Onset.OverTime, "Shield", 1f); } Collect(parts.Effects, parts.Source, EffectColors.Get("Petrify") + "+" + EffectFormatter.WholePoints(val.minPetrify) + "-" + EffectFormatter.WholePoints(val.maxPetrify) + " " + StatusIcons.Tag("Petrify") + "</color>", Onset.Instant, "Petrify", 1f); } private static void DescribeCloneSelectedItem(Component component, Parts parts) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown Action_CloneSelectedItem val = (Action_CloneSelectedItem)component; string text = "<#F2ECDE>" + StatusIcons.Tag("Item") + "</color>"; parts.Layout.Add(Block.Custom, text + "<#CCCCCC> → </color>" + text + text); Collect(parts.Effects, parts.Source, EffectColors.Get("Petrify") + "+" + EffectFormatter.WholePoints((float)val.petrify / 100f) + "/" + EffectFormatter.WholePoints((float)val.petrifyMystical / 100f) + " " + StatusIcons.Tag("Petrify") + "</color>", Onset.Instant, "Petrify", 1f); } private static void DescribeSuperJumpAmulet(Component component, Parts parts) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown Action_SuperJumpAmulet val = (Action_SuperJumpAmulet)component; CollectAfflictions(parts, ((Action_ApplyAffliction)val).affliction, ((Action_ApplyAffliction)val).extraAfflictions); if (val.petrifyPerUse != 0f) { Collect(parts.Effects, parts.Source, EffectFormatter.Colored("+" + EffectFormatter.WholePoints(val.petrifyPerUse), "Petrify"), Onset.Instant, "Petrify", val.petrifyPerUse); } } internal static float RopeSegmentLength(RopeShooter shooter) { //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) RopeAnchorWithRope val = (((Object)(object)shooter.ropeAnchorWithRopePref == (Object)null) ? null : shooter.ropeAnchorWithRopePref.GetComponent<RopeAnchorWithRope>()); Rope val2 = (((Object)(object)val == (Object)null || (Object)(object)val.ropePrefab == (Object)null) ? null : val.ropePrefab.GetComponent<Rope>()); if ((Object)(object)val2 == (Object)null || (Object)(object)val2.ropeSegmentPrefab == (Object)null) { return 0f; } ConfigurableJoint component = val2.ropeSegmentPrefab.GetComponent<ConfigurableJoint>(); float num = (((Object)(object)component == (Object)null) ? 0f : Mathf.Abs(((Joint)component).anchor.y)); float y = val2.ropeSegmentPrefab.transform.localScale.y; return (num + val2.spacing) * y; } private static string ReachInUnits(float unityUnits) { return "<#CCCCCC>" + EffectFormatter.PeakMetres(unityUnits) + "</color>"; } private static List<EffectLine> DescribeLantern(GameObject itemGameObj) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) List<EffectLine> list = new List<EffectLine>(); StatusField componentInChildren = itemGameObj.GetComponentInChildren<StatusField>(true); if ((Object)(object)componentInChildren == (Object)null) { return list; } Dictionary<STATUSTYPE, float> dictionary = new Dictionary<STATUSTYPE, float>(); Accumulate(dictionary, ((StatusFieldBase)componentInChildren).statusType, ((StatusFieldBase)componentInChildren).statusAmountPerSecond); foreach (StatusFieldStatus additionalStatus in ((StatusFieldBase)componentInChildren).additionalStatuses) { Accumulate(dictionary, additionalStatus.statusType, ((StatusFieldBase)componentInChildren).statusAmountPerSecond); } if (dictionary.TryGetValue((STATUSTYPE)3, out var value) && CuresSporesToo((STATUSTYPE)3, value)) { Accumulate(dictionary, (STATUSTYPE)10, value); } foreach (KeyValuePair<STATUSTYPE, float> item in dictionary) { AddPerSecond(list, item.Value, item.Key); } return list; } private static bool CuresSporesToo(STATUSTYPE statusType, float amount) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 if ((int)statusType == 3) { return amount < 0f; } return false; } private static void Accumulate(Dictionary<STATUSTYPE, float> rates, STATUSTYPE statusType, float amount) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) rates[statusType] = (rates.TryGetValue(statusType, out var value) ? (value + amount) : amount); } private unsafe static void AddPerSecond(List<EffectLine> lines, float perSecond, STATUSTYPE statusType) { string text = ((object)(*(STATUSTYPE*)(&statusType))/*cast due to .constrained prefix*/).ToString(); string text2 = EffectFormatter.PerSecond(perSecond, text); if (text2.Length > 0) { lines.Add(new EffectLine(text2, Onset.OverTime, text, perSecond)); } } private static List<EffectLine> DescribeEmitters(GameObject? prefab) { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) List<EffectLine> list = new List<EffectLine>(); if ((Object)(object)prefab == (Object)null) { return list; } Dictionary<STATUSTYPE, float> dictionary = new Dictionary<STATUSTYPE, float>(); StatusEmitter[] componentsInChildren = prefab.GetComponentsInChildren<StatusEmitter>(true); foreach (StatusEmitter val in componentsInChildren) { if (((Component)val).gameObject.activeSelf && Blast.Reachable(val.radius + val.outerFade)) { Accumulate(dictionary, val.statusType, TickedRate(val.amount * val.tickTime, val.tickTime)); } } if (dictionary.TryGetValue((STATUSTYPE)3, out var value) && CuresSporesToo((STATUSTYPE)3, value)) { Accumulate(dictionary, (STATUSTYPE)10, value); } foreach (KeyValuePair<STATUSTYPE, float> item in dictionary) { AddPerSecond(list, item.Value, item.Key); } return list; } private static float TickedRate(float perTickAmount, float period) { float every; float num = Payout(perTickAmount, period, out every); if (num == 0f) { return 0f; } float num2 = num / every; if (!(perTickAmount < 0f)) { return num2; } return 0f - num2; } private static float Payout(float perTickAmount, float period, out float every) { every = period; float num = Mathf.Abs(perTickAmount); if (num == 0f || period <= 0f) { return 0f; } if (num >= GameValues.StatusStep) { return Mathf.Floor(num / GameValues.StatusStep) * GameValues.StatusStep; } every = Mathf.Ceil(GameValues.StatusStep / num) * period; return GameValues.StatusStep; } private static float Lifetime(Transform spawned) { RemoveAfterSeconds componentInParent = ((Component)spawned).GetComponentInParent<RemoveAfterSeconds>(true); if (!((Object)(object)componentInParent != (Object)null)) { return 0f; } return componentInParent.seconds; } private unsafe static void AddBlast(List<EffectLine> lines, AOE aoe, STATUSTYPE statusType, float amount, TimeEvent? repeat, float seconds, string suffix) { //IL_007c: Unknown result type (might be due to invalid IL or missing references) string text = ((object)(*(STATUSTYPE*)(&statusType))/*cast due to .constrained prefix*/).ToString(); if ((Object)(object)repeat == (Object)null || !repeat.repeating || repeat.rate <= 0f) { float num = Blast.Delivered(aoe, amount); if (num != 0f) { Collect(lines, 0, EffectFormatter.Token(num, text) + suffix, Onset.Instant, text, amount); } } else { float num2 = TickedTotal(amount, repeat.rate, seconds); Collect(lines, 0, EffectFormatter.OverTime(num2, seconds, text), Onset.OverTime, text, num2); } if (CuresSporesToo(statusType, amount)) { AddBlast(lines, aoe, (STATUSTYPE)10, amount, repeat, seconds, suffix); } } private static float TickedTotal(float amount, float period, float seconds) { float every; float num = Payout(amount, period, out every); if (num == 0f || seconds <= 0f) { return 0f; } float num2 = Mathf.Max(0f, Mathf.Ceil(seconds / every) - 1f); float num3 = num2 * num; if (!(amount < 0f)) { return num3; } return 0f - num3; } } internal static class ItemDebug { private static string lastLogged = ""; private static string lastAudited = ""; private const int MaxPrefabDepth = 4; internal static void LogItem(Item item) { if (!(((Object)((Component)item).gameObject).name == lastLogged)) { lastLogged = ((Object)((Component)item).gameObject).name; Plugin.Log.LogInfo((object)Components(item)); } } internal static string Components(Item item) { //IL_005d: Unknown result type (might be due to invalid IL or missing references) GameObject gameObject = ((Component)item).gameObject; StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append("[item] " + ((Object)gameObject).name + " name=\"" + item.UIData?.itemName + "\"" + $" carryWeight={item.carryWeight} tags={item.itemTags}"); ItemUIData uIData = item.UIData; Texture2D val = ((uIData != null) ? uIData.GetIcon() : null); stringBuilder.Append(" icon=" + (((Object)(object)val == (Object)null) ? "<none>" : ((Object)val).name)); Component[] components = gameObject.GetComponents(typeof(Component)); foreach (Component val2 in components) { if ((Object)(object)val2 == (Object)null) { continue; } Type type = ((object)val2).GetType(); if (!(type == typeof(Transform)) && !(type == typeof(RectTransform))) { stringBuilder.Append("\n[item] ").Append(type.FullName); Behaviour val3 = (Behaviour)(object)((val2 is Behaviour) ? val2 : null); if (val3 != null && !val3.enabled) { stringBuilder.Append(" [DISABLED]"); } stringBuilder.Append(Values(val2)); } } return stringBuilder.ToString(); } internal static void LogUntagged(string description) { if (description == lastAudited) { return; } lastAudited = description; List<string> list = new List<string>(); int num = 0; int i = 0; while (i < description.Length) { if (description[i] == '<') { int num2 = description.IndexOf('>', i); if (num2 < 0) { list.Add("unterminated tag"); break; } string text = description.Substring(i + 1, num2 - i - 1); if (text.StartsWith("#") || text.StartsWith("color=")) { num++; } else if (text == "/color") { if (num > 0) { num--; } else { list.Add("</color> closing nothing"); } } else if (text.StartsWith("sprite") && num == 0) { list.Add("<" + text + ">"); } i = num2 + 1; } else if (num == 0 && !char.IsWhiteSpace(description[i])) { int num3 = i; for (; i < description.Length && description[i] != '<'; i++) { } list.Add("\"" + description.Substring(num3, i - num3).Trim() + "\""); } else { i++; } } if (num != 0) { list.Add($"{num} colour tag(s) left open"); } if (list.Count > 0) { Plugin.Log.LogWarning((object)("[color] untagged, renders in the base colour: " + string.Join(", ", list))); } } private static string Values(Component component) { //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_070e: Unknown result type (might be due to invalid IL or missing references) //IL_0713: Unknown result type (might be due to invalid IL or missing references) Action_RestoreHunger val = (Action_RestoreHunger)(object)((component is Action_RestoreHunger) ? component : null); if (val == null) { Action_GiveExtraStamina val2 = (Action_GiveExtraStamina)(object)((component is Action_GiveExtraStamina) ? component : null); if (val2 == null) { Action_ModifyStatus val3 = (Action_ModifyStatus)(object)((component is Action_ModifyStatus) ? component : null); if (val3 == null) { Action_InflictPoison val4 = (Action_InflictPoison)(object)((component is Action_InflictPoison) ? component : null); if (val4 == null) { Action_AddOrRemoveThorns val5 = (Action_AddOrRemoveThorns)(object)((component is Action_AddOrRemoveThorns) ? component : null); if (val5 == null) { Action_SuperJumpAmulet val6 = (Action_SuperJumpAmulet)(object)((component is Action_SuperJumpAmulet) ? component : null); if (val6 == null) { Action_ApplyMassAffliction val7 = (Action_ApplyMassAffliction)(object)((component is Action_ApplyMassAffliction) ? component : null); if (val7 == null) { Action_ApplyAffliction val8 = (Action_ApplyAffliction)(object)((component is Action_ApplyAffliction) ? component : null); if (val8 == null) { Action_RaycastDart val9 = (Action_RaycastDart)(object)((component is Action_RaycastDart) ? component : null); if (val9 == null) { Action_RaycastSpawnSomething val10 = (Action_RaycastSpawnSomething)(object)((component is Action_RaycastSpawnSomething) ? component : null); if (val10 == null) { Action_MoraleBoost val11 = (Action_MoraleBoost)(object)((component is Action_MoraleBoost) ? component : null); if (val11 == null) { Action_Numb val12 = (Action_Numb)(object)((component is Action_Numb) ? component : null); if (val12 == null) { Action_RandomMushroomEffect val13 = (Action_RandomMushroomEffect)(object)((component is Action_RandomMushroomEffect) ? component : null); if (val13 == null) { Action_ClearAllStatus val14 = (Action_ClearAllStatus)(object)((component is Action_ClearAllStatus) ? component : null); if (val14 == null) { StickyItemComponent val15 = (StickyItemComponent)(object)((component is StickyItemComponent) ? component : null); if (val15 == null) { ShelfShroom val16 = (ShelfShroom)(object)((component is ShelfShroom) ? component : null); if (val16 == null) { Breakable val17 = (Breakable)(object)((component is Breakable) ? component : null); if (val17 == null) { VineShooter val18 = (VineShooter)(object)((component is VineShooter) ? component : null); if (val18 == null) { MagicBean val19 = (MagicBean)(object)((component is MagicBean) ? component : null); if (val19 == null) { Action_Spawn val20 = (Action_Spawn)(object)((component is Action_Spawn) ? component : null); if (val20 == null) { RopeShooter val21 = (RopeShooter)(object)((component is RopeShooter) ? component : null); if (val21 == null) { RopeSpool val22 = (RopeSpool)(object)((component is RopeSpool) ? component : null); if (val22 == null) { MagicBugle val23 = (MagicBugle)(object)((component is MagicBugle) ? component : null); if (val23 == null) { RitualDaggerFeedBehavior val24 = (RitualDaggerFeedBehavior)(object)((component is RitualDaggerFeedBehavior) ? component : null); if (val24 == null) { ItemCooking val25 = (ItemCooking)(object)((component is ItemCooking) ? component : null); if (val25 == null) { Scorpion val26 = (Scorpion)(object)((component is Scorpion) ? component : null); if (val26 == null) { Dynamite val27 = (Dynamite)(object)((component is Dynamite) ? component : null); if (val27 == null) { Constructable val28 = (Constructable)(object)((component is Constructable) ? component : null); if (val28 == null) { Lantern val29 = (Lantern)(object)((component is Lantern) ? component : null); if (val29 == null) { Candle val30 = (Candle)(object)((component is Candle) ? component : null); if (val30 == null) { Action_HealingGem val31 = (Action_HealingGem)(object)((component is Action_HealingGem) ? component : null); if (val31 == null) { Action_CloneSelectedItem val32 = (Action_CloneSelectedItem)(object)((component is Action_CloneSelectedItem) ? component : null); if (val32 == null) { AmuletBase val33 = (AmuletBase)(object)((component is AmuletBase) ? component : null); if (val33 != null) { return $" amuletIndex={val33.amuletIndex} startActive={val33.startActive}"; } return ""; } return $" petrify={val32.petrify} mystical={val32.petrifyMystical} range={val32.range}"; } return " heal=" + Affliction((Affliction?)(object)val31.healingAffliction) + " shield=" + Affliction(val31.invincibilityAffliction) + $" ratio={val31.healingToPetrifyRatio} petrify={val31.minPetrify}-{val31.maxPetrify}"; } return $" startingFuel={val30.startingFuel}" + Field(((Component)val30).gameObject); } return $" startingFuel={val29.startingFuel}" + Field(((Component)val29).gameObject); } return $" maxConstructDistance={val28.maxConstructDistance}" + Prefab(" builds", val28.constructedPrefab); } return $" fuse={val27.startingFuseTime} lightFuseRadius={val27.lightFuseRadius}" + Prefab(" explodes", val27.explosionPrefab); } return $" totalPoisonTime={val26.totalPoisonTime}"; } return $" canBeCooked={val25.canBeCooked} wreck={val25.wreckWhenCooked} preCooked={val25.preCooked}" + $" ignoreDefault={val25.ignoreDefaultCookBehavior} ignorePoison={val25.ignoreDefaultPoisonBehavior}" + Prefab(" explosionPrefab", val25.explosionPrefab) + Behaviours(val25); } return $" bonusStamina={val24.bonusStamina}" + $" infiniteStaminaTime={val24.infiniteStaminaTime}"; } return $" totalTootTime={val23.totalTootTime} initialTootCost={val23.initialTootCost}"; } Scene scene = ((Component)val22).gameObject.scene; return (((Scene)(ref scene)).IsValid() ? $" fuel={val22.RopeFuel} metres={Rope.GetLengthInMeters(val22.RopeFuel)}" : " fuel=<prefab>") + $" startFuel={val22.ropeStartFuel} anti={val22.isAntiRope}"; } return $" shootRange={val21.maxLength}u ropeSegments={val21.length}" + $" segmentLength={ItemDescriptionBuilder.RopeSegmentLength(val21)}u" + $" achievementMetres={Rope.GetLengthInMeters(val21.length)}"; } return Spawns(val20); } return ((Object)(object)val19.plantPrefab == (Object)null) ? " plantPrefab=<none>" : $" maxLength={val19.plantPrefab.maxLength}u"; } return $" maxLength={val18.maxLength}u -> {val18.maxLength * CharacterStats.unitsToMeters}m"; } return string.Concat($" onCollision={val17.breakOnCollision} minVelocity={val17.minBreakVelocity}", " items=[", string.Join(", ", (val17.instantiateOnBreak ?? new List<GameObject>()).ConvertAll((GameObject g) => (!((Object)(object)g == (Object)null)) ? ((Object)g).name : "<null>")), "]", string.Concat((val17.instantiateNonItemOnBreak ?? new List<GameObject>()).ConvertAll((GameObject g) => Prefab(" spawns", g)))); } return BreaksInto(val16); } return $" thorns={val15.addThornsToStuckPlayer} weight={val15.addWeightToStuckPlayer}" + $" throwCharge={val15.throwChargeRequirement}"; } return $" excludeCurse={val14.excludeCurse}" + " otherExclusions=[" + string.Join(", ", val14.otherExclusions) + "]"; } return $" mushroomTypeIndex={val13.mushroomTypeIndex}"; } return $" numbAmount={val12.numbAmount}"; } return $" radius={val11.boostRadius} baseline={val11.baselineStaminaBoost}" + $" perScout={val11.staminaBoostPerAdditionalScout}"; } return $" maxDistance={val10.maxDistance}" + $" bubbleRadius={Blast.AntiSphereRadius(val10.prefabToSpawn)}u" + Prefab(" spawns", val10.prefabToSpawn); } return $" maxDistance={val9.maxDistance} onHit=[{Afflictions(val9.afflictionsOnHit)}]"; } return " affliction=" + Affliction(val8.affliction) + " extra=[" + Afflictions(val8.extraAfflictions) + "]"; } return $" radius={val7.radius} ignoreCaster={val7.ignoreCaster}" + " affliction=" + Affliction(((Action_ApplyAffliction)val7).affliction) + " extra=[" + Afflictions(((Action_ApplyAffliction)val7).extraAfflictions) + "]"; } return $" petrifyPerUse={val6.petrifyPerUse}" + " affliction=" + Affliction(((Action_ApplyAffliction)val6).affliction) + " extra=[" + Afflictions(((Action_ApplyAffliction)val6).extraAfflictions) + "]"; } return $" thornCount={val5.thornCount}"; } return $" perSecond={val4.poisonPerSecond} time={val4.inflictionTime} delay={val4.delay}"; } return $" {val3.statusType}={val3.changeAmount} onConsumed={((ItemAction)val3).OnConsumed}" + $" ifSkeleton={val3.ifSkeleton}"; } return $" amount={val2.amount} onConsumed={((ItemAction)val2).OnConsumed}"; } return $" restorationAmount={val.restorationAmount} onConsumed={((ItemAction)val).OnConsumed}"; } private static string Behaviours(ItemCooking cooking) { //IL_0274: Unknown result type (might be due to invalid IL or missing references) if (cooking.additionalCookingBehaviors == null || cooking.additionalCookingBehaviors.Length == 0) { return ""; } StringBuilder stringBuilder = new StringBuilder(); AdditionalCookingBehavior[] additionalCookingBehaviors = cooking.additionalCookingBehaviors; foreach (AdditionalCookingBehavior val in additionalCookingBehaviors) { if (val == null) { stringBuilder.Append("\n[item] <null behaviour>"); continue; } stringBuilder.Append("\n[item] ").Append(((object)val).GetType().Name).Append($" at={val.cookedAmountToTrigger} once={val.onlyOnce}"); StringBuilder stringBuilder2 = stringBuilder; CookingBehavior_DisableScripts val2 = (CookingBehavior_DisableScripts)(object)((val is CookingBehavior_DisableScripts) ? val : null); string value; if (val2 == null) { CookingBehavior_EnableScripts val3 = (CookingBehavior_EnableScripts)(object)((val is CookingBehavior_EnableScripts) ? val : null); if (val3 == null) { CookingBehavior_RunActions val4 = (CookingBehavior_RunActions)(object)((val is CookingBehavior_RunActions) ? val : null); if (val4 == null) { CookingBehavior_ReplaceItem val5 = (CookingBehavior_ReplaceItem)(object)((val is CookingBehavior_ReplaceItem) ? val : null); if (val5 == null) { CookingBehavior_ChangeAfflictionTime val6 = (CookingBehavior_ChangeAfflictionTime)(object)((val is CookingBehavior_ChangeAfflictionTime) ? val : null); if (val6 == null) { CookingBehavior_AddPoisonOnUse val7 = (CookingBehavior_AddPoisonOnUse)(object)((val is CookingBehavior_AddPoisonOnUse) ? val : null); if (val7 == null) { CookingBehavior_AdjustStatusInstantly val8 = (CookingBehavior_AdjustStatusInstantly)(object)((val is CookingBehavior_AdjustStatusInstantly) ? val : null); if (val8 == null) { CookingBehavior_Explode val9 = (CookingBehavior_Explode)(object)((val is CookingBehavior_Explode) ? val : null); if (val9 == null) { CookingBehavior_MessUpAudio val10 = (CookingBehavior_MessUpAudio)(object)((val is CookingBehavior_MessUpAudio) ? val : null); if (val10 == null) { CookingBehavior_ModifyBugleWobble val11 = (CookingBehavior_ModifyBugleWobble)(object)((val is CookingBehavior_ModifyBugleWobble) ? val : null); if (val11 == null) { CookingBehavior_ModifyAudioSourcePitch val12 = (CookingBehavior_ModifyAudioSourcePitch)(object)((val is CookingBehavior_ModifyAudioSourcePitch) ? val : null); if (val12 == null) { CookingBehavior_EnableDisableObjects val13 = (CookingBehavior_EnableDisableObjects)(object)((val is CookingBehavior_EnableDisableObjects) ? val : null); if (val13 == null) { CookingBehavior_ModifyEtcStats val14 = (CookingBehavior_ModifyEtcStats)(object)((val is CookingBehavior_ModifyEtcStats) ? val : null); value = ((val14 == null) ? "" : $" canPocket={val14.canPocket} canBackpack={val14.canBackpack}"); } else { value = $" enable={val13.objectsToEnable?.Count ?? 0} disable={val13.objectsToDisable?.Count ?? 0}"; } } else { value = $" pitch+={val12.changePerCooking}"; } } else { value = $" wobble+={val11.changePerCooking} max={val11.maxCooking}"; } } else { value = $" pitch-={val10.pitchReductionPerCooking} volume-={val10.volumeReductionPerCooking} max={val10.max}"; } } else { value = $" dontRunIfOutOfFuel={val9.dontRunIfOutOfFuel}"; } } else { value = $" {val8.statusType}={val8.amount}"; } } else { value = $" onUse={val7.onUse} onConsume={val7.onConsume}"; } } else { value = string.Format(" change={0} on={1}", val6.change, ((Object)(object)val6.action == (Object)null) ? "<none>" : Affliction(val6.action.affliction)); } } else { value = string.Format(" replaceWith={0} cookNew={1}", ((Object)(object)val5.replaceWithItem == (Object)null) ? "<none>" : ((Object)val5.replaceWithItem).name, val5.cookNewItem); } } else { Component[] actionsToRun = (Component[])(object)val4.actionsToRun; value = " runs=[" + Names(actionsToRun) + "]"; } } else { Component[] actionsToRun = (Component[])(object)val3.scriptsToEnable; value = " enables=[" + Names(actionsToRun) + "]"; } } else { Component[] actionsToRun = (Component[])(object)val2.scriptsToDisable; value = " disables=[" + Names(actionsToRun) + "]"; } stringBuilder2.Append(value); } return stringBuilder.ToString(); } private static string Names(Component[]? components) { if (components == null) { return ""; } List<string> list = new List<string>(); foreach (Component val in components) { list.Add(((Object)(object)val == (Object)null) ? "<null>" : ((object)val).GetType().Name); } return string.Join(", ", list); } private static string Affliction(Affliction? affliction) { //IL_0299: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) if (affliction == null) { return "<none>"; } Affliction_FasterBoi val = (Affliction_FasterBoi)(object)((affliction is Affliction_FasterBoi) ? affliction : null); string text; if (val == null) { Affliction_InfiniteStamina val2 = (Affliction_InfiniteStamina)(object)((affliction is Affliction_InfiniteStamina) ? affliction : null); if (val2 == null) { Affliction_AddBonusStamina val3 = (Affliction_AddBonusStamina)(object)((affliction is Affliction_AddBonusStamina) ? affliction : null); if (val3 == null) { Affliction_AdjustStatus val4 = (Affliction_AdjustStatus)(object)((affliction is Affliction_AdjustStatus) ? affliction : null); if (val4 == null) { Affliction_AdjustDrowsyOverTime val5 = (Affliction_AdjustDrowsyOverTime)(object)((affliction is Affliction_AdjustDrowsyOverTime) ? affliction : null); if (val5 == null) { Affliction_AdjustColdOverTime val6 = (Affliction_AdjustColdOverTime)(object)((affliction is Affliction_AdjustColdOverTime) ? affliction : null); if (val6 == null) { Affliction_AdjustStatusOverTime val7 = (Affliction_AdjustStatusOverTime)(object)((affliction is Affliction_AdjustStatusOverTime) ? affliction : null); if (val7 == null) { Affliction_PoisonOverTime val8 = (Affliction_PoisonOverTime)(object)((affliction is Affliction_PoisonOverTime) ? affliction : null); if (val8 == null) { Affliction_ClearAllStatus val9 = (Affliction_ClearAllStatus)(object)((affliction is Affliction_ClearAllStatus) ? affliction : null); if (val9 == null) { Affliction_HealAll val10 = (Affliction_HealAll)(object)((affliction is Affliction_HealAll) ? affliction : null); if (val10 == null) { Affliction_RadiateInfiniteStam val11 = (Affliction_RadiateInfiniteStam)(object)((affliction is Affliction_RadiateInfiniteStam) ? affliction : null); if (val11 == null) { Affliction_MassSuperJump val12 = (Affliction_MassSuperJump)(object)((affliction is Affliction_MassSuperJump) ? affliction : null); if (val12 == null) { Affliction_LowGravity val13 = (Affliction_LowGravity)(object)((affliction is Affliction_LowGravity) ? affliction : null); text = ((val13 == null) ? "" : $" lowGrav={val13.lowGravAmount}"); } else { text = $" radius={val12.radius}" + $" lowGrav={val12.lowGravAmount} lowGravTime={val12.lowGravTime}"; } } else { text = $" radius={val11.radius}"; } } else { text = $" maxHealing={val10.maxHealing}"; } } else { text = $" excludeCurse={val9.excludeCurse}"; } } else { text = $" perSecond={val8.statusPerSecond} delay={val8.delayBeforeEffect}"; } } else { text = $" perSecond={val7.statusPerSecond}"; } } else { text = $" perSecond={val6.statusPerSecond}"; } } else { text = $" perSecond={val5.statusPerSecond}"; } } else { text = $" {val4.statusType}={val4.statusAmount}"; } } else { text = $" stamina={val3.staminaAmount}"; } } else { text = $" climbDelay={val2.climbDelay}" + " drowsy=" + Affliction(val2.drowsyAffliction); } } else { text = $" drowsyOnEnd={val.drowsyOnEnd}"; } string arg = text; return $"{affliction.GetAfflictionType()}(totalTime={affliction.totalTime}{arg})"; } private static string Afflictions(Affliction[]? afflictions) { if (afflictions == null) { return ""; } List<string> list = new List<string>(); foreach (Affliction affliction in afflictions) { list.Add(Affliction(affliction)); } return string.Join(", ", list); } private static string Prefab(string label, GameObject? prefab) { if ((Object)(object)prefab == (Object)null) { return label + "=<none>"; } StringBuilder stringBuilder = new StringBuilder(label + "=" + ((Object)prefab).name); Component[] components = prefab.GetComponents(typeof(Component)); foreach (Component val in components) { if ((Object)(object)val != (Object)null && !(val is Transform)) { stringBuilder.Append(" | ").Append(((object)val).GetType().Name).Append(PrefabValues(val)); } } Describe(stringBuilder, prefab.transform, 4); DeepEffects(stringBuilder, prefab); return stringBuilder.ToString(); } private static void DeepEffects(StringBuilder tree, GameObject prefab) { Component[] componentsInChildren = prefab.GetComponentsInChildren<Component>(true); foreach (Component val in componentsInChildren) { if ((val is AOE || val is StatusFieldBase || val is StatusEmitter) ? true : false) { string text = ((Object)val.transform).name; bool flag = val.gameObject.activeSelf; Transform parent = val.transform.parent; while ((Object)(object)parent != (Object)null && (Object)(object)parent != (Object)(object)prefab.transform) { text = ((Object)parent).name + "/" + text; flag &= ((Component)parent).gameObject.activeSelf; parent = parent.parent; } tree.Append("\n[item] effect ").Append(text).Append(flag ? "" : " [INACTIVE]") .Append(" | ") .Append(((object)val).GetType().Name) .Append(PrefabValues(val)); } } } private static string Field(GameObject item) { StatusField componentInChildren = item.GetComponentInChildren<StatusField>(true); if (!((Object)(object)componentInChildren == (Object)null)) { return " field=" + ((Object)componentInChildren).name + PrefabValues((Component)(object)componentInChildren); } return " field=<none>"; } private static string Rolls(Action_RandomMushroomEffect effect) { MushroomManager instance = MushroomManager.instance; if ((Object)(object)instance == (Object)null || instance.mushroomEffects == null || instance.mushroomEffects.Length == 0) { return " <no MushroomManager>"; } int num = effect.mushroomTypeIndex % instance.mushroomEffects.Length; string arg = ((instance.mushroomStamAmt != null && num < instance.mushroomStamAmt.Length) ? (instance.mushroomStamAmt[num] * 5).ToString() : "?"); return $" slot={num} effect={instance.mushroomEffects[num]} stamina={arg}" + $" minGood={instance.minGoodEffects} minBad={instance.minBadEffects}" + " effects=[" + string.Join(", ", instance.mushroomEffects) + "] stamAmts=[" + string.Join(", ", instance.mushroomStamAmt ?? new int[0]) + "]"; } private static string Spawns(Action_Spawn action) { if ((Object)(object)action.objectToSpawn == (Object)null) { return " spawns=<none>"; } StringBuilder stringBuilder = new StringBuilder(" spawns=" + ((Object)action.objectToSpawn).name); Component[] components = action.objectToSpawn.GetComponents(typeof(Component)); foreach (Component val in components) { if ((Object)(object)val != (Object)null && !(val is Transform)) { stringBuilder.Append(" | ").Append(((object)val).GetType().Name).Append(PrefabValues(val)); } } Describe(stringBuilder, action.objectToSpawn.transform, 4); return stringBuilder.ToString(); } private static string BreaksInto(ShelfShroom shroom) { if ((Object)(object)shroom.instantiateOnBreak == (Object)null) { return " breaksInto=<none>"; } StringBuilder stringBuilder = new StringBuilder(" breaksInto=" + ((Object)shroom.instantiateOnBreak).name); Describe(stringBuilder, shroom.instantiateOnBreak.transform, 4); return stringBuilder.ToString(); } private static void Describe(StringBuilder tree, Transform parent, int depth) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown if (depth == 0) { return; } foreach (Transform item in parent) { Transform val = item; tree.Append("\n[item] ").Append(new string(' ', (4 - depth) * 2)).Append(((Object)val).name); Component[] components = ((Component)val).GetComponents(typeof(Component)); foreach (Component val2 in components) { if (!((Object)(object)val2 == (Object)null) && !(val2 is Transform)) { tree.Append(" | ").Append(((object)val2).GetType().Name).Append(PrefabValues(val2)); } } Describe(tree, val, depth - 1); } } private static string PrefabValues(Component component) { //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_02b5: Unknown result type (might be due to invalid IL or missing references) AOE val = (AOE)(object)((component is AOE) ? component : null); if (val == null) { StatusFieldBase val2 = (StatusFieldBase)(object)((component is StatusFieldBase) ? component : null); if (val2 == null) { StatusEmitter val3 = (StatusEmitter)(object)((component is StatusEmitter) ? component : null); if (val3 == null) { TimeEvent val4 = (TimeEvent)(object)((component is TimeEvent) ? component : null); if (val4 == null) { RemoveAfterSeconds val5 = (RemoveAfterSeconds)(object)((component is RemoveAfterSeconds) ? component : null); if (val5 == null) { Campfire val6 = (Campfire)(object)((component is Campfire) ? component : null); if (val6 != null) { return $" burnsFor={val6.burnsFor} moraleRadius={val6.moraleBoostRadius}"; } return ""; } return $" seconds={val5.seconds}"; } return $" rate={val4.rate} repeating={val4.repeating}"; } return $" {val3.statusType}={val3.amount}/s radius={val3.radius} outerFade={val3.outerFade}" + $" innerFade={val3.innerFade} minAmount={val3.minAmount} tick={val3.tickTime}"; } string[] obj = new string[6] { $" {val2.statusType}={val2.statusAmountPerSecond}/s", $" onEntry={val2.statusAmountOnEntry} delay={val2.delayBeforeStatusOverTime}", " addtl=[", DescribeAdditional(val2), "]", null }; StatusField val7 = (StatusField)(object)((val2 is StatusField) ? val2 : null); obj[5] = ((val7 != null) ? ($" radius={val7.radius} tickBased={val7.tickBased}" + $" timeBetweenTicks={val7.timeBetweenTicks}") : ""); return string.Concat(obj); } return $" {val.statusType}={val.statusAmount} range={val.range} minFactor={val.minFactor}" + ((val.hasAffliction && val.affliction != null) ? $" affliction={val.affliction.GetAfflictionType()} totalTime={val.affliction.totalTime}" : "") + $" factorPow={val.factorPow} ignoreFactor={val.ignoreFactor}" + $" auto={val.auto} onEnable={val.onEnable}" + (string.IsNullOrEmpty(val.illegalStatus) ? "" : (" illegalStatus=" + val.illegalStatus)) + (val.cooksItems ? " cooksItems" : "") + ((val.addtlStatus != null && val.addtlStatus.Length != 0) ? (" addtl=[" + string.Join(", ", val.addtlStatus) + "] overrides=[" + string.Join(", ", val.addlStatusAmountOverrides ?? new List<float>()) + "]") : ""); } private static string DescribeAdditional(StatusFieldBase field) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) if (field.additionalStatuses == null) { return ""; } List<string> list = new List<string>(); foreach (StatusFieldStatus additionalStatus in field.additionalStatuses) { list.Add($"{additionalStatus.statusType}={additionalStatus.statusAmountPerSecond}/s"); } return string.Join(", ", list); } } internal static class ItemDump { private const string FileName = "VeeItemInfo-items.txt"; private static bool wri