Decompiled source of VeeItemInfo v2.0.1

plugins/com.github.vergir.VeeItemInfo.dll

Decompiled a week ago
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