Decompiled source of ItemInfoDisplayForkedCNPlus new v1.2.0

plugins/com.github.cherrycove.ItemInfoDisplay.dll

Decompiled a day ago
using System;
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using ItemInfoDisplay.Properties;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Peak;
using Peak.Afflictions;
using Photon.Pun;
using TMPro;
using UnityEngine;
using Zorro.Core;

[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.cherrycove.ItemInfoDisplay")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.2.0.0")]
[assembly: AssemblyInformationalVersion("1.2.0")]
[assembly: AssemblyProduct("com.github.cherrycove.ItemInfoDisplay")]
[assembly: AssemblyTitle("ItemInfoDisplay")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.2.0.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 ItemInfoDisplay
{
	[BepInPlugin("com.github.cherrycove.ItemInfoDisplay", "ItemInfoDisplay", "1.2.0")]
	public class Plugin : BaseUnityPlugin
	{
		private static class ItemInfoDisplayUpdatePatch
		{
			[HarmonyPatch(typeof(CharacterItems), "Update")]
			[HarmonyPostfix]
			private static void ItemInfoDisplayUpdate(CharacterItems __instance)
			{
				try
				{
					if ((Object)(object)guiManager == (Object)null)
					{
						AddDisplayObject();
						return;
					}
					if (configEnableTestMode.Value && (Object)(object)Character.localCharacter != (Object)null && __instance.character == Character.localCharacter)
					{
						HandleTestModeInput();
					}
					if ((Object)(object)Character.observedCharacter.data.currentItem != (Object)null)
					{
						UpdateLanternRefreshFlag(Character.observedCharacter.data.currentItem);
						if (hasChanged)
						{
							hasChanged = false;
							ProcessItemGameObject();
						}
						else if (Mathf.Abs(Character.observedCharacter.data.sinceItemAttach - lastKnownSinceItemAttach) >= configForceUpdateTime.Value)
						{
							hasChanged = true;
							lastKnownSinceItemAttach = Character.observedCharacter.data.sinceItemAttach;
						}
						if (!((Component)itemInfoDisplayTextMesh).gameObject.activeSelf)
						{
							((Component)itemInfoDisplayTextMesh).gameObject.SetActive(true);
						}
					}
					else if (((Component)itemInfoDisplayTextMesh).gameObject.activeSelf)
					{
						((Component)itemInfoDisplayTextMesh).gameObject.SetActive(false);
					}
				}
				catch (Exception ex)
				{
					Log.LogError((object)(ex.Message + ex.StackTrace));
				}
			}
		}

		private static class ItemInfoDisplayEquipPatch
		{
			[HarmonyPatch(typeof(CharacterItems), "Equip")]
			[HarmonyPostfix]
			private static void ItemInfoDisplayEquip(CharacterItems __instance)
			{
				try
				{
					if (Character.observedCharacter == __instance.character)
					{
						hasChanged = true;
					}
				}
				catch (Exception ex)
				{
					Log.LogError((object)(ex.Message + ex.StackTrace));
				}
			}
		}

		private static class ItemInfoDisplayFinishCookingPatch
		{
			[HarmonyPatch(typeof(ItemCooking), "FinishCooking")]
			[HarmonyPostfix]
			private static void ItemInfoDisplayFinishCooking(ItemCooking __instance)
			{
				try
				{
					if (Character.observedCharacter == ((ItemComponent)__instance).item.holderCharacter)
					{
						hasChanged = true;
					}
				}
				catch (Exception ex)
				{
					Log.LogError((object)(ex.Message + ex.StackTrace));
				}
			}
		}

		private static class ItemInfoDisplayReduceUsesRPCPatch
		{
			[HarmonyPatch(typeof(Action_ReduceUses), "ReduceUsesRPC")]
			[HarmonyPostfix]
			private static void ItemInfoDisplayReduceUsesRPC(Action_ReduceUses __instance)
			{
				try
				{
					if (Character.observedCharacter == ((ItemActionBase)__instance).character)
					{
						hasChanged = true;
					}
				}
				catch (Exception ex)
				{
					Log.LogError((object)(ex.Message + ex.StackTrace));
				}
			}
		}

		private static GUIManager guiManager;

		private static TextMeshProUGUI itemInfoDisplayTextMesh;

		private static Dictionary<string, string> effectColors = new Dictionary<string, string>();

		private static float lastKnownSinceItemAttach;

		private static bool hasChanged;

		private static ConfigEntry<float> configFontSize;

		private static ConfigEntry<float> configOutlineWidth;

		private static ConfigEntry<float> configLineSpacing;

		private static ConfigEntry<float> configSizeDeltaX;

		private static ConfigEntry<float> configForceUpdateTime;

		private static ConfigEntry<bool> configEnableTestMode;

		private static List<Item> allItemPrefabs = new List<Item>();

		private static int currentTestItemIndex = 0;

		private static bool testModeInitialized = false;

		private static bool testModeInputDisabled = false;

		private static bool inputSystemChecked = false;

		private static bool inputSystemAvailable = false;

		private static PropertyInfo inputSystemKeyboardCurrentProp;

		private static PropertyInfo inputSystemKeyboardItemProp;

		private static PropertyInfo inputSystemKeyControlPressedProp;

		private static Type inputSystemKeyType;

		private static bool legacyInputAvailable = true;

		private static HashSet<string> missingEffectColors = new HashSet<string>();

		private static int lastLanternItemId = 0;

		private static int lastLanternRemainingSeconds = -1;

		private static Dictionary<string, string> itemNameKeyMap = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);

		private static bool itemNameKeyMapInitialized = false;

		private static bool cookingMultiplierResolved = false;

		private static Func<ItemCooking, float>? cookingMultiplierGetter;

		private static string? cookingMultiplierSource;

		public const string Id = "com.github.cherrycove.ItemInfoDisplay";

		internal static ManualLogSource Log { get; private set; } = null;

		public static string Name => "ItemInfoDisplay";

		public static string Version => "1.2.0";

		private void Awake()
		{
			Log = ((BaseUnityPlugin)this).Logger;
			InitEffectColors(effectColors);
			lastKnownSinceItemAttach = 0f;
			hasChanged = true;
			configFontSize = ((BaseUnityPlugin)this).Config.Bind<float>("ItemInfoDisplay", "Font Size", 20f, "Customize the Font Size for description text.");
			configOutlineWidth = ((BaseUnityPlugin)this).Config.Bind<float>("ItemInfoDisplay", "Outline Width", 0.08f, "Customize the Outline Width for item description text.");
			configLineSpacing = ((BaseUnityPlugin)this).Config.Bind<float>("ItemInfoDisplay", "Line Spacing", -35f, "Customize the Line Spacing for item description text.");
			configSizeDeltaX = ((BaseUnityPlugin)this).Config.Bind<float>("ItemInfoDisplay", "Size Delta X", 550f, "Customize the horizontal length of the container for the mod. Increasing moves text left, decreasing moves text right.");
			configForceUpdateTime = ((BaseUnityPlugin)this).Config.Bind<float>("ItemInfoDisplay", "Force Update Time", 1f, "Customize the time in seconds until the mod forces an update for the item.");
			configEnableTestMode = ((BaseUnityPlugin)this).Config.Bind<bool>("ItemInfoDisplay", "Enable Test Mode", false, "Enable test mode to cycle through all items with F9/F10 keys.");
			Harmony.CreateAndPatchAll(typeof(ItemInfoDisplayUpdatePatch), (string)null);
			Harmony.CreateAndPatchAll(typeof(ItemInfoDisplayEquipPatch), (string)null);
			Harmony.CreateAndPatchAll(typeof(ItemInfoDisplayFinishCookingPatch), (string)null);
			Harmony.CreateAndPatchAll(typeof(ItemInfoDisplayReduceUsesRPCPatch), (string)null);
			Log.LogInfo((object)("Plugin " + Name + " is loaded!"));
		}

		private static void ProcessItemGameObject()
		{
			Item currentItem = Character.observedCharacter.data.currentItem;
			ProcessItemGameObject(currentItem);
		}

		private unsafe static void ProcessItemGameObject(Item item)
		{
			//IL_059c: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a3: Expected O, but got Unknown
			//IL_062a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0631: Expected O, but got Unknown
			//IL_0684: Unknown result type (might be due to invalid IL or missing references)
			//IL_068b: Expected O, but got Unknown
			//IL_0733: Unknown result type (might be due to invalid IL or missing references)
			//IL_073a: Expected O, but got Unknown
			//IL_0784: Unknown result type (might be due to invalid IL or missing references)
			//IL_078b: Expected O, but got Unknown
			//IL_0803: Unknown result type (might be due to invalid IL or missing references)
			//IL_080a: Expected O, but got Unknown
			//IL_08a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_08ac: Expected O, but got Unknown
			//IL_09c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_09cb: Expected O, but got Unknown
			//IL_097e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0985: Expected O, but got Unknown
			//IL_0bd9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0be0: Expected O, but got Unknown
			//IL_0cf0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0cf7: Expected O, but got Unknown
			//IL_0db8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0dbf: Expected O, but got Unknown
			//IL_0a47: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a4c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0fda: Unknown result type (might be due to invalid IL or missing references)
			//IL_0fe1: Expected O, but got Unknown
			//IL_0efd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0f04: Expected O, but got Unknown
			//IL_0f06: Unknown result type (might be due to invalid IL or missing references)
			//IL_0f0c: Invalid comparison between Unknown and I4
			//IL_10e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_10ed: Expected O, but got Unknown
			//IL_1240: Unknown result type (might be due to invalid IL or missing references)
			//IL_1247: Expected O, but got Unknown
			//IL_133c: Unknown result type (might be due to invalid IL or missing references)
			//IL_1343: Expected O, but got Unknown
			//IL_13dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_13e3: Expected O, but got Unknown
			//IL_145d: Unknown result type (might be due to invalid IL or missing references)
			//IL_1464: Expected O, but got Unknown
			//IL_1760: Unknown result type (might be due to invalid IL or missing references)
			//IL_1767: Expected O, but got Unknown
			//IL_197f: Unknown result type (might be due to invalid IL or missing references)
			//IL_1986: Expected O, but got Unknown
			//IL_1b68: Unknown result type (might be due to invalid IL or missing references)
			//IL_1b6f: Expected O, but got Unknown
			//IL_1b89: Unknown result type (might be due to invalid IL or missing references)
			//IL_1caf: Unknown result type (might be due to invalid IL or missing references)
			//IL_1cb6: Expected O, but got Unknown
			//IL_1d99: Unknown result type (might be due to invalid IL or missing references)
			//IL_1da0: Expected O, but got Unknown
			//IL_1f6d: Unknown result type (might be due to invalid IL or missing references)
			//IL_1f74: Expected O, but got Unknown
			//IL_2080: Unknown result type (might be due to invalid IL or missing references)
			//IL_2087: Expected O, but got Unknown
			//IL_2370: Unknown result type (might be due to invalid IL or missing references)
			//IL_2377: Expected O, but got Unknown
			//IL_2481: Unknown result type (might be due to invalid IL or missing references)
			//IL_2488: Expected O, but got Unknown
			//IL_25ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_25f4: Expected O, but got Unknown
			//IL_2bf9: Unknown result type (might be due to invalid IL or missing references)
			//IL_2c00: Expected O, but got Unknown
			//IL_2ffd: Unknown result type (might be due to invalid IL or missing references)
			//IL_3004: Expected O, but got Unknown
			//IL_30e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_30ec: Expected O, but got Unknown
			//IL_3182: Unknown result type (might be due to invalid IL or missing references)
			//IL_3189: Expected O, but got Unknown
			GameObject gameObject = ((Component)item).gameObject;
			Component[] source = (from c in gameObject.GetComponents(typeof(Component))
				where (Object)(object)c != (Object)null
				select c).ToArray();
			Component[] array = source.Where(IsComponentActiveForDisplay).ToArray();
			bool isConsumable = IsConsumableForCookingDelta(array);
			Action_ModifyStatus[] array2 = array.OfType<Action_ModifyStatus>().ToArray();
			bool suppressNoEffectHint = array.OfType<Action_RaycastDart>().Any();
			Component[] array3 = (from c in array
				where ((object)c).GetType() != typeof(Action_ModifyStatus)
				group c by ((object)c).GetType() into g
				select g.First()).ToArray();
			ItemCooking val = null;
			foreach (Component obj in array3)
			{
				ItemCooking val2 = (ItemCooking)(object)((obj is ItemCooking) ? obj : null);
				if (val2 != null)
				{
					val = val2;
					break;
				}
			}
			bool flag = false;
			bool flag2 = false;
			bool flag3 = false;
			bool suppressThrowAchievement = false;
			List<AdditionalCookingBehavior> list = new List<AdditionalCookingBehavior>();
			if ((Object)(object)val != (Object)null && val.additionalCookingBehaviors != null)
			{
				AdditionalCookingBehavior[] additionalCookingBehaviors = val.additionalCookingBehaviors;
				foreach (AdditionalCookingBehavior val3 in additionalCookingBehaviors)
				{
					if (val3 == null)
					{
						continue;
					}
					list.Add(val3);
					if (val3 is CookingBehavior_Explode)
					{
						flag = true;
						continue;
					}
					if (val3 is CookingBehavior_Wreck)
					{
						flag2 = true;
						continue;
					}
					CookingBehavior_EnableScripts val4 = (CookingBehavior_EnableScripts)(object)((val3 is CookingBehavior_EnableScripts) ? val3 : null);
					if (val4 != null)
					{
						if (flag3 || val4.scriptsToEnable == null)
						{
							continue;
						}
						MonoBehaviour[] scriptsToEnable = val4.scriptsToEnable;
						foreach (MonoBehaviour val5 in scriptsToEnable)
						{
							if ((Object)(object)val5 != (Object)null && ContainsExplodeKeyword(((object)val5).GetType().Name))
							{
								flag3 = true;
								break;
							}
						}
						if (!flag3 && ScriptsContainSpawnExplosion(val4.scriptsToEnable))
						{
							flag3 = true;
						}
						continue;
					}
					CookingBehavior_RunActions val6 = (CookingBehavior_RunActions)(object)((val3 is CookingBehavior_RunActions) ? val3 : null);
					if (val6 != null)
					{
						if (flag || val6.actionsToRun == null)
						{
							continue;
						}
						ItemAction[] actionsToRun = val6.actionsToRun;
						foreach (ItemAction val7 in actionsToRun)
						{
							if (!((Object)(object)val7 == (Object)null))
							{
								if (ContainsExplodeKeyword(((object)val7).GetType().Name))
								{
									flag = true;
									break;
								}
								Action_Spawn val8 = (Action_Spawn)(object)((val7 is Action_Spawn) ? val7 : null);
								if (val8 != null && (Object)(object)val8.objectToSpawn != (Object)null && ContainsExplodeKeyword(((Object)val8.objectToSpawn).name))
								{
									flag = true;
									break;
								}
								if (val7 is Action_RaycastDart)
								{
									flag3 = true;
								}
							}
						}
					}
					else if (!flag3 && HasExplodeOnUseBehavior(val3))
					{
						flag3 = true;
					}
				}
			}
			if ((Object)(object)val != (Object)null && !flag && (Object)(object)val.explosionPrefab != (Object)null)
			{
				flag = true;
			}
			float cookingEffectMultiplier = GetCookingEffectMultiplier(val);
			bool flag4 = false;
			string text = "";
			string text2 = "";
			string text3 = "";
			string suffixCooked = "";
			string text4 = "";
			((TMP_Text)itemInfoDisplayTextMesh).text = "";
			text2 = ((Ascents.itemWeightModifier <= 0) ? (text2 + GetText("WEIGHT", effectColors["Weight"], ((float)item.carryWeight * 2.5f).ToString("F1").Replace(".0", "")) + "</color>") : (text2 + GetText("WEIGHT", effectColors["Weight"], ((float)(item.carryWeight + Ascents.itemWeightModifier) * 2.5f).ToString("F1").Replace(".0", "")) + "</color>"));
			if (((Object)gameObject).name.Equals("Bugle(Clone)"))
			{
				TextMeshProUGUI obj2 = itemInfoDisplayTextMesh;
				((TMP_Text)obj2).text = ((TMP_Text)obj2).text + GetText("Bugle") + "\n";
			}
			else if (((Object)gameObject).name.Equals("Pirate Compass(Clone)"))
			{
				TextMeshProUGUI obj3 = itemInfoDisplayTextMesh;
				((TMP_Text)obj3).text = ((TMP_Text)obj3).text + GetText("Pirate Compass", effectColors["Injury"]);
			}
			else if (((Object)gameObject).name.Equals("Compass(Clone)"))
			{
				TextMeshProUGUI obj4 = itemInfoDisplayTextMesh;
				((TMP_Text)obj4).text = ((TMP_Text)obj4).text + GetText("Compass", effectColors["Injury"]);
			}
			else if (((Object)gameObject).name.Equals("Shell Big(Clone)"))
			{
				TextMeshProUGUI obj5 = itemInfoDisplayTextMesh;
				((TMP_Text)obj5).text = ((TMP_Text)obj5).text + GetText("Shell Big", effectColors["Hunger"]);
			}
			else if (((Object)gameObject).name.Equals("Matchbook(Clone)"))
			{
				TextMeshProUGUI obj6 = itemInfoDisplayTextMesh;
				((TMP_Text)obj6).text = ((TMP_Text)obj6).text + GetText("Matchbook");
			}
			for (int num5 = 0; num5 < array3.Length; num5++)
			{
				if (((object)array3[num5]).GetType() == typeof(ItemUseFeedback))
				{
					ItemUseFeedback val9 = (ItemUseFeedback)array3[num5];
					if (val9.useAnimation.Equals("Eat") || val9.useAnimation.Equals("Drink") || val9.useAnimation.Equals("Heal"))
					{
						flag4 = true;
					}
				}
				else if (((object)array3[num5]).GetType() == typeof(Action_Consume))
				{
					flag4 = true;
				}
				else if (((object)array3[num5]).GetType() == typeof(Action_RestoreHunger))
				{
					Action_RestoreHunger val10 = (Action_RestoreHunger)array3[num5];
					float num6 = ApplyCookingMultiplier(val10.restorationAmount, cookingEffectMultiplier);
					text += ProcessEffect(num6 * -1f, "Hunger");
				}
				else if (((object)array3[num5]).GetType() == typeof(Action_ApplyInfiniteStamina))
				{
					Action_ApplyInfiniteStamina val11 = (Action_ApplyInfiniteStamina)array3[num5];
					float num7 = ApplyCookingMultiplier(val11.buffTime, cookingEffectMultiplier);
					if (num7 > 0f)
					{
						TextMeshProUGUI obj7 = itemInfoDisplayTextMesh;
						((TMP_Text)obj7).text = ((TMP_Text)obj7).text + GetText("Affliction_InfiniteStamina", effectColors["ItemInfoDisplayPositive"], num7.ToString("F1").Replace(".0", ""), effectColors["Extra Stamina"]);
					}
				}
				else if (((object)array3[num5]).GetType() == typeof(Action_GiveExtraStamina))
				{
					Action_GiveExtraStamina val12 = (Action_GiveExtraStamina)array3[num5];
					float amount = ApplyCookingMultiplier(val12.amount, cookingEffectMultiplier);
					text += ProcessEffect(amount, "Extra Stamina");
				}
				else if (((object)array3[num5]).GetType() == typeof(Action_InflictPoison))
				{
					Action_InflictPoison val13 = (Action_InflictPoison)array3[num5];
					float amountPerSecond = ApplyCookingMultiplier(val13.poisonPerSecond, cookingEffectMultiplier);
					text += GetText("InflictPoison", val13.delay.ToString(), ProcessEffectOverTime(amountPerSecond, 1f, val13.inflictionTime, "Poison"));
				}
				else if (((object)array3[num5]).GetType() == typeof(Action_AddOrRemoveThorns))
				{
					Action_AddOrRemoveThorns val14 = (Action_AddOrRemoveThorns)array3[num5];
					float amount2 = ApplyCookingMultiplier((float)val14.thornCount * 0.05f, cookingEffectMultiplier);
					text += ProcessEffect(amount2, "Thorns");
				}
				else if (((object)array3[num5]).GetType() == typeof(Action_RandomMushroomEffect))
				{
					string addition = BuildRandomMushroomEffectText(array3[num5]);
					((TMP_Text)itemInfoDisplayTextMesh).text = AppendWithSectionSpacing(((TMP_Text)itemInfoDisplayTextMesh).text, addition);
				}
				else if (((object)array3[num5]).GetType() == typeof(Action_ApplyMassAffliction))
				{
					Action_ApplyMassAffliction val15 = (Action_ApplyMassAffliction)array3[num5];
					text4 += GetText("ApplyMassAffliction");
					text4 += ProcessAffliction(((Action_ApplyAffliction)val15).affliction, cookingEffectMultiplier);
					if (((Action_ApplyAffliction)val15).extraAfflictions == null || ((Action_ApplyAffliction)val15).extraAfflictions.Length == 0)
					{
						continue;
					}
					for (int num8 = 0; num8 < ((Action_ApplyAffliction)val15).extraAfflictions.Length; num8++)
					{
						if (text4.EndsWith('\n'))
						{
							text4 = text4.Remove(text4.Length - 1);
						}
						text4 = text4 + ",\n" + ProcessAffliction(((Action_ApplyAffliction)val15).extraAfflictions[num8], cookingEffectMultiplier);
					}
				}
				else if (((object)array3[num5]).GetType() == typeof(Action_ApplyAffliction))
				{
					if ((Object)(object)((Component)item).GetComponent<AmuletBase>() == (Object)null)
					{
						Action_ApplyAffliction val16 = (Action_ApplyAffliction)array3[num5];
						text4 += ProcessAffliction(val16.affliction, cookingEffectMultiplier);
					}
				}
				else if (((object)array3[num5]).GetType() == typeof(Action_ClearAllStatus))
				{
					Action_ClearAllStatus val17 = (Action_ClearAllStatus)array3[num5];
					string text5 = GetText("ClearAllStatus_Base", effectColors["ItemInfoDisplayPositive"]);
					if (val17.excludeCurse)
					{
						text5 += GetText("ClearAllStatus_ExceptCurse", effectColors["Curse"]);
					}
					if (val17.otherExclusions.Count > 0)
					{
						foreach (STATUSTYPE otherExclusion in val17.otherExclusions)
						{
							text5 = text5 + ", " + effectColors[((object)(*(STATUSTYPE*)(&otherExclusion))/*cast due to .constrained prefix*/).ToString()] + GetText("Effect_" + ((object)(*(STATUSTYPE*)(&otherExclusion))/*cast due to .constrained prefix*/).ToString().ToUpper()).ToUpper() + "</color>";
						}
					}
					text5 = text5.Replace(", <#E13542>" + GetText("Effect_CRAB").ToUpper() + "</color>", "") + "\n";
					TextMeshProUGUI obj8 = itemInfoDisplayTextMesh;
					((TMP_Text)obj8).text = ((TMP_Text)obj8).text + text5;
				}
				else if (((object)array3[num5]).GetType() == typeof(Action_BecomeSkeleton))
				{
					((TMP_Text)itemInfoDisplayTextMesh).text = AppendWithSectionSpacing(((TMP_Text)itemInfoDisplayTextMesh).text, GetText("BecomeSkeleton", effectColors["ItemInfoDisplayPositive"], effectColors["Curse"], effectColors["Injury"], effectColors["Curse"]));
				}
				else if (((object)array3[num5]).GetType() == typeof(Action_ConsumeAndSpawn))
				{
					Action_ConsumeAndSpawn val18 = (Action_ConsumeAndSpawn)array3[num5];
					if (((object)val18.itemToSpawn).ToString().Contains("Peel"))
					{
						TextMeshProUGUI obj9 = itemInfoDisplayTextMesh;
						((TMP_Text)obj9).text = ((TMP_Text)obj9).text + GetText("ConsumeAndSpawn_Peel");
					}
				}
				else if (((object)array3[num5]).GetType() == typeof(Action_ReduceUses))
				{
					if (item?.data?.data != null && item.data.data.TryGetValue((DataEntryKey)2, out var value))
					{
						OptionableIntItemData val19 = (OptionableIntItemData)(object)((value is OptionableIntItemData) ? value : null);
						if (val19 != null && val19.HasData && val19.Value > 1)
						{
							text3 += GetText("ReduceUses", val19.Value.ToString());
						}
					}
				}
				else if (((object)array3[num5]).GetType() == typeof(Lantern))
				{
					Lantern lantern = (Lantern)array3[num5];
					if (((Object)gameObject).name.Equals("Torch(Clone)"))
					{
						TextMeshProUGUI obj10 = itemInfoDisplayTextMesh;
						((TMP_Text)obj10).text = ((TMP_Text)obj10).text + GetText("Torch");
					}
					else
					{
						text4 += GetText("Lantern");
					}
					if (!((Object)gameObject).name.Equals("Torch(Clone)"))
					{
						int lanternRemainingSecondsInt = GetLanternRemainingSecondsInt(item, lantern);
						text4 += GetText("LanternRemaining", lanternRemainingSecondsInt.ToString());
						text4 = AppendLanternStatusPerSecond(gameObject, text4);
					}
				}
				else if (((object)array3[num5]).GetType() == typeof(Action_RaycastDart))
				{
					Action_RaycastDart effect = (Action_RaycastDart)array3[num5];
					flag4 = true;
					text4 += BuildRaycastDartSection(effect, cookingEffectMultiplier);
				}
				else if (((object)array3[num5]).GetType() == typeof(MagicBugle))
				{
					TextMeshProUGUI obj11 = itemInfoDisplayTextMesh;
					((TMP_Text)obj11).text = ((TMP_Text)obj11).text + GetText("MagicBugle");
				}
				else if (((object)array3[num5]).GetType() == typeof(ClimbingSpikeComponent))
				{
					TextMeshProUGUI obj12 = itemInfoDisplayTextMesh;
					((TMP_Text)obj12).text = ((TMP_Text)obj12).text + GetText("ClimbingSpike", effectColors["Extra Stamina"]);
				}
				else if (((object)array3[num5]).GetType() == typeof(Action_Flare))
				{
					TextMeshProUGUI obj13 = itemInfoDisplayTextMesh;
					((TMP_Text)obj13).text = ((TMP_Text)obj13).text + GetText("Flare");
				}
				else if (((object)array3[num5]).GetType() == typeof(Backpack))
				{
					if ((Object)(object)((Component)item).GetComponent<JetpackItem>() == (Object)null && (Object)(object)((Component)item).GetComponent<Rocketpack>() == (Object)null)
					{
						Backpack val20 = (Backpack)array3[num5];
						if ((int)val20.backpackType == 2)
						{
							TextMeshProUGUI obj14 = itemInfoDisplayTextMesh;
							((TMP_Text)obj14).text = ((TMP_Text)obj14).text + GetText("Fannypack");
						}
						else
						{
							TextMeshProUGUI obj15 = itemInfoDisplayTextMesh;
							((TMP_Text)obj15).text = ((TMP_Text)obj15).text + GetText("Backpack");
						}
					}
				}
				else if (((object)array3[num5]).GetType() == typeof(BananaPeel))
				{
					TextMeshProUGUI obj16 = itemInfoDisplayTextMesh;
					((TMP_Text)obj16).text = ((TMP_Text)obj16).text + GetText("BananaPeel", effectColors["Hunger"]);
				}
				else if (((object)array3[num5]).GetType() == typeof(Constructable))
				{
					Constructable val21 = (Constructable)array3[num5];
					if ((Object)(object)val21.constructedPrefab != (Object)null && ((Object)val21.constructedPrefab).name.Equals("PortableStovetop_Placed"))
					{
						Campfire component = val21.constructedPrefab.GetComponent<Campfire>();
						if ((Object)(object)component != (Object)null)
						{
							TextMeshProUGUI obj17 = itemInfoDisplayTextMesh;
							((TMP_Text)obj17).text = ((TMP_Text)obj17).text + GetText("Constructable_PortableStovetop_Placed", effectColors["Injury"], component.burnsFor.ToString());
						}
						else
						{
							TextMeshProUGUI obj18 = itemInfoDisplayTextMesh;
							((TMP_Text)obj18).text = ((TMP_Text)obj18).text + GetText("Constructable");
						}
					}
					else
					{
						TextMeshProUGUI obj19 = itemInfoDisplayTextMesh;
						((TMP_Text)obj19).text = ((TMP_Text)obj19).text + GetText("Constructable");
					}
				}
				else if (((object)array3[num5]).GetType() == typeof(RopeSpool))
				{
					RopeSpool val22 = (RopeSpool)array3[num5];
					if (val22.isAntiRope)
					{
						TextMeshProUGUI obj20 = itemInfoDisplayTextMesh;
						((TMP_Text)obj20).text = ((TMP_Text)obj20).text + GetText("RopeSpool_AntiRope");
					}
					else
					{
						TextMeshProUGUI obj21 = itemInfoDisplayTextMesh;
						((TMP_Text)obj21).text = ((TMP_Text)obj21).text + GetText("RopeSpool");
					}
					TextMeshProUGUI obj22 = itemInfoDisplayTextMesh;
					((TMP_Text)obj22).text = ((TMP_Text)obj22).text + GetText("RopeSpool_TIP", (val22.minSegments / 4f).ToString("F2").Replace(".0", ""), ((float)Rope.MaxSegments / 4f).ToString("F1").Replace(".0", ""));
					if (configForceUpdateTime.Value <= 1f)
					{
						text3 += GetText("RopeSpool_Left", (val22.RopeFuel / 4f).ToString("F2").Replace(".00", ""));
					}
				}
				else if (((object)array3[num5]).GetType() == typeof(RopeShooter))
				{
					RopeShooter val23 = (RopeShooter)array3[num5];
					if ((Object)(object)val23.ropeAnchorWithRopePref != (Object)null && ((Object)val23.ropeAnchorWithRopePref).name.Equals("RopeAnchorForRopeShooterAnti"))
					{
						TextMeshProUGUI obj23 = itemInfoDisplayTextMesh;
						((TMP_Text)obj23).text = ((TMP_Text)obj23).text + GetText("RopeShooter_Anti", (val23.maxLength / 4f).ToString("F1").Replace(".0", ""));
					}
					else
					{
						TextMeshProUGUI obj24 = itemInfoDisplayTextMesh;
						((TMP_Text)obj24).text = ((TMP_Text)obj24).text + GetText("RopeShooter", (val23.maxLength / 4f).ToString("F1").Replace(".0", ""));
					}
				}
				else if (((object)array3[num5]).GetType() == typeof(Antigrav))
				{
					Antigrav val24 = (Antigrav)array3[num5];
					if (val24.intensity != 0f)
					{
						text4 += GetText("Antigrav", effectColors["Injury"]);
					}
				}
				else if (((object)array3[num5]).GetType() == typeof(Action_Balloon))
				{
					text4 += GetText("Balloon");
				}
				else if (((object)array3[num5]).GetType() == typeof(VineShooter))
				{
					VineShooter val25 = (VineShooter)array3[num5];
					TextMeshProUGUI obj25 = itemInfoDisplayTextMesh;
					((TMP_Text)obj25).text = ((TMP_Text)obj25).text + GetText("VineShooter", (val25.maxLength / 1.6666666f).ToString("F1").Replace(".0", ""));
				}
				else if (((object)array3[num5]).GetType() == typeof(ShelfShroom))
				{
					ShelfShroom val26 = (ShelfShroom)array3[num5];
					if ((Object)(object)val26.instantiateOnBreak == (Object)null)
					{
						Log.LogWarning((object)"[ItemInfoDisplay] ShelfShroom instantiateOnBreak was null. Skipping detailed info.");
					}
					else if (((Object)val26.instantiateOnBreak).name.Equals("HealingPuffShroomSpawn"))
					{
						TextMeshProUGUI obj26 = itemInfoDisplayTextMesh;
						((TMP_Text)obj26).text = ((TMP_Text)obj26).text + GetText("HealingPuffShroom", effectColors["Hunger"]);
						((TMP_Text)itemInfoDisplayTextMesh).text = AppendHealingPuffShroomEffectInfo(gameObject, ((TMP_Text)itemInfoDisplayTextMesh).text);
					}
					else if (((Object)val26.instantiateOnBreak).name.Equals("ShelfShroomSpawn"))
					{
						TextMeshProUGUI obj27 = itemInfoDisplayTextMesh;
						((TMP_Text)obj27).text = ((TMP_Text)obj27).text + GetText("ShelfShroomSpawn", effectColors["Hunger"]);
					}
					else if (((Object)val26.instantiateOnBreak).name.Equals("BounceShroomSpawn"))
					{
						TextMeshProUGUI obj28 = itemInfoDisplayTextMesh;
						((TMP_Text)obj28).text = ((TMP_Text)obj28).text + GetText("BounceShroomSpawn", effectColors["Hunger"]);
					}
				}
				else if (((object)array3[num5]).GetType() == typeof(ScoutEffigy))
				{
					TextMeshProUGUI obj29 = itemInfoDisplayTextMesh;
					((TMP_Text)obj29).text = ((TMP_Text)obj29).text + GetText("ScoutEffigy", effectColors["Extra Stamina"]);
				}
				else if (((object)array3[num5]).GetType() == typeof(Action_Die))
				{
					TextMeshProUGUI obj30 = itemInfoDisplayTextMesh;
					((TMP_Text)obj30).text = ((TMP_Text)obj30).text + GetText("Action_Die", effectColors["Curse"]);
				}
				else if (((object)array3[num5]).GetType() == typeof(Action_SpawnGuidebookPage))
				{
					flag4 = true;
					TextMeshProUGUI obj31 = itemInfoDisplayTextMesh;
					((TMP_Text)obj31).text = ((TMP_Text)obj31).text + GetText("SpawnGuidebookPage");
				}
				else if (((object)array3[num5]).GetType() == typeof(Action_Guidebook))
				{
					TextMeshProUGUI obj32 = itemInfoDisplayTextMesh;
					((TMP_Text)obj32).text = ((TMP_Text)obj32).text + GetText("Guidebook");
				}
				else if (((object)array3[num5]).GetType() == typeof(Action_CallScoutmaster))
				{
					((TMP_Text)itemInfoDisplayTextMesh).text = AppendWithSectionSpacing(((TMP_Text)itemInfoDisplayTextMesh).text, GetText("CallScoutmaster", effectColors["Injury"]) ?? "");
				}
				else if (((object)array3[num5]).GetType() == typeof(Action_MoraleBoost))
				{
					Action_MoraleBoost val27 = (Action_MoraleBoost)array3[num5];
					float num9 = ApplyCookingMultiplier(val27.baselineStaminaBoost, cookingEffectMultiplier);
					if (val27.boostRadius < 0f)
					{
						TextMeshProUGUI obj33 = itemInfoDisplayTextMesh;
						((TMP_Text)obj33).text = ((TMP_Text)obj33).text + GetText("MoraleBoost_Self", effectColors["ItemInfoDisplayPositive"], effectColors["Extra Stamina"], (num9 * 100f).ToString("F1").Replace(".0", ""));
					}
					else if (val27.boostRadius > 0f)
					{
						TextMeshProUGUI obj34 = itemInfoDisplayTextMesh;
						((TMP_Text)obj34).text = ((TMP_Text)obj34).text + GetText("MoraleBoost_Nearby", effectColors["ItemInfoDisplayPositive"], effectColors["Extra Stamina"], (num9 * 100f).ToString("F1").Replace(".0", ""));
					}
				}
				else if (((object)array3[num5]).GetType() == typeof(Breakable))
				{
					((TMP_Text)itemInfoDisplayTextMesh).text = AppendWithSectionSpacing(((TMP_Text)itemInfoDisplayTextMesh).text, GetText("Breakable", effectColors["Hunger"]) ?? "");
				}
				else if (((object)array3[num5]).GetType() == typeof(Bonkable))
				{
					((TMP_Text)itemInfoDisplayTextMesh).text = AppendWithSectionSpacing(((TMP_Text)itemInfoDisplayTextMesh).text, GetText("Bonkable", effectColors["Hunger"], effectColors["Injury"]) ?? "");
				}
				else if (((object)array3[num5]).GetType() == typeof(MagicBean))
				{
					MagicBean val28 = (MagicBean)array3[num5];
					string text6 = GetText("MagicBean", effectColors["Hunger"], "");
					if ((Object)(object)val28.plantPrefab != (Object)null)
					{
						text6 = GetText("MagicBean", effectColors["Hunger"], (val28.plantPrefab.maxLength / 2f).ToString("F1").Replace(".0", ""));
					}
					TextMeshProUGUI obj35 = itemInfoDisplayTextMesh;
					((TMP_Text)obj35).text = ((TMP_Text)obj35).text + text6;
				}
				else if (((object)array3[num5]).GetType() == typeof(BingBong))
				{
					TextMeshProUGUI obj36 = itemInfoDisplayTextMesh;
					((TMP_Text)obj36).text = ((TMP_Text)obj36).text + GetText("BingBong");
				}
				else if (((object)array3[num5]).GetType() == typeof(Action_Passport))
				{
					TextMeshProUGUI obj37 = itemInfoDisplayTextMesh;
					((TMP_Text)obj37).text = ((TMP_Text)obj37).text + GetText("Passport") + "\n";
				}
				else if (((object)array3[num5]).GetType() == typeof(Actions_Binoculars))
				{
					TextMeshProUGUI obj38 = itemInfoDisplayTextMesh;
					((TMP_Text)obj38).text = ((TMP_Text)obj38).text + GetText("Binoculars");
				}
				else if (((object)array3[num5]).GetType() == typeof(Action_WarpToRandomPlayer))
				{
					TextMeshProUGUI obj39 = itemInfoDisplayTextMesh;
					((TMP_Text)obj39).text = ((TMP_Text)obj39).text + GetText("WarpToRandomPlayer");
				}
				else if (((object)array3[num5]).GetType() == typeof(Action_WarpToBiome))
				{
					Action_WarpToBiome val29 = (Action_WarpToBiome)array3[num5];
					TextMeshProUGUI obj40 = itemInfoDisplayTextMesh;
					((TMP_Text)obj40).text = ((TMP_Text)obj40).text + GetText("WarpToBiome", SegmentToBiomeName(val29.segmentToWarpTo));
				}
				else if (((object)array3[num5]).GetType() == typeof(Parasol))
				{
					TextMeshProUGUI obj41 = itemInfoDisplayTextMesh;
					((TMP_Text)obj41).text = ((TMP_Text)obj41).text + GetText("Parasol") + "\n";
				}
				else if (((object)array3[num5]).GetType() == typeof(Frisbee))
				{
					TextMeshProUGUI obj42 = itemInfoDisplayTextMesh;
					((TMP_Text)obj42).text = ((TMP_Text)obj42).text + GetText("Frisbee", effectColors["Hunger"]);
				}
				else if (((object)array3[num5]).GetType() == typeof(Action_ConstructableScoutCannonScroll))
				{
					TextMeshProUGUI obj43 = itemInfoDisplayTextMesh;
					((TMP_Text)obj43).text = ((TMP_Text)obj43).text + GetText("ConstructableScoutCannonScroll");
				}
				else if (((object)array3[num5]).GetType() == typeof(Dynamite))
				{
					Dynamite val30 = (Dynamite)array3[num5];
					string text7 = GetText("Dynamite", effectColors["Injury"], "");
					if ((Object)(object)val30.explosionPrefab != (Object)null)
					{
						AOE component2 = val30.explosionPrefab.GetComponent<AOE>();
						if ((Object)(object)component2 != (Object)null)
						{
							text7 = GetText("Dynamite", effectColors["Injury"], (component2.statusAmount * 100f).ToString("F1").Replace(".0", ""));
						}
					}
					TextMeshProUGUI obj44 = itemInfoDisplayTextMesh;
					((TMP_Text)obj44).text = ((TMP_Text)obj44).text + text7;
				}
				else if (((object)array3[num5]).GetType() == typeof(Scorpion))
				{
					Scorpion val31 = (Scorpion)array3[num5];
					if (configForceUpdateTime.Value <= 1f)
					{
						Character val32 = item.holderCharacter ?? Character.observedCharacter;
						float num10 = (((Object)(object)val32 != (Object)null && val32.refs != null && (Object)(object)val32.refs.afflictions != (Object)null) ? val32.refs.afflictions.statusSum : 0f);
						float num11 = Mathf.Max(0.5f, 1f - num10 + 0.05f) * 100f;
						TextMeshProUGUI obj45 = itemInfoDisplayTextMesh;
						((TMP_Text)obj45).text = ((TMP_Text)obj45).text + GetText("Scorpion_Dynamic", effectColors["Poison"], effectColors["Curse"], effectColors["Heat"], num11.ToString("F1").Replace(".0", ""), val31.totalPoisonTime.ToString("F1").Replace(".0", ""));
					}
					else
					{
						TextMeshProUGUI obj46 = itemInfoDisplayTextMesh;
						((TMP_Text)obj46).text = ((TMP_Text)obj46).text + GetText("Scorpion_Static", effectColors["Poison"], effectColors["Curse"], effectColors["Heat"], val31.totalPoisonTime.ToString("F1").Replace(".0", ""));
					}
				}
				else if (((object)array3[num5]).GetType() == typeof(Action_Spawn))
				{
					Action_Spawn val33 = (Action_Spawn)array3[num5];
					if ((Object)(object)val33.objectToSpawn != (Object)null && ((Object)val33.objectToSpawn).name.Equals("VFX_Sunscreen"))
					{
						Transform val34 = val33.objectToSpawn.transform.Find("AOE");
						AOE val35 = (((Object)(object)val34 != (Object)null) ? ((Component)val34).GetComponent<AOE>() : null);
						RemoveAfterSeconds val36 = (((Object)(object)val34 != (Object)null) ? ((Component)val34).GetComponent<RemoveAfterSeconds>() : null);
						if ((Object)(object)val35 != (Object)null && (Object)(object)val36 != (Object)null)
						{
							TextMeshProUGUI obj47 = itemInfoDisplayTextMesh;
							((TMP_Text)obj47).text = ((TMP_Text)obj47).text + GetText("VFX_Sunscreen", val36.seconds.ToString("F1").Replace(".0", ""), ProcessAffliction(val35.affliction, cookingEffectMultiplier));
						}
					}
				}
				else if (((object)array3[num5]).GetType() == typeof(CactusBall))
				{
					CactusBall val37 = (CactusBall)array3[num5];
					TextMeshProUGUI obj48 = itemInfoDisplayTextMesh;
					((TMP_Text)obj48).text = ((TMP_Text)obj48).text + GetText("CactusBall", effectColors["Thorns"], effectColors["Hunger"], (((StickyItemComponent)val37).throwChargeRequirement * 100f).ToString("F1").Replace(".0", ""));
				}
				else if (((object)array3[num5]).GetType() == typeof(BingBongShieldWhileHolding))
				{
					TextMeshProUGUI obj49 = itemInfoDisplayTextMesh;
					((TMP_Text)obj49).text = ((TMP_Text)obj49).text + GetText("BingBongShieldWhileHolding", effectColors["Shield"]);
				}
				else if (((object)array3[num5]).GetType() == typeof(RescueHook))
				{
					if (((Object)gameObject).name.StartsWith("RescueHook_Infinite", StringComparison.Ordinal))
					{
						TextMeshProUGUI obj50 = itemInfoDisplayTextMesh;
						((TMP_Text)obj50).text = ((TMP_Text)obj50).text + GetText("RescueHook_Infinite");
					}
					else
					{
						TextMeshProUGUI obj51 = itemInfoDisplayTextMesh;
						((TMP_Text)obj51).text = ((TMP_Text)obj51).text + GetText("RescueHook");
					}
				}
				else if (((object)array3[num5]).GetType() == typeof(Beehive))
				{
					TextMeshProUGUI obj52 = itemInfoDisplayTextMesh;
					((TMP_Text)obj52).text = ((TMP_Text)obj52).text + GetText("Beehive", effectColors["Injury"], effectColors["Poison"]);
				}
				else if (((object)array3[num5]).GetType() == typeof(BugPhobia))
				{
					((TMP_Text)itemInfoDisplayTextMesh).text = AppendWithSectionSpacing(((TMP_Text)itemInfoDisplayTextMesh).text, GetText("BugPhobia"));
				}
				else if (((object)array3[num5]).GetType() == typeof(Mandrake))
				{
					TextMeshProUGUI obj53 = itemInfoDisplayTextMesh;
					((TMP_Text)obj53).text = ((TMP_Text)obj53).text + GetText("Mandrake", effectColors["Drowsy"], effectColors["Heat"]);
					suppressThrowAchievement = true;
				}
				else if (((object)array3[num5]).GetType() == typeof(Snowball))
				{
					TextMeshProUGUI obj54 = itemInfoDisplayTextMesh;
					((TMP_Text)obj54).text = ((TMP_Text)obj54).text + GetText("Snowball", effectColors["Cold"]);
				}
				else if (((object)array3[num5]).GetType() == typeof(StickyItemComponent))
				{
					StickyItemComponent val38 = (StickyItemComponent)array3[num5];
					string text8 = GetText("StickyItemComponent", effectColors["Hunger"]);
					if (val38.addWeightToStuckPlayer > 0)
					{
						text8 += GetText("StickyItemComponent_Weight", effectColors["Weight"], ((float)val38.addWeightToStuckPlayer * 2.5f).ToString("F1").Replace(".0", ""));
					}
					if (val38.addThornsToStuckPlayer > 0)
					{
						text8 += GetText("StickyItemComponent_Thorns", effectColors["Thorns"], val38.addThornsToStuckPlayer.ToString());
					}
					TextMeshProUGUI obj55 = itemInfoDisplayTextMesh;
					((TMP_Text)obj55).text = ((TMP_Text)obj55).text + text8;
				}
				else if (((object)array3[num5]).GetType() == typeof(JetpackItem))
				{
					JetpackItem val39 = (JetpackItem)array3[num5];
					float itemFuelRemaining = GetItemFuelRemaining(item, val39.startingFuel);
					int num12 = Mathf.RoundToInt(itemFuelRemaining / Mathf.Max(1f, val39.startingFuel) * 100f);
					int num13 = Mathf.CeilToInt(itemFuelRemaining / 20f);
					TextMeshProUGUI obj56 = itemInfoDisplayTextMesh;
					((TMP_Text)obj56).text = ((TMP_Text)obj56).text + GetText("Jetpack", num12.ToString(), num13.ToString());
				}
				else if (((object)array3[num5]).GetType() == typeof(Rocketpack))
				{
					TextMeshProUGUI obj57 = itemInfoDisplayTextMesh;
					((TMP_Text)obj57).text = ((TMP_Text)obj57).text + GetText("Rocketpack", effectColors["Injury"], effectColors["Injury"], effectColors["Curse"]);
				}
				else if (((object)array3[num5]).GetType() == typeof(ParachuteItem))
				{
					TextMeshProUGUI obj58 = itemInfoDisplayTextMesh;
					((TMP_Text)obj58).text = ((TMP_Text)obj58).text + GetText("Parachute", "1.5");
				}
				else if (((object)array3[num5]).GetType() == typeof(Candle))
				{
					Candle candle = (Candle)array3[num5];
					int candleRemainingSecondsInt = GetCandleRemainingSecondsInt(item, candle);
					TextMeshProUGUI obj59 = itemInfoDisplayTextMesh;
					((TMP_Text)obj59).text = ((TMP_Text)obj59).text + GetText("Candle", effectColors["Injury"], candleRemainingSecondsInt.ToString());
				}
				else if (((object)array3[num5]).GetType() == typeof(AmuletBase))
				{
					string name = ((Object)gameObject).name;
					if (name.StartsWith("Amulet_Clone", StringComparison.Ordinal))
					{
						Action_CloneSelectedItem component3 = ((Component)item).GetComponent<Action_CloneSelectedItem>();
						int num14 = (((Object)(object)component3 != (Object)null) ? component3.petrify : 0);
						int num15 = (((Object)(object)component3 != (Object)null) ? component3.petrifyMystical : 0);
						string text9 = ((num15 > num14) ? $"{num14}(神秘物品 {num15})" : num14.ToString());
						TextMeshProUGUI obj60 = itemInfoDisplayTextMesh;
						((TMP_Text)obj60).text = ((TMP_Text)obj60).text + GetText("Amulet_Clone", effectColors["ItemInfoDisplayPositive"], effectColors["Curse"], text9);
					}
					else if (name.StartsWith("Amulet_Healing", StringComparison.Ordinal))
					{
						Action_HealingGem component4 = ((Component)item).GetComponent<Action_HealingGem>();
						float num16 = (((Object)(object)component4 != (Object)null && component4.healingAffliction != null) ? (component4.healingAffliction.maxHealing * 100f) : 60f);
						float num17 = (((Object)(object)component4 != (Object)null && component4.invincibilityAffliction != null) ? GetAfflictionTotalTime(component4.invincibilityAffliction) : 10f);
						float num18 = (((Object)(object)component4 != (Object)null) ? (component4.minPetrify * 100f) : 0f);
						float num19 = (((Object)(object)component4 != (Object)null) ? (component4.maxPetrify * 100f) : 0f);
						TextMeshProUGUI obj61 = itemInfoDisplayTextMesh;
						((TMP_Text)obj61).text = ((TMP_Text)obj61).text + GetText("Amulet_Healing", effectColors["ItemInfoDisplayPositive"], num16.ToString("F0"), num17.ToString("F1").Replace(".0", ""), effectColors["Curse"], num18.ToString("F0"), num19.ToString("F0"));
					}
					else if (name.StartsWith("Amulet_InfiniteStamina", StringComparison.Ordinal))
					{
						float num20 = 0f;
						float num21 = 0f;
						Action_ApplyAffliction component5 = ((Component)item).GetComponent<Action_ApplyAffliction>();
						if ((Object)(object)component5 != (Object)null && component5.affliction != null)
						{
							num20 = GetAfflictionRadius(component5.affliction);
							num21 = GetAfflictionTotalTime(component5.affliction);
						}
						Action_ModifyStatus component6 = ((Component)item).GetComponent<Action_ModifyStatus>();
						float num22 = (((Object)(object)component6 != (Object)null) ? (component6.changeAmount * 100f) : 0f);
						TextMeshProUGUI obj62 = itemInfoDisplayTextMesh;
						((TMP_Text)obj62).text = ((TMP_Text)obj62).text + GetText("Amulet_InfiniteStamina", effectColors["ItemInfoDisplayPositive"], effectColors["Extra Stamina"], effectColors["Curse"], num21.ToString("F1").Replace(".0", ""), num20.ToString("F1").Replace(".0", ""), num22.ToString("F0"));
					}
					else if (name.StartsWith("Amulet_SuperJump", StringComparison.Ordinal))
					{
						Action_SuperJumpAmulet component7 = ((Component)item).GetComponent<Action_SuperJumpAmulet>();
						float num23 = (((Object)(object)component7 != (Object)null) ? ((float)Mathf.FloorToInt(component7.petrifyPerUse * 100f)) : 0f);
						float num24 = (((Object)(object)component7 != (Object)null) ? GetAfflictionRadius(((Action_ApplyAffliction)component7).affliction) : 0f);
						TextMeshProUGUI obj63 = itemInfoDisplayTextMesh;
						((TMP_Text)obj63).text = ((TMP_Text)obj63).text + GetText("Amulet_SuperJump", effectColors["ItemInfoDisplayPositive"], effectColors["Curse"], num23.ToString("F0"), num24.ToString("F1").Replace(".0", ""));
					}
					else if (name.StartsWith("ScoutsHonor", StringComparison.Ordinal))
					{
						TextMeshProUGUI obj64 = itemInfoDisplayTextMesh;
						((TMP_Text)obj64).text = ((TMP_Text)obj64).text + GetText("ScoutsHonor", effectColors["ItemInfoDisplayPositive"], effectColors["Injury"], effectColors["Curse"]);
					}
					else if (!name.Contains("Strange Gem"))
					{
						TextMeshProUGUI obj65 = itemInfoDisplayTextMesh;
						((TMP_Text)obj65).text = ((TMP_Text)obj65).text + GetText("Amulet_Base", effectColors["ItemInfoDisplayPositive"], effectColors["Curse"]);
					}
				}
				else if (((object)array3[num5]).GetType() == typeof(Action_StrangeGem))
				{
					if (((Object)gameObject).name.Equals("Strange Gem(Clone)") || ((Object)gameObject).name.Equals("Strange Gem"))
					{
						TextMeshProUGUI obj66 = itemInfoDisplayTextMesh;
						((TMP_Text)obj66).text = ((TMP_Text)obj66).text + GetText("StrangeGem", effectColors["ItemInfoDisplayPositive"]);
					}
				}
				else if (((object)array3[num5]).GetType() == typeof(Action_HealingGem))
				{
					if ((Object)(object)((Component)item).GetComponent<AmuletBase>() == (Object)null)
					{
						Action_HealingGem val40 = (Action_HealingGem)array3[num5];
						float num25 = ((val40.healingAffliction != null) ? (val40.healingAffliction.maxHealing * 100f) : 0f);
						float num26 = ((val40.invincibilityAffliction != null) ? GetAfflictionTotalTime(val40.invincibilityAffliction) : 0f);
						float num27 = val40.minPetrify * 100f;
						float num28 = val40.maxPetrify * 100f;
						TextMeshProUGUI obj67 = itemInfoDisplayTextMesh;
						((TMP_Text)obj67).text = ((TMP_Text)obj67).text + GetText("HealingGem", num25.ToString("F1").Replace(".0", ""), effectColors["ItemInfoDisplayPositive"], effectColors["Curse"], num26.ToString("F1").Replace(".0", ""), num27.ToString("F0"), num28.ToString("F0"));
					}
				}
				else if (((object)array3[num5]).GetType() == typeof(Action_CloneSelectedItem))
				{
					if ((Object)(object)((Component)item).GetComponent<AmuletBase>() == (Object)null)
					{
						TextMeshProUGUI obj68 = itemInfoDisplayTextMesh;
						((TMP_Text)obj68).text = ((TMP_Text)obj68).text + GetText("Amulet_Clone", effectColors["ItemInfoDisplayPositive"], effectColors["Curse"], "");
					}
				}
				else if (((object)array3[num5]).GetType() == typeof(Action_SuperJumpAmulet))
				{
					if ((Object)(object)((Component)item).GetComponent<AmuletBase>() == (Object)null)
					{
						Action_SuperJumpAmulet component8 = ((Component)item).GetComponent<Action_SuperJumpAmulet>();
						float num29 = (((Object)(object)component8 != (Object)null) ? ((float)Mathf.FloorToInt(component8.petrifyPerUse * 100f)) : 0f);
						float num30 = (((Object)(object)component8 != (Object)null) ? GetAfflictionRadius(((Action_ApplyAffliction)component8).affliction) : 0f);
						TextMeshProUGUI obj69 = itemInfoDisplayTextMesh;
						((TMP_Text)obj69).text = ((TMP_Text)obj69).text + GetText("Amulet_SuperJump", effectColors["ItemInfoDisplayPositive"], effectColors["Curse"], num29.ToString("F0"), num30.ToString("F1").Replace(".0", ""));
					}
				}
				else if (((object)array3[num5]).GetType() == typeof(Action_WarpToShadowRealm))
				{
					if ((Object)(object)((Component)item).GetComponent<AmuletBase>() == (Object)null)
					{
						TextMeshProUGUI obj70 = itemInfoDisplayTextMesh;
						((TMP_Text)obj70).text = ((TMP_Text)obj70).text + GetText("ScoutsHonor", effectColors["ItemInfoDisplayPositive"], effectColors["Injury"], effectColors["Curse"]);
					}
				}
				else if (((object)array3[num5]).GetType() == typeof(Action_Antizooka))
				{
					TextMeshProUGUI obj71 = itemInfoDisplayTextMesh;
					((TMP_Text)obj71).text = ((TMP_Text)obj71).text + GetText("AntiZooka", effectColors["Injury"], effectColors["ItemInfoDisplayPositive"]);
				}
				else if (((object)array3[num5]).GetType() == typeof(Action_SacrificeFriend))
				{
					TextMeshProUGUI obj72 = itemInfoDisplayTextMesh;
					((TMP_Text)obj72).text = ((TMP_Text)obj72).text + GetText("RitualDagger", effectColors["Curse"], "50", "10");
				}
				else if (((object)array3[num5]).GetType() == typeof(Action_Numb))
				{
					Action_Numb val41 = (Action_Numb)array3[num5];
					float num31 = ApplyCookingMultiplier(val41.numbAmount, cookingEffectMultiplier);
					TextMeshProUGUI obj73 = itemInfoDisplayTextMesh;
					((TMP_Text)obj73).text = ((TMP_Text)obj73).text + GetText("Numb", effectColors["Drowsy"], num31.ToString("F1").Replace(".0", ""));
				}
				else if (((object)array3[num5]).GetType() == typeof(WarpOnThrow))
				{
					TextMeshProUGUI obj74 = itemInfoDisplayTextMesh;
					((TMP_Text)obj74).text = ((TMP_Text)obj74).text + GetText("WarpOnThrow", effectColors["Injury"]);
				}
				else if (((object)array3[num5]).GetType() == typeof(Glider))
				{
					Glider val42 = (Glider)array3[num5];
					TextMeshProUGUI obj75 = itemInfoDisplayTextMesh;
					((TMP_Text)obj75).text = ((TMP_Text)obj75).text + GetText("Glider", effectColors["Extra Stamina"], (Mathf.Min(val42.stamUse, 1f) * 100f).ToString("F1").Replace(".0", ""));
				}
				else
				{
					if (!(((object)array3[num5]).GetType() == typeof(ItemCooking)))
					{
						continue;
					}
					val = (ItemCooking)array3[num5];
					bool flag5 = val.wreckWhenCooked || flag2;
					bool flag6 = !flag && !flag5;
					bool hasDeltaHeader;
					List<string> list2 = BuildNextCookDeltaLines(val, list, flag3, flag5, cookingEffectMultiplier, isConsumable, flag6, suppressThrowAchievement, suppressNoEffectHint, out hasDeltaHeader);
					bool flag7 = flag6 && val.timesCookedLocal == 0;
					string text10 = null;
					bool flag8 = false;
					if (flag7 && !hasDeltaHeader && list2.Count == 1 && IsCookNextHintLine(list2[0]))
					{
						text10 = list2[0];
						flag8 = true;
					}
					bool flag9 = false;
					if (!val.canBeCooked)
					{
						suffixCooked += GetText("COOK_DISABLED", effectColors["Curse"]);
					}
					else if (flag5 && val.timesCookedLocal >= 1)
					{
						suffixCooked += GetText("COOKED_BROKEN", effectColors["Curse"]);
					}
					else if (val.timesCookedLocal >= 12)
					{
						suffixCooked += GetText("COOKED_MAX", effectColors["Curse"], val.timesCookedLocal.ToString());
					}
					else if (val.timesCookedLocal == 0)
					{
						if (flag6)
						{
							suffixCooked += GetText("COOK", effectColors["Extra Stamina"]);
							if (hasDeltaHeader)
							{
								suffixCooked = suffixCooked + " " + GetText("COOK_NEXT_DELTA");
								flag9 = true;
							}
							else if (!string.IsNullOrWhiteSpace(text10))
							{
								suffixCooked = suffixCooked + " " + text10;
							}
						}
					}
					else if (val.timesCookedLocal <= 2)
					{
						suffixCooked += GetText("COOKED", effectColors["Extra Stamina"], val.timesCookedLocal.ToString());
						if (hasDeltaHeader)
						{
							suffixCooked = suffixCooked + " " + GetText("COOK_NEXT_DELTA");
							flag9 = true;
						}
					}
					else if (val.timesCookedLocal == 3)
					{
						suffixCooked += GetText("COOKED", effectColors["Injury"], val.timesCookedLocal.ToString());
						if (hasDeltaHeader)
						{
							suffixCooked = suffixCooked + " " + GetText("COOK_NEXT_DELTA");
							flag9 = true;
						}
					}
					else if (val.timesCookedLocal >= 4)
					{
						suffixCooked += GetText("COOKED", effectColors["Poison"], val.timesCookedLocal.ToString());
						if (hasDeltaHeader)
						{
							suffixCooked = suffixCooked + " " + GetText("COOK_NEXT_DELTA");
							flag9 = true;
						}
					}
					if (val.canBeCooked && val.timesCookedLocal < 12 && list2.Count > 0)
					{
						if (flag8 && text10 != null && list2.Count == 1 && list2[0] == text10)
						{
							list2.Clear();
						}
						if (hasDeltaHeader && !flag9)
						{
							list2.Insert(0, GetText("COOK_NEXT_DELTA"));
						}
						AppendCookDeltaLines(ref suffixCooked, list2);
					}
				}
			}
			if (array2.Length != 0)
			{
				bool flag10 = (Object)(object)((Component)item).GetComponent<AmuletBase>() != (Object)null;
				Dictionary<string, float> dictionary = new Dictionary<string, float>();
				Action_ModifyStatus[] array4 = array2;
				foreach (Action_ModifyStatus val43 in array4)
				{
					if (!((Object)(object)val43 == (Object)null) && !flag10)
					{
						float num33 = ApplyCookingMultiplier(val43.changeAmount, cookingEffectMultiplier);
						string key = ((object)Unsafe.As<STATUSTYPE, STATUSTYPE>(ref val43.statusType)/*cast due to .constrained prefix*/).ToString();
						if (dictionary.TryGetValue(key, out var value2))
						{
							dictionary[key] = value2 + num33;
						}
						else
						{
							dictionary[key] = num33;
						}
					}
				}
				foreach (KeyValuePair<string, float> item2 in dictionary)
				{
					text += ProcessEffect(item2.Value, item2.Key);
				}
			}
			if (text.Length > 0 && flag4)
			{
				((TMP_Text)itemInfoDisplayTextMesh).text = text + "\n" + ((TMP_Text)itemInfoDisplayTextMesh).text;
			}
			if (text4.Length > 0)
			{
				TextMeshProUGUI obj76 = itemInfoDisplayTextMesh;
				((TMP_Text)obj76).text = ((TMP_Text)obj76).text + "\n" + text4;
			}
			string text11 = text2 + text3;
			if (!string.IsNullOrEmpty(suffixCooked))
			{
				if (!string.IsNullOrEmpty(text11))
				{
					text11 += "\n\n";
				}
				text11 += suffixCooked;
			}
			if (!string.IsNullOrEmpty(text11))
			{
				if (((TMP_Text)itemInfoDisplayTextMesh).text.Length > 0 && !((TMP_Text)itemInfoDisplayTextMesh).text.EndsWith("\n\n"))
				{
					if (((TMP_Text)itemInfoDisplayTextMesh).text.EndsWith("\n"))
					{
						TextMeshProUGUI obj77 = itemInfoDisplayTextMesh;
						((TMP_Text)obj77).text = ((TMP_Text)obj77).text + "\n";
					}
					else
					{
						TextMeshProUGUI obj78 = itemInfoDisplayTextMesh;
						((TMP_Text)obj78).text = ((TMP_Text)obj78).text + "\n\n";
					}
				}
				TextMeshProUGUI obj79 = itemInfoDisplayTextMesh;
				((TMP_Text)obj79).text = ((TMP_Text)obj79).text + text11;
			}
			while (((TMP_Text)itemInfoDisplayTextMesh).text.Contains("\n\n\n"))
			{
				((TMP_Text)itemInfoDisplayTextMesh).text = ((TMP_Text)itemInfoDisplayTextMesh).text.Replace("\n\n\n", "\n\n");
			}
		}

		private static string AppendWithSectionSpacing(string target, string addition)
		{
			if (string.IsNullOrEmpty(addition))
			{
				return target;
			}
			if (target.Length > 0 && !target.EndsWith("\n\n"))
			{
				target += (target.EndsWith("\n") ? "\n" : "\n\n");
			}
			target += addition;
			return target;
		}

		private static string AppendHealingPuffShroomEffectInfo(GameObject itemGameObj, string target)
		{
			return AppendStatusFieldInfo(itemGameObj, target);
		}

		private static string AppendStatusFieldInfo(GameObject source, string target)
		{
			if ((Object)(object)source == (Object)null)
			{
				return target;
			}
			StatusField[] array = source.GetComponentsInChildren<StatusField>(true);
			if (array == null)
			{
				array = Array.Empty<StatusField>();
			}
			Dictionary<string, float> dictionary = new Dictionary<string, float>();
			Dictionary<string, float> dictionary2 = new Dictionary<string, float>();
			StatusField[] array2 = array;
			foreach (StatusField val in array2)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				string text = ((object)Unsafe.As<STATUSTYPE, STATUSTYPE>(ref ((StatusFieldBase)val).statusType)/*cast due to .constrained prefix*/).ToString();
				if (!string.IsNullOrEmpty(text))
				{
					dictionary[text] = (dictionary.TryGetValue(text, out var value) ? (value + ((StatusFieldBase)val).statusAmountPerSecond) : ((StatusFieldBase)val).statusAmountPerSecond);
					if (((StatusFieldBase)val).statusAmountOnEntry != 0f)
					{
						dictionary2[text] = (dictionary2.TryGetValue(text, out var value2) ? (value2 + ((StatusFieldBase)val).statusAmountOnEntry) : ((StatusFieldBase)val).statusAmountOnEntry);
					}
				}
				if (((StatusFieldBase)val).additionalStatuses == null)
				{
					continue;
				}
				foreach (StatusFieldStatus additionalStatus in ((StatusFieldBase)val).additionalStatuses)
				{
					string text2 = ((object)Unsafe.As<STATUSTYPE, STATUSTYPE>(ref additionalStatus.statusType)/*cast due to .constrained prefix*/).ToString();
					if (!string.IsNullOrEmpty(text2))
					{
						dictionary[text2] = (dictionary.TryGetValue(text2, out var value3) ? (value3 + additionalStatus.statusAmountPerSecond) : additionalStatus.statusAmountPerSecond);
					}
				}
			}
			if (dictionary.Count == 0 && dictionary2.Count == 0)
			{
				dictionary2["Injury"] = -0.15f;
				dictionary["Injury"] = -0.025f;
				dictionary["Poison"] = -0.05f;
			}
			List<string> list = new List<string>();
			string text3 = GetText("HealingPuffShroom_FollowupPerSecond");
			foreach (KeyValuePair<string, float> item in dictionary2.OrderBy((KeyValuePair<string, float> k) => k.Key))
			{
				string text4 = ToInlineText(ProcessEffectOnEntry(item.Value, item.Key));
				if (!string.IsNullOrWhiteSpace(text4))
				{
					list.Add("• " + text4 + text3);
				}
			}
			foreach (KeyValuePair<string, float> item2 in dictionary.OrderBy((KeyValuePair<string, float> k) => k.Key))
			{
				string text5 = ToInlineText(ProcessEffectPerSecond(item2.Value, item2.Key));
				if (!string.IsNullOrWhiteSpace(text5))
				{
					list.Add("• " + text5);
				}
			}
			if (list.Count > 0)
			{
				target = target + string.Join("\n", list) + "\n";
			}
			return target;
		}

		private static string AppendLanternStatusPerSecond(GameObject itemGameObj, string target)
		{
			if ((Object)(object)itemGameObj == (Object)null)
			{
				return target;
			}
			StatusField[] componentsInChildren = itemGameObj.GetComponentsInChildren<StatusField>(true);
			if (componentsInChildren == null || componentsInChildren.Length == 0)
			{
				return target;
			}
			Dictionary<string, float> dictionary = new Dictionary<string, float>();
			Dictionary<string, float> dictionary2 = new Dictionary<string, float>();
			StatusField[] array = componentsInChildren;
			foreach (StatusField val in array)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				string text = ((object)Unsafe.As<STATUSTYPE, STATUSTYPE>(ref ((StatusFieldBase)val).statusType)/*cast due to .constrained prefix*/).ToString();
				if (!string.IsNullOrEmpty(text))
				{
					dictionary[text] = (dictionary.TryGetValue(text, out var value) ? (value + ((StatusFieldBase)val).statusAmountPerSecond) : ((StatusFieldBase)val).statusAmountPerSecond);
					if (((StatusFieldBase)val).statusAmountOnEntry != 0f)
					{
						dictionary2[text] = (dictionary2.TryGetValue(text, out var value2) ? (value2 + ((StatusFieldBase)val).statusAmountOnEntry) : ((StatusFieldBase)val).statusAmountOnEntry);
					}
				}
				foreach (StatusFieldStatus additionalStatus in ((StatusFieldBase)val).additionalStatuses)
				{
					string text2 = ((object)Unsafe.As<STATUSTYPE, STATUSTYPE>(ref additionalStatus.statusType)/*cast due to .constrained prefix*/).ToString();
					if (!string.IsNullOrEmpty(text2))
					{
						dictionary[text2] = (dictionary.TryGetValue(text2, out var value3) ? (value3 + additionalStatus.statusAmountPerSecond) : additionalStatus.statusAmountPerSecond);
					}
				}
			}
			AddFaerieLanternSporesPerSecond(itemGameObj, dictionary);
			foreach (KeyValuePair<string, float> item in dictionary.OrderBy((KeyValuePair<string, float> k) => k.Key))
			{
				target += ProcessEffectPerSecond(item.Value, item.Key);
			}
			foreach (KeyValuePair<string, float> item2 in dictionary2.OrderBy((KeyValuePair<string, float> k) => k.Key))
			{
				target += ProcessEffectOnEntry(item2.Value, item2.Key);
			}
			if (TryGetDispelFogFieldInfo(itemGameObj, out var innerRadius, out var outerRadius))
			{
				target += GetText("DispelFogField_Strength", effectColors["ItemInfoDisplayPositive"], GetEffectColor("Spores"), innerRadius.ToString("F1").Replace(".0", ""), outerRadius.ToString("F1").Replace(".0", ""));
			}
			return target;
		}

		private static void AddFaerieLanternSporesPerSecond(GameObject itemGameObj, Dictionary<string, float> totals)
		{
			if (totals != null && !((Object)(object)itemGameObj == (Object)null) && IsFaerieLantern(itemGameObj))
			{
				totals["Spores"] = (totals.TryGetValue("Spores", out var value) ? (value + -0.025f) : (-0.025f));
			}
		}

		private static bool IsFaerieLantern(GameObject itemGameObj)
		{
			if ((Object)(object)itemGameObj == (Object)null)
			{
				return false;
			}
			string text = ((Object)itemGameObj).name ?? string.Empty;
			return text.StartsWith("Lantern_Faerie", StringComparison.OrdinalIgnoreCase);
		}

		private static bool TryGetDispelFogFieldInfo(GameObject itemGameObj, out float innerRadius, out float outerRadius)
		{
			innerRadius = 0f;
			outerRadius = 0f;
			if ((Object)(object)itemGameObj == (Object)null)
			{
				return false;
			}
			Component[] componentsInChildren = itemGameObj.GetComponentsInChildren<Component>(true);
			Component[] array = componentsInChildren;
			foreach (Component val in array)
			{
				if (!((Object)(object)val == (Object)null) && ((object)val).GetType().Name == "DispelFogField")
				{
					Type type = ((object)val).GetType();
					FieldInfo field = type.GetField("innerRadius", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					FieldInfo field2 = type.GetField("outerRadius", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					if (field != null)
					{
						innerRadius = (float)field.GetValue(val);
					}
					if (field2 != null)
					{
						outerRadius = (float)field2.GetValue(val);
					}
					return true;
				}
			}
			return false;
		}

		private static string BuildRandomMushroomEffectText(object effect)
		{
			if (effect is Action_RandomMushroomEffect)
			{
				return BuildRandomMushroomEffectListText();
			}
			if (effect == null)
			{
				return GetText("RandomMushroomEffect");
			}
			HashSet<string> hashSet = new HashSet<string>();
			CollectStatusTypes(effect, hashSet);
			if (hashSet.Count == 0)
			{
				return GetText("RandomMushroomEffect");
			}
			List<string> list = new List<string>();
			foreach (string item in hashSet)
			{
				list.Add(FormatEffectNameWithColor(item));
			}
			string text = string.Join(", ", list);
			return GetText("RandomMushroomEffect_List", text);
		}

		private static string BuildRandomMushroomEffectListText()
		{
			string text = GetText("RandomMushroomEffect_Title");
			text += GetText("RandomMushroomEffect_0", effectColors["Extra Stamina"], "4");
			text += GetText("RandomMushroomEffect_1", effectColors["ItemInfoDisplayPositive"], "50", "150", "5", "1");
			text += GetText("RandomMushroomEffect_2", effectColors["ItemInfoDisplayPositive"], "3", "15");
			text += GetText("RandomMushroomEffect_3", effectColors["ItemInfoDisplayPositive"], "10");
			text += GetText("RandomMushroomEffect_4", effectColors["ItemInfoDisplayPositive"], effectColors["Hunger"], effectColors["Injury"], effectColors["Poison"], "<#CCCCCC>");
			text += GetText("RandomMushroomEffect_5", effectColors["Spores"]);
			text += GetText("RandomMushroomEffect_6", effectColors["ItemInfoDisplayNegative"], "60");
			text += GetText("RandomMushroomEffect_7", effectColors["ItemInfoDisplayNegative"]);
			text += GetText("RandomMushroomEffect_8", effectColors["ItemInfoDisplayNegative"], effectColors["Spores"]);
			return text + GetText("RandomMushroomEffect_9", effectColors["ItemInfoDisplayNegative"], "60");
		}

		private unsafe static void CollectStatusTypes(object value, HashSet<string> statusTypes)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			if (value == null)
			{
				return;
			}
			if (value is STATUSTYPE val)
			{
				statusTypes.Add(((object)(*(STATUSTYPE*)(&val))/*cast due to .constrained prefix*/).ToString());
				return;
			}
			Affliction val2 = (Affliction)((value is Affliction) ? value : null);
			if (val2 != null)
			{
				statusTypes.Add(((object)val2.GetAfflictionType()/*cast due to .constrained prefix*/).ToString());
			}
			else
			{
				if (!(value is IEnumerable enumerable) || value is string)
				{
					return;
				}
				foreach (object item in enumerable)
				{
					CollectStatusTypes(item, statusTypes);
				}
			}
		}

		private static string FormatEffectNameWithColor(string effect)
		{
			string text;
			try
			{
				text = GetText("Effect_" + effect.ToUpper()).ToUpper();
			}
			catch
			{
				text = effect.ToUpper();
			}
			return GetEffectColor(effect) + text + "</color>";
		}

		private static string ProcessEffect(float amount, string effect)
		{
			string text = "";
			string text2 = string.Empty;
			string key = string.Empty;
			if (amount == 0f)
			{
				return text;
			}
			if (amount > 0f)
			{
				text2 = ((!effect.Equals("Extra Stamina")) ? effectColors["ItemInfoDisplayNegative"] : effectColors["ItemInfoDisplayPositive"]);
				key = "GAIN";
			}
			else if (amount < 0f)
			{
				text2 = ((!effect.Equals("Extra Stamina")) ? effectColors["ItemInfoDisplayPositive"] : effectColors["ItemInfoDisplayNegative"]);
				key = "REMOVE";
			}
			return text + GetText("ProcessEffect", text2, GetText(key), GetEffectColor(effect), (Mathf.Abs(amount) * 100f).ToString("F1").Replace(".0", ""), GetText("Effect_" + effect.ToUpper()).ToUpper());
		}

		private static string ProcessEffectOverTime(float amountPerSecond, float rate, float time, string effect)
		{
			string text = "";
			string text2 = string.Empty;
			string key = string.Empty;
			if (amountPerSecond == 0f || time == 0f)
			{
				return text;
			}
			if (amountPerSecond > 0f)
			{
				text2 = ((!effect.Equals("Extra Stamina")) ? effectColors["ItemInfoDisplayNegative"] : effectColors["ItemInfoDisplayPositive"]);
				key = "GAIN";
			}
			else if (amountPerSecond < 0f)
			{
				text2 = ((!effect.Equals("Extra Stamina")) ? effectColors["ItemInfoDisplayPositive"] : effectColors["ItemInfoDisplayNegative"]);
				key = "REMOVE";
			}
			return text + GetText("ProcessEffectOverTime", text2, GetText(key), GetEffectColor(effect), (Mathf.Abs(amountPerSecond) * time * (1f / rate) * 100f).ToString("F1").Replace(".0", ""), GetText("Effect_" + effect.ToUpper()).ToUpper(), time.ToString());
		}

		private static string ProcessEffectPerSecond(float amountPerSecond, string effect)
		{
			string text = "";
			string text2 = string.Empty;
			string key = string.Empty;
			if (amountPerSecond == 0f)
			{
				return text;
			}
			if (amountPerSecond > 0f)
			{
				text2 = ((!effect.Equals("Extra Stamina")) ? effectColors["ItemInfoDisplayNegative"] : effectColors["ItemInfoDisplayPositive"]);
				key = "GAIN";
			}
			else if (amountPerSecond < 0f)
			{
				text2 = ((!effect.Equals("Extra Stamina")) ? effectColors["ItemInfoDisplayPositive"] : effectColors["ItemInfoDisplayNegative"]);
				key = "REMOVE";
			}
			string text3 = (Mathf.Abs(amountPerSecond) * 100f).ToString("F1").Replace(".0", "");
			return text + GetText("ProcessEffectPerSecond", text2, GetText(key), GetEffectColor(effect), text3, GetText("Effect_" + effect.ToUpper()).ToUpper());
		}

		private static string ProcessEffectOnEntry(float amount, string effect)
		{
			string text = "";
			string text2 = string.Empty;
			string key = string.Empty;
			if (amount == 0f)
			{
				return text;
			}
			if (amount > 0f)
			{
				text2 = ((!effect.Equals("Extra Stamina")) ? effectColors["ItemInfoDisplayNegative"] : effectColors["ItemInfoDisplayPositive"]);
				key = "GAIN";
			}
			else if (amount < 0f)
			{
				text2 = ((!effect.Equals("Extra Stamina")) ? effectColors["ItemInfoDisplayPositive"] : effectColors["ItemInfoDisplayNegative"]);
				key = "REMOVE";
			}
			return text + GetText("ProcessEffectOnEntry", text2, GetText(key), GetEffectColor(effect), (Mathf.Abs(amount) * 100f).ToString("F1").Replace(".0", ""), GetText("Effect_" + effect.ToUpper()).ToUpper());
		}

		private static string ProcessEffectInline(float amount, string effect)
		{
			string text = ProcessEffect(amount, effect);
			if (string.IsNullOrEmpty(text))
			{
				return text;
			}
			text = text.Replace("\r\n", " ").Replace("\n", " ").Replace("\r", " ");
			return text.Trim();
		}

		private static float ApplyCookingMultiplier(float amount, float cookingMultiplier)
		{
			if (amount == 0f || cookingMultiplier == 1f || float.IsNaN(cookingMultiplier) || float.IsInfinity(cookingMultiplier))
			{
				return amount;
			}
			return amount * cookingMultiplier;
		}

		private static float GetCookingEffectMultiplier(ItemCooking? itemCooking)
		{
			if ((Object)(object)itemCooking == (Object)null || itemCooking.timesCookedLocal <= 0)
			{
				return 1f;
			}
			EnsureCookingMultiplierGetter();
			if (cookingMultiplierGetter == null)
			{
				return 1f;
			}
			try
			{
				float num = cookingMultiplierGetter(itemCooking);
				if (float.IsNaN(num) || float.IsInfinity(num) || num == 0f)
				{
					return 1f;
				}
				return num;
			}
			catch
			{
				return 1f;
			}
		}

		private static void EnsureCookingMultiplierGetter()
		{
			if (cookingMultiplierResolved)
			{
				return;
			}
			cookingMultiplierResolved = true;
			Type typeFromHandle = typeof(ItemCooking);
			BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
			string[] array = new string[7] { "GetCookedEffectMultiplier", "GetCookedMultiplier", "GetCookingEffectMultiplier", "GetCookingMultiplier", "GetCookMultiplier", "GetEffectMultiplier", "GetCookedStatusMultiplier" };
			string[] array2 = array;
			foreach (string b in array2)
			{
				MethodInfo[] methods = typeFromHandle.GetMethods(bindingAttr);
				foreach (MethodInfo methodInfo in methods)
				{
					if (!string.Equals(methodInfo.Name, b, StringComparison.OrdinalIgnoreCase) || methodInfo.ReturnType != typeof(float))
					{
						continue;
					}
					ParameterInfo[] parameters = methodInfo.GetParameters();
					if (parameters.Length == 0)
					{
						MethodInfo captured = methodInfo;
						cookingMultiplierGetter = (ItemCooking itemCooking) => (float)captured.Invoke(itemCooking, null);
						cookingMultiplierSource = typeFromHandle.Name + "." + captured.Name + "()";
						Log.LogInfo((object)("[ItemInfoDisplay] Cooking multiplier resolved via " + cookingMultiplierSource + "."));
						return;
					}
					if (parameters.Length == 1 && parameters[0].ParameterType == typeof(int))
					{
						MethodInfo captured2 = methodInfo;
						cookingMultiplierGetter = (ItemCooking itemCooking) => (float)captured2.Invoke(itemCooking, new object[1] { itemCooking.timesCookedLocal });
						cookingMultiplierSource = typeFromHandle.Name + "." + captured2.Name + "(int)";
						Log.LogInfo((object)("[ItemInfoDisplay] Cooking multiplier resolved via " + cookingMultiplierSource + "."));
						return;
					}
				}
			}
			FieldInfo[] fields = typeFromHandle.GetFields(bindingAttr);
			foreach (FieldInfo fieldInfo in fields)
			{
				if (IsLikelyCookingMultiplierMember(fieldInfo.Name))
				{
					Func<ItemCooking, float> func = TryCreateMultiplierGetter(fieldInfo, fieldInfo.FieldType, fieldInfo.IsStatic);
					if (func != null)
					{
						cookingMultiplierGetter = func;
						cookingMultiplierSource = typeFromHandle.Name + "." + fieldInfo.Name;
						Log.LogInfo((object)("[ItemInfoDisplay] Cooking multiplier resolved via " + cookingMultiplierSource + "."));
						return;
					}
				}
			}
			PropertyInfo[] properties = typeFromHandle.GetProperties(bindingAttr);
			foreach (PropertyInfo propertyInfo in properties)
			{
				if (propertyInfo.CanRead && propertyInfo.GetIndexParameters().Length == 0 && IsLikelyCookingMultiplierMember(propertyInfo.Name))
				{
					bool isStatic = propertyInfo.GetMethod != null && propertyInfo.GetMethod.IsStatic;
					Func<ItemCooking, float> func2 = TryCreateMultiplierGetter(propertyInfo, propertyInfo.PropertyType, isStatic);
					if (func2 != null)
					{
						cookingMultiplierGetter = func2;
						cookingMultiplierSource = typeFromHandle.Name + "." + propertyInfo.Name;
						Log.LogInfo((object)("[ItemInfoDisplay] Cooking multiplier resolved via " + cookingMultiplierSource + "."));
						break;
					}
				}
			}
		}

		private static bool IsLikelyCookingMultiplierMember(string name)
		{
			if (string.IsNullOrWhiteSpace(name))
			{
				return false;
			}
			string text = name.ToLowerInvariant();
			if (!text.Contains("cook"))
			{
				return false;
			}
			if (!text.Contains("mult") && !text.Contains("scale"))
			{
				return text.Contains("effect");
			}
			return true;
		}

		private static Func<ItemCooking, float>? TryCreateMultiplierGetter(MemberInfo member, Type memberType, bool isStatic)
		{
			if (memberType == typeof(float))
			{
				return delegate(ItemCooking itemCooking)
				{
					object memberValue = GetMemberValue(member, isStatic, itemCooking);
					return (memberValue is float) ? ((float)memberValue) : 1f;
				};
			}
			if (memberType == typeof(float[]))
			{
				return delegate(ItemCooking itemCooking)
				{
					object memberValue = GetMemberValue(member, isStatic, itemCooking);
					return (memberValue is float[] values) ? GetMultiplierFromList(values, itemCooking.timesCookedLocal) : 1f;
				};
			}
			if (memberType == typeof(List<float>))
			{
				return delegate(ItemCooking itemCooking)
				{
					object memberValue = GetMemberValue(member, isStatic, itemCooking);
					return (memberValue is List<float> values) ? GetMultiplierFromList(values, itemCooking.timesCookedLocal) : 1f;
				};
			}
			if (memberType == typeof(AnimationCurve))
			{
				return delegate(ItemCooking itemCooking)
				{
					object memberValue = GetMemberValue(member, isStatic, itemCooking);
					AnimationCurve val = (AnimationCurve)((memberValue is AnimationCurve) ? memberValue : null);
					return (val != null) ? val.Evaluate((float)itemCooking.timesCookedLocal) : 1f;
				};
			}
			return null;
		}

		private static object GetMemberValue(MemberInfo member, bool isStatic, ItemCooking itemCooking)
		{
			try
			{
				if (member is FieldInfo fieldInfo)
				{
					return fieldInfo.GetValue(isStatic ? null : itemCooking);
				}
				if (member is PropertyInfo propertyInfo)
				{
					return propertyInfo.GetValue(isStatic ? null : itemCooking, null);
				}
			}
			catch
			{
				return null;
			}
			return null;
		}

		private static float GetMultiplierFromList(IReadOnlyList<float> values, int timesCooked)
		{
			if (values == null || values.Count == 0)
			{
				return 1f;
			}
			int index = Mathf.Clamp(timesCooked, 0, values.Count - 1);
			return values[index];
		}

		private static List<string> BuildNextCookDeltaLines(ItemCooking itemCooking, IReadOnlyList<AdditionalCookingBehavior> cookingBehaviors, bool hasCookUseExplosion, bool breaksWhenCooked, float cookingMultiplier, bool isConsumable, bool allowCookPreview, bool suppressThrowAchievement, bool suppressNoEffectHint, out bool hasDeltaHeader)
		{
			List<string> list = new List<string>();
			hasDeltaHeader = false;
			if ((Object)(object)itemCooking == (Object)null || !itemCooking.canBeCooked || itemCooking.timesCookedLocal >= 12)
			{
				return list;
			}
			if (suppressNoEffectHint)
			{
				return list;
			}
			int nextCooked = itemCooking.timesCookedLocal + 1;
			bool flag = WillExplodeOnNextCook(itemCooking, cookingBehaviors, nextCooked);
			List<string> list2 = new List<string>();
			if (allowCookPreview && !breaksWhenCooked && !itemCooking.ignoreDefaultCookBehavior && !flag)
			{
				list2.AddRange(BuildDefaultNextCookDeltaEffects(itemCooking, nextCooked, cookingMultiplier, isConsumable));
			}
			List<string> list3 = new List<string>();
			List<string> list4 = new List<string>();
			List<string> list5 = new List<string>();
			List<string> list6 = new List<string>();
			foreach (AdditionalCookingBehavior cookingBehavior in cookingBehaviors)
			{
				if (cookingBehavior == null || !WillTriggerBehavior(cookingBehavior, itemCooking.timesCookedLocal, nextCooked))
				{
					continue;
				}
				CookingBehavior_Explode val = (CookingBehavior_Explode)(object)((cookingBehavior is CookingBehavior_Explode) ? cookingBehavior : null);
				if (val != null)
				{
					if (CanExplodeWhenCooked(val, itemCooking))
					{
						list4.Add(TrimLeadingSeparator(GetText("COOK_EXPLODE", effectColors["Injury"])));
					}
					continue;
				}
				if (cookingBehavior is CookingBehavior_Wreck)
				{
					list4.Add(TrimLeadingSeparator(GetText("COOK_BROKEN", effectColors["Curse"])));
					continue;
				}
				CookingBehavior_AdjustStatusInstantly val2 = (CookingBehavior_AdjustStatusInstantly)(object)((cookingBehavior is CookingBehavior_AdjustStatusInstantly) ? cookingBehavior : null);
				if (val2 != null)
				{
					float amount = ApplyCookingMultiplier(val2.amount, cookingMultiplier);
					AppendHint(list3, ProcessEffectInline(amount, ((object)Unsafe.As<STATUSTYPE, STATUSTYPE>(ref val2.statusType)/*cast due to .constrained prefix*/).ToString()));
					continue;
				}
				CookingBehavior_ChangeAfflictionTime val3 = (CookingBehavior_ChangeAfflictionTime)(object)((cookingBehavior is CookingBehavior_ChangeAfflictionTime) ? cookingBehavior : null);
				if (val3 != null)
				{
					list4.Add(TrimLeadingSeparator(BuildAfflictionTimeChangeHint(val3)));
					continue;
				}
				CookingBehavior_RunActions val4 = (CookingBehavior_RunActions)(object)((cookingBehavior is CookingBehavior_RunActions) ? cookingBehavior : null);
				if (val4 != null)
				{
					if (val4.actionsToRun == null)
					{
						continue;
					}
					ItemAction[] actionsToRun = val4.actionsToRun;
					foreach (ItemAction val5 in actionsToRun)
					{
						if (!suppressThrowAchievement || !(val5 is Action_ThrowAchievement))
						{
							string hint = BuildActionEffectInline(val5, cookingMultiplier);
							AppendHint(list3, hint);
						}
					}
					continue;
				}
				CookingBehavior_EnableScripts val6 = (CookingBehavior_EnableScripts)(object)((cookingBehavior is CookingBehavior_EnableScripts) ? cookingBehavior : null);
				if (val6 != null)
				{
					AddScriptEffectHints(list5, val6.scriptsToEnable, cookingMultiplier, suppressThrowAchievement, allowCookPreview);
					continue;
				}
				if (cookingBehavior is CookingBehavior_MessUpAudio || cookingBehavior is CookingBehavior_ModifyAudioSourcePitch)
				{
					list4.Add(TrimLeadingSeparator(GetText("COOK_AUDIO", effectColors["ItemInfoDisplayPositive"])));
					continue;
				}
				CookingBehavior_ReplaceItem val7 = (CookingBehavior_ReplaceItem)(object)((cookingBehavior is CookingBehavior_ReplaceItem) ? cookingBehavior : null);
				if (val7 != null)
				{
					string text = "?";
					if ((Object)(object)val7.replaceWithItem != (Object)null)
					{
						text = GetLocalizedItemName(val7.replaceWithItem);
						if (string.IsNullOrEmpty(text) && val7.replaceWithItem.UIData != null)
						{
							text = val7.replaceWithItem.UIData.itemName;
						}
					}
					list4.Add(TrimLeadingSeparator(GetText("COOK_REPLACE", effectColors["ItemInfoDisplayPositive"], text)));
					continue;
				}
				if (cookingBehavior is CookingBehavior_AddPoisonOnUse)
				{
					list3.Add(GetText("COOK_ADD_POISON_ON_USE", effectColors["Poison"], "10"));
					continue;
				}
				CookingBehavior_ModifyEtcStats val8 = (CookingBehavior_ModifyEtcStats)(object)((cookingBehavior is CookingBehavior_ModifyEtcStats) ? cookingBehavior : null);
				if (val8 != null)
				{
					if (val8.canPocket && val8.canBackpack)
					{
						list4.Add(TrimLeadingSeparator(GetText("COOK_MODIFY_ETC", effectColors["ItemInfoDisplayPositive"])));
					}
					else if (!val8.canPocket && !val8.canBackpack)
					{
						list4.Add(TrimLeadingSeparator(GetText("COOK_MODIFY_ETC_NOPOCKET", effectColors["Curse"]) + GetText("COOK_MODIFY_ETC_NOBACKPACK", effectColors["Curse"])));
					}
					else if (!val8.canPocket)
					{
						list4.Add(TrimLeadingSeparator(GetText("COOK_MODIFY_ETC_NOPOCKET", effectColors["Curse"])));
					}
					else
					{
						list4.Add(TrimLeadingSeparator(GetText("COOK_MODIFY_ETC_NOBACKPACK", effectColors["Curse"])));
					}
				}
				else if (cookingBehavior is CookingBehavior_EnableDisableObjects)
				{
					list4.Add(TrimLeadingSeparator(GetText("COOK_ENABLE_DISABLE_OBJECTS", effectColors["ItemInfoDisplayPositive"])));
				}
				else if (cookingBehavior is CookingBehavior_EarlyWorm)
				{
					list4.Add(TrimLeadingSeparator(GetText("COOK_EARLYWORM", effectColors["ItemInfoDisplayPositive"])));
				}
				else if (IsDisableScriptsBehavior(cookingBehavior))
				{
					AddScriptEffectHints(list6, GetBehaviorScripts(cookingBehavior), cookingMultiplier, suppressThrowAchievement, allowCookPreview);
				}
				else if (IsModifyBugleWobbleBehavior(cookingBehavior))
				{
					list4.Add(TrimLeadingSeparator(GetText("COOK_BUGLE_WOBBLE", effectColors["ItemInfoDisplayPositive"])));
				}
			}
			if (list5.Count > 0 && list6.Count > 0)
			{
				List<string> list7 = list5.Intersect(list6).ToList();
				foreach (string duplicatedHint in list7)
				{
					list5.RemoveAll((string text4) => text4 == duplicatedHint);
					list6.RemoveAll((string text4) => text4 == duplicatedHint);
				}
			}
			if (list5.Count > 0)
			{
				list4.Add(TrimLeadingSeparator(GetText("COOK_ENABLE")) + string.Join(" ", list5));
			}
			if (list6.Count > 0)
			{
				list4.Add(TrimLeadingSeparator(GetText("COOK_DISABLE")) + string.Join(" ", list6));
			}
			if (allowCookPreview && hasCookUseExplosion)
			{
				list4.Add(TrimLeadingSeparator(GetText("COOK_USE_EXPLODE", effectColors["Injury"])));
			}
			if (breaksWhenCooked && list4.Count == 0)
			{
				list4.Add(TrimLeadingSeparator(GetText("COOK_BROKEN", effectColors["Curse"])));
			}
			if (allowCookPreview && list2.Count > 0)
			{
				foreach (string item in list2)
				{
					if (!string.IsNullOrWhiteSpace(item))
					{
						list.Add("• " + item);
					}
				}
				hasDeltaHeader = true;
			}
			if (list3.Count > 0)
			{
				string text2 = TrimLeadingSeparator(GetText("COOK_ON_COOK"));
				foreach (string item2 in list3)
				{
					if (!string.IsNullOrWhiteSpace(item2))
					{
						list.Add(text2 + item2);
					}
				}
			}
			if (list4.Count > 0)
			{
				list.AddRange(list4.Where((string line) => !string.IsNullOrWhiteSpace(line)));
			}
			if (allowCookPreview && !suppressNoEffectHint && list2.Count == 0 && !flag && !breaksWhenCooked && !hasCookUseExplosion && list3.Count == 0 && list4.Count == 0)
			{
				string text3 = TrimLeadingSeparator(GetText("COOK_NEXT_NONE", effectColors["Curse"]));
				if (!string.IsNullOrWhiteSpace(text3) && !list.Contains(text3))
				{
					list.Insert(0, text3);
				}
			}
			return list;
		}

		private static List<string> BuildDefaultNextCookDeltaEffects(ItemCooking itemCooking, int nextCooked, float cookingMultiplier, bool isConsumable)
		{
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			List<string> list = new List<string>();
			if ((Object)(object)itemCooking == (Object)null || !isConsumable)
			{
				return list;
			}
			Action_RestoreHunger component = ((Component)itemCooking).GetComponent<Action_RestoreHunger>();
			bool flag = (Object)(object)component != (Object)null && IsComponentActiveForDisplay((Component)(object)component);
			Action_GiveExtraStamina component2 = ((Component)itemCooking).GetComponent<Action_GiveExtraStamina>();
			bool flag2 = (Object)(object)component2 != (Object)null && IsComponentActiveForDisplay((Component)(object)component2);
			Action_InflictPoison component3 = ((Component)itemCooking).GetComponent<Action_InflictPoison>();
			bool flag3 = (Object)(object)component3 != (Object)null && IsComponentActiveForDisplay((Component)(object)component3);
			if (!flag && !flag2 && !flag3)
			{
				return list;
			}
			if (flag)
			{
				float restorationAmount = component.restorationAmount;
				float num = restorationAmount;
				if (nextCooked < 2)
				{
					num = restorationAmount * 2f;
				}
				else if (nextCooked > 2)
				{
					num = Mathf.Max(restorationAmount - 0.05f, 0f);
				}
				float num2 = ApplyCookingMultiplier(num - restorationAmount, cookingMultiplier);
				if (Mathf.Abs(num2) > 0.0001f)
				{
					list.Add(ProcessEffectInline(num2 * -1f, "Hunger"));
				}
			}
			float num3 = 0f;
			bool flag4 = false;
			if (flag2)
			{
				num3 = component2.amount;
				flag4 = true;
			}
			if (flag4)
			{
				float num4 = num3;
				if (nextCooked < 2)
				{
					num4 = Mathf.Max(0.1f, num3 * 1.5f);
				}
				else if (nextCooked > 2)
				{
					num4 = 0f;
				}
				float num5 = ApplyCookingMultiplier(num4 - num3, cookingMultiplier);
				if (Mathf.Abs(num5) > 0.0001f)
				{
					list.Add(ProcessEffectInline(num5, "Extra Stamina"));
				}
			}
			bool flag5 = false;
			if (itemCooking.additionalCookingBehaviors != null)
			{
				AdditionalCookingBehavior[] additionalCookingBehaviors = itemCooking.additionalCookingBehaviors;
				foreach (AdditionalCookingBehavior val in additionalCookingBehaviors)
				{
					if (val is CookingBehavior_AddPoisonOnUse && WillTriggerBehavior(val, itemCooking.timesCookedLocal, nextCooked))
					{
						flag5 = true;
						break;
					}
				}
			}
			if (nextCooked > 3 && !flag5)
			{
				float num6 = ApplyCookingMultiplier(0.1f, cookingMultiplier);
				if (Mathf.Abs(num6) > 0.0001f)
				{
					list.Add(ProcessEffectInline(num6, ((object)(STATUSTYPE)3/*cast due to .constrained prefix*/).ToString()));
				}
			}
			return list;
		}

		private static bool WillExplodeOnNextCook(ItemCooking itemCooking, IReadOnlyList<AdditionalCookingBehavior> cookingBehaviors, int nextCooked)
		{
			if ((Object)(object)itemCooking == (Object)null)
			{
				return false;
			}
			foreach (AdditionalCookingBehavior cookingBehavior in cookingBehaviors)
			{
				CookingBehavior_Explode val = (CookingBehavior_Explode)(object)((cookingBehavior is CookingBehavior_Explode) ? cookingBehavior : null);
				if (val != null && WillTriggerBehavior(cookingBehavior, itemCooking.timesCookedLocal, nextCooked) && CanExplodeWhenCooked(val, itemCooking))
				{
					return true;
				}
			}
			return false;
		}

		private static bool WillTriggerBehavior(AdditionalCookingBehavior behavior, int currentCooked, int nextCooked)
		{
			if (behavior == null)
			{
				return false;
			}
			if (nextCooked < behavior.cookedAmountToTrigger)
			{
				return false;
			}
			if (behavior.onlyOnce && currentCooked >= behavior.cookedAmountToTrigger)
			{
				return false;
			}
			return true;
		}

		private static bool CanExplodeWhenCooked(CookingBehavior_Explode explode, ItemCooking itemCooking)
		{
			if (explode == null || (Object)(object)itemCooking == (Object)null)
			{
				return false;
			}
			if (!explode.dontRunIfOutOfFuel)
			{
				return true;
			}
			try
			{
				FloatItemData data = ((ItemComponent)itemCooking).item.GetData<FloatItemData>((DataEntryKey)10);
				return data != null && data.Value > 0f;
			}
			catch
			{
				return true;
			}
		}

		private static bool IsDisableScriptsBehavior(AdditionalCookingBehavior behavior)
		{
			if (behavior != null)
			{
				return ((object)behavior).GetType().Name.IndexOf("DisableScripts", StringComparison.OrdinalIgnoreCase) >= 0;
			}
			return false;
		}

		private static bool IsModifyBugleWobbleBehavior(AdditionalCookingBehavior behavior)
		{
			if (behavior != null)
			{
				return ((object)behavior).GetType().Name.IndexOf("ModifyBugleWobble", StringComparison.OrdinalIgnoreCase) >= 0;
			}
			return false;
		}

		private static void AppendHint(List<string> target, string hint)
		{
			if (!string.IsNullOrWhiteSpace(hint) && !target.Contains(hint))
			{
				target.Add(hint);
			}
		}

		private static string BuildRaycastDartSection(Action_RaycastDart? effect, float cookingMultiplier)
		{
			string text = GetText("RaycastDart");
			if ((Object)(object)effect == (Object)null || effect.afflictionsOnHit == null || effect.afflictionsOnHit.Length == 0)
			{
				return text;
			}
			List<string> list = new List<string>();
			Affliction[] afflictionsOnHit = effect.afflictionsOnHit;
			foreach (Affliction val in afflictionsOnHit)
			{
				if (val != null)
				{
					string text2 = ToInlineText(ProcessAffliction(val, cookingMultiplier)).TrimEnd(',', ',');
					if (!string.IsNullOrWhiteSpace(text2))
					{
						list.Add(text2);
					}
				}
			}
			if (list.Count == 0)
			{
				return text;
			}
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append(text);
			stringBuilder.Append('\n');
			for (int j = 0; j < list.Count; j++)
			{
				bool flag = j < list.Count - 1;
				stringBuilder.Append("• ");
				stringBuilder.Append(list[j]);
				if (flag)
				{
					stringBuilder.Append(',');
				}
				stringBuilder.Append('\n');
			}
			return stringBuilder.ToString();
		}

		private static bool IsComponentActiveForDisplay(Component component)
		{
			if ((Object)(object)component == (Object)null)
			{
				return false;
			}
			if (component is ItemCooking)
			{
				return true;
			}
			Behaviour val = (Behaviour)(object)((component is Behaviour) ? component : null);
			if (val != null)
			{
				return val.isActiveAndEnabled;
			}
			return true;
		}

		private static bool IsConsumableForCookingDelta(IEnumerable<Component> components)
		{
			if (components == null)
			{
				return false;
			}
			foreach (Component component in components)
			{
				if ((Object)(object)component == (Object)null)
				{
					continue;
				}
				ItemUseFeedback val = (ItemUseFeedback)(object)((component is ItemUseFeedback) ? component : null);
				if (val != null)
				{
					if (val.useAnimation.Equals("Eat") || val.useAnimation.Equals("Drink") || val.useAnimation.Equals("Heal"))
					{
						return true;
					}
					continue;
				}
				if (component is Action_Consume)
				{
					return true;
				}
				if (component is Action_ConsumeAndSpawn)
				{
					return true;
				}
				if (component is Action_RaycastDart)
				{
					return true;
				}
				if (component is Action_SpawnGuidebookPage)
				{
					return true;
				}
				if (component is Action_RestoreHunger)
				{
					return true;
				}
				if (component is Action_GiveExtraStamina)
				{
					return true;
				}
			}
			return false;
		}

		private static void AppendCookDeltaLines(ref string suffixCooked, IReadOnlyList<string> lines)
		{
			if (lines == null || lines.Count == 0)
			{
				return;
			}
			string text = string.Join("\n", lines.Where((string line) => !string.IsNullOrWhiteSpace(line)));
			if (string.IsNullOrWhiteSpace(text))
			{
				return;
			}
			if (!string.IsNullOrEmpty(suffixCooked) && !suffixCooked.EndsWith("\n\n"))
			{
				if (suffixCooked.EndsWith("\n"))
				{
					suffixCooked += "\n";
				}
				else
				{
					suffixCooked += "\n\n";
				}
			}
			suffixCooked += text;
		}

		private static bool IsCookNextHintLine(string line)
		{
			if (string.IsNullOrWhiteSpace(line))
			{
				return false;
			}
			if (line.IndexOf("NEXT COOK", StringComparison.OrdinalIgnoreCase) < 0 && !line.Contains("下次烹饪", StringComparison.Ordinal))
			{
				return line.Contains("下次烹飪", StringComparison.Ordinal);
			}
			return true;
		}

		private static string TrimLeadingSeparator(string text)
		{
			if (string.IsNullOrEmpty(text))
			{
				return string.Empty;
			}
			if (text.StartsWith(" | ", StringComparison.Ordinal))
			{
				return text.Substring(3);
			}
			if (text.StartsWith("| ", StringComparison.Ordinal))
			{
				return text.Substring(2);
			}
			if (text.StartsWith("|", StringComparison.Ordinal))
			{
				return text.Substring(1);
			}
			return text;
		}

		private static string BuildAfflictionTimeChangeHint(CookingBehavior_ChangeAfflictionTime change)
		{
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			if (change == null)
			{
				return string.Empty;
			}
			string text = Mathf.Abs(change.change).ToString("F1").Replace(".0", "");
			string text2 = ((change.change >= 0f) ? "+" : "-");
			string name = "Affliction";
			try
			{
				if ((Object)(object)change.action != (Object)null && change.action.affliction != null)
				{
					name = ((object)change.action.affliction.GetAfflictionType()/*cast due to .constrained prefix*/).ToString();
				}
			}
			catch
			{
				name = "Affliction";
			}
			name = GetAfflictionDisplayName(name);
			return GetText("COOK_AFFLICTION_TIME", name, text2, text);
		}

		private static string GetAfflictionDisplayName(string name)
		{
			if (string.IsNullOrWhiteSpace(name))
			{
				return string.Empty;
			}
			string text = name.Trim();
			if (!(text == "Invincibility"))
			{
				if (text == "Numb")
				{
					return GetText("AFFLICTION_NAME_NUMB");
				}
				return name;
			}
			return GetText("AFFLICTION_NAME_INVINCIBILITY");
		}

		private static void AddScriptEffectHints(List<string> target, IEnumerable<MonoBehaviour> scripts, float cookingMultiplier, bool suppressThrowAchievement, bool allowCookPreview)
		{
			if (scripts == null)
			{
				return;
			}
			foreach (MonoBehaviour script in scripts)
			{
				if ((Object)(object)script == (Object)null || (suppressThrowAchievement && script is Action_ThrowAchievement))
				{
					continue;
				}
				ItemAction val = (ItemAction)(object)((script is ItemAction) ? script : null);
				if (val != null)
				{
					if (!allowCookPreview || !(val is Action_Spawn))
					{
						AppendHint(target, BuildActionEffectInline(val, cookingMultiplier));
					}
				}
				else
				{
					AppendHint(target, GetFriendlyActionName(((object)script).GetType()));
				}
			}
		}

		private static List<MonoBehaviour> GetBehaviorScripts(object behavior)
		{
			List<MonoBehaviour> list = new List<MonoBehaviour>();
			if (behavior == null)
			{
				return list;
			}
			BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
			Type type = behavior.GetType();
			FieldInfo[] fields = type.GetFields(bindingAttr);
			foreach (FieldInfo fieldInfo in fields)
			{
				if (NameContainsActionOrScript(fieldInfo.Name))
				{
					AddScriptsFromValue(list, fieldInfo.GetValue(behavior));
				}
			}
			PropertyInfo[] properties = type.GetProperties(bindingAttr);
			foreach (PropertyInfo propertyInfo in properties)
			{
				if (propertyInfo.CanRead && propertyInfo.GetIndexParameters().Length == 0 && NameContainsActionOrScript(propertyInfo.Name))
				{
					object obj = null;
					try
					{
						obj = propertyInfo.GetValue(behavior, null);
					}
					catch
					{
						continue;
					}
					AddScriptsFromValue(list, obj);
				}
			}
			return list;
		}

		private static void AddScriptsFromValue(List<MonoBehaviour> scripts, object value)
		{
			MonoBehaviour val = (MonoBehaviour)((value is MonoBehaviour) ? value : null);
			if (val != null)
			{
				scripts.Add(val);
			}
			else if (value is MonoBehaviour[] source)
			{
				scripts.AddRange(source.Where((MonoBehaviour s) => (Object)(object)s != (Object)null));
			}
			else if (value is IEnumerable<MonoBehaviour> source2)
			{
				scripts.AddRange(source2.Where((MonoBehaviour s) => (Object)(object)s != (Object)null));
			}
		}

		private unsafe static string BuildActionEffectInline(ItemAction action, float cookingMultiplier)
		{
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Invalid comparison between Unknown and I4
			//IL_02d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d5: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)action == (Object)null)
			{
				return string.Empty;
			}
			Action_RestoreHunger val = (Action_RestoreHunger)(object)((action is Action_RestoreHunger) ? action : null);
			if (val != null)
			{
				float num = ApplyCookingMultiplier(val.restorationAmount, cookingMultiplier);
				return ProcessEffectInline(num * -1f, "Hunger");
			}
			Action_GiveExtraStamina val2 = (Action_GiveExtraStamina)(object)((action is Action_GiveExtraStamina) ? action : null);
			if (val2 != null)
			{
				float amount = ApplyCookingMultiplier(val2.amount, cookingMultiplier);
				return ProcessEffectInline(amount, "Extra Stamina");
			}
			Action_ModifyStatus val3 = (Action_ModifyStatus)(object)((action is Action_ModifyStatus) ? action : null);
			if (val3 != null)
			{
				float num2 = ApplyCookingMultiplier(val3.changeAmount, cookingMultiplier);
				if ((int)val3.statusType == 5 && num2 > 0f && num2 <= 0.5001f)
				{
					num2 = 0.25f;
				}
				string text = ProcessEffectInline(num2, ((object)Unsafe.As<STATUSTYPE, STATUSTYPE>(ref val3.statusType)/*cast due to .constrained prefix*/).ToString());
				if (val3.ifSkeleton)
				{
					text = text + " " + GetText("COOK_IF_SKELETON");
				}
				return text;
			}
			Action_InflictPoison val4 = (Action_InflictPoison)(object)((action is Action_InflictPoison) ? action : null);
			if (val4 != null)
			{
				float amountPerSecond = ApplyCookingMultiplier(val4.poisonPerSecond, cookingMultiplier);
				string text2 = GetText("InflictPoison", val4.delay.ToString(), ProcessEffectOverTime(amountPerSecond, 1f, val4.inflictionTime, "Poison"));
				return ToInlineText(text2);
			}
			Action_AddOrRemoveThorns val5 = (Action_AddOrRemoveThorns)(object)((action is Action_AddOrRemoveThorns) ? action : null);
			if (val5 != null)
			{
				float amount2 = ApplyCookingMultiplier((float)val5.thornCount * 0.05f, cookingMultiplier);
				return