Decompiled source of Biome Crafting Tabs v0.3.0

BepInEx/plugins/TieredBlackForge.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("TieredBlackForge")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.1.0")]
[assembly: AssemblyInformationalVersion("0.1.1")]
[assembly: AssemblyProduct("TieredBlackForge")]
[assembly: AssemblyTitle("TieredBlackForge")]
[assembly: AssemblyVersion("0.1.1.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[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 TieredBlackForge
{
	[BepInPlugin("fr.dessouille.tieredblackforge", "Tiered Black Forge", "0.3.0")]
	public sealed class Plugin : BaseUnityPlugin
	{
		public const string PluginGuid = "fr.dessouille.tieredblackforge";

		public const string PluginName = "Tiered Black Forge";

		public const string PluginVersion = "0.3.0";

		internal static ManualLogSource Log;

		internal static ConfigEntry<string> MistlandsTokens;

		internal static ConfigEntry<string> AshlandsTokens;

		internal static ConfigEntry<string> DeepNorthTokens;

		internal static ConfigEntry<string> SwampTokens;

		internal static ConfigEntry<string> MountainTokens;

		internal static ConfigEntry<string> PlainsTokens;

		internal static ConfigEntry<string> MistlandsRecipes;

		internal static ConfigEntry<string> AshlandsRecipes;

		internal static ConfigEntry<string> DeepNorthRecipes;

		internal static ConfigEntry<string> SwampRecipes;

		internal static ConfigEntry<string> MountainRecipes;

		internal static ConfigEntry<string> PlainsRecipes;

		internal static ConfigEntry<string> MeadowsRecipes;

		internal static ConfigEntry<string> BlackForestRecipes;

		private Harmony _harmony;

		private void Awake()
		{
			//IL_0209: Unknown result type (might be due to invalid IL or missing references)
			//IL_0213: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			MistlandsTokens = ((BaseUnityPlugin)this).Config.Bind<string>("Classification", "MistlandsTokens", "blackcore,blackmarble,bluejute,sap,softtissue,yggdrasil,wisp,sealbreaker,scalehide,jotunpuff,magecap,royaljelly,bilebag,bloodclot,carapace,mandible,seeker", "Fragments de noms internes de matériaux associés aux Mistlands.");
			AshlandsTokens = ((BaseUnityPlugin)this).Config.Bind<string>("Classification", "AshlandsTokens", "flametal,grausten,proustite,sulfur,bonemaw,morgen,volture,fiddlehead,smokepuff,celestialfeather,charred,asksvin,askvin,bloodstone,jade,iolite", "Fragments de noms internes de matériaux associés aux Ashlands.");
			DeepNorthTokens = ((BaseUnityPlugin)this).Config.Bind<string>("Classification", "DeepNorthTokens", "timberwood,liquidfrost,petrifiedtissue,bloodgold,memorialcoal,frostfire,thunderblood,lingonberr,oat,poteitr,kale,moose,sealblubber,sealpel,elaking,longclaw,frozenbranch,leatherstrap,nornathread,deadpulp,frostcore", "Fragments de noms internes de matériaux associés au Deep North.");
			SwampTokens = ((BaseUnityPlugin)this).Config.Bind<string>("Classification", "SwampTokens", "iron,scrapiron,ancientbark,guck,root,chain,ooze,bloodbag,entrails,witheredbone", "Fragments de noms internes de matériaux associés au Swamp.");
			MountainTokens = ((BaseUnityPlugin)this).Config.Bind<string>("Classification", "MountainTokens", "silver,wolf,fenring,fenris,drake,freeze,obsidian,crystal,onion", "Fragments de noms internes de matériaux associés au Mountain.");
			PlainsTokens = ((BaseUnityPlugin)this).Config.Bind<string>("Classification", "PlainsTokens", "blackmetal,linen,flax,barley,lox,needle,tar,goblin,fuling", "Fragments de noms internes de matériaux associés au Plains.");
			MistlandsRecipes = ((BaseUnityPlugin)this).Config.Bind<string>("Overrides", "MistlandsRecipes", "", "Noms internes exacts de recettes forcées dans Mist Lands, séparés par des virgules.");
			AshlandsRecipes = ((BaseUnityPlugin)this).Config.Bind<string>("Overrides", "AshlandsRecipes", "", "Noms internes exacts de recettes forcées dans Ash Lands, séparés par des virgules.");
			DeepNorthRecipes = ((BaseUnityPlugin)this).Config.Bind<string>("Overrides", "DeepNorthRecipes", "", "Noms internes exacts de recettes forcées dans Deep North, séparés par des virgules.");
			SwampRecipes = ((BaseUnityPlugin)this).Config.Bind<string>("Overrides", "SwampRecipes", "", "Noms internes exacts de recettes forcées dans Swamp, séparés par des virgules.");
			MountainRecipes = ((BaseUnityPlugin)this).Config.Bind<string>("Overrides", "MountainRecipes", "", "Noms internes exacts de recettes forcées dans Mountain, séparés par des virgules.");
			PlainsRecipes = ((BaseUnityPlugin)this).Config.Bind<string>("Overrides", "PlainsRecipes", "", "Noms internes exacts de recettes forcées dans Plains, séparés par des virgules.");
			MeadowsRecipes = ((BaseUnityPlugin)this).Config.Bind<string>("Overrides", "MeadowsRecipes", "", "Noms internes exacts de recettes forcées dans Meadows, séparés par des virgules.");
			BlackForestRecipes = ((BaseUnityPlugin)this).Config.Bind<string>("Overrides", "BlackForestRecipes", "", "Noms internes exacts de recettes forcées dans Black Forest, séparés par des virgules.");
			_harmony = new Harmony("fr.dessouille.tieredblackforge");
			_harmony.PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Tiered Black Forge 0.3.0 charge.");
		}

		private void OnDestroy()
		{
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}
	}
	internal enum ForgeTier
	{
		Mistlands,
		Ashlands,
		DeepNorth,
		Swamp,
		Mountain,
		Plains,
		Meadows,
		BlackForest
	}
	internal enum ForgeStationKind
	{
		None,
		BlackForge,
		Forge,
		Workbench
	}
	internal static class TierState
	{
		internal static ForgeTier? Selected;

		internal static ForgeStationKind GetOpenStationKind()
		{
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return ForgeStationKind.None;
			}
			try
			{
				object? obj = AccessTools.Method(typeof(Player), "GetCurrentCraftingStation", (Type[])null, (Type[])null)?.Invoke(localPlayer, null);
				CraftingStation val = (CraftingStation)((obj is CraftingStation) ? obj : null);
				if ((Object)(object)val == (Object)null)
				{
					return ForgeStationKind.None;
				}
				string text = NormalizeStationName(((Object)((Component)val).gameObject).name);
				if (text.StartsWith("pieceblackforge") || text.StartsWith("blackforge"))
				{
					return ForgeStationKind.BlackForge;
				}
				if (text.StartsWith("pieceforge") || text == "forge" || text.StartsWith("forgeclone"))
				{
					return ForgeStationKind.Forge;
				}
				if (text.StartsWith("pieceworkbench") || text == "workbench" || text.StartsWith("workbenchclone"))
				{
					return ForgeStationKind.Workbench;
				}
				return ForgeStationKind.None;
			}
			catch (Exception ex)
			{
				Plugin.Log.LogDebug((object)("Detection de la forge impossible: " + ex.Message));
				return ForgeStationKind.None;
			}
		}

		internal static bool IsTierForStation(ForgeTier tier, ForgeStationKind station)
		{
			switch (station)
			{
			case ForgeStationKind.BlackForge:
				if (tier != ForgeTier.Mistlands && tier != ForgeTier.Ashlands)
				{
					return tier == ForgeTier.DeepNorth;
				}
				return true;
			case ForgeStationKind.Forge:
				if (tier != ForgeTier.Swamp && tier != ForgeTier.Mountain)
				{
					return tier == ForgeTier.Plains;
				}
				return true;
			case ForgeStationKind.Workbench:
				if (tier != ForgeTier.Meadows)
				{
					return tier == ForgeTier.BlackForest;
				}
				return true;
			default:
				return false;
			}
		}

		private static string NormalizeStationName(string value)
		{
			return new string((value ?? string.Empty).Where(char.IsLetterOrDigit).Select(char.ToLowerInvariant).ToArray());
		}

		internal static bool Matches(Recipe recipe, ForgeStationKind station)
		{
			if ((Object)(object)recipe == (Object)null)
			{
				return false;
			}
			if (!Selected.HasValue)
			{
				return true;
			}
			return RecipeClassifier.GetTier(recipe, station) == Selected;
		}
	}
	internal static class RecipeClassifier
	{
		private const string MistlandsOutputs = "jotunbane,demolisher,spinesnap,mistwalker,himminafl,krom,skollandhati,arbalest,carapace";

		private const string AshlandsOutputs = "ashlands,flametal,niedhogg,slayer,ripper,eldner,berzerkr,splitner,dyrnwyn,askhide,armorashlands,helmetashlands";

		private const string DeepNorthOutputs = "deepnorth,gold,nord,frostfire,thunderblood,protector,vanguard,caller";

		private const string SwampOutputs = "atgeiriron,axeiron,battleaxe,bowhuntsman,armoriron,helmetiron,maceiron,pickaxeiron,shieldbanded,shieldiron,shieldserpentscale,sledgeiron,spearelderbark,swordiron,ironnails";

		private const string EarlierForgeOutputs = "bronze";

		private const string MountainOutputs = "armorwolf,helmetdrake,bowdraugrfang,battleaxecrystal,knifesilver,macesilver,frostner,shieldsilver,spearwolf,swordsilver,capewolf";

		private const string PlainsOutputs = "atgeirblackmetal,axeblackmetal,knifeblackmetal,swordblackmetal,pickaxeblackmetal,maceneedle,porcupine,shieldblackmetal,armorpadded,helmetpadded";

		private const string MeadowsOutputs = "axeflint,bow,club,hammer,hoe,knifeflint,spearflint,shieldwood,shieldwoodtower,armorragschest,armorragslegs,armorleatherchest,armorleatherlegs,helmetleather,capedeerhide,arrowwood,arrowflint,arrowfire,pickaxeantler,torch";

		private const string BlackForestOutputs = "armortrollleatherchest,armortrollleatherlegs,helmettrollleather,capetrollhide,bowfinewood,sledgestagbreaker,sledgewood,shieldbonetower,arrowbronze";

		private const string MistlandsMaterials = "blackcore,blackmarble,bluejute,sap,softtissue,yggdrasilwood,wisp,scalehide,mushroomjotunpuff,mushroommagecap,royaljelly,bilebag,bloodclot,carapace,mandible,seekermeat,eitr,refinedeitr,upgrader5armor,upgrader5weapon";

		private const string AshlandsMaterials = "flametal,flametalnew,flametalorenew,grausten,proustitepowder,sulfurstone,bonemawmeat,morgenheart,volturemeat,smokepuff,celestialfeather,charredbone,charredcogwheel,asksvinhide,gemstoneblue,gemstonegreen,gemstonered,bloodstone,jade,iolite,upgrader6armor,upgrader6weapon";

		private const string DeepNorthMaterials = "gold,bloodgold,timberwood,frostcore,ice,nornthread,moosehide,sealhide,sealblubber,leatherstraps,crownjewel,faderember,memorialcoal,orbthunderblood,orbfrostfire,upgrader7armor,upgrader7weapon";

		private const string SwampMaterials = "iron,ironscrap,scrapiron,elderbark,root,guck,chain,ooze,bloodbag,entrails,witheredbone,trophydraugrelite,upgrader2armor,upgrader2weapon";

		private const string MountainMaterials = "silver,silverore,wolfpelt,wolffang,freezegland,obsidian,crystal,onion,trophyhatchling,upgrader3armor,upgrader3weapon";

		private const string PlainsMaterials = "blackmetal,blackmetalscrap,linenthread,flax,barley,loxpelt,needle,tar,upgrader4armor,upgrader4weapon";

		private const string WorkbenchLaterMaterials = "iron,ironscrap,scrapiron,elderbark,root,guck,chain,silver,wolfpelt,wolffang,freezegland,obsidian,crystal,blackmetal,blackmetalscrap,linenthread,loxpelt,needle,tar,carapace,eitr,refinedeitr,flametal,flametalnew,flametalorenew,asksvinhide,gold,bloodgold,timberwood,nornthread";

		private const string BlackForestMaterials = "trollhide,finewood,roundlog,corewood,bronze,surtlingcore,greydwarfeye,ancientseed,upgrader1armor,upgrader1weapon";

		private const string MeadowsMaterials = "wood,stone,flint,leatherscraps,deerhide,bonefragments,resin,feathers,hardantler,deertrophy,boarmeat,boarhide,upgrader0armor,upgrader0weapon";

		internal static ForgeTier? GetTier(Recipe recipe, ForgeStationKind station)
		{
			string normalizedRecipeName = Normalize(((Object)recipe).name);
			if (station == ForgeStationKind.BlackForge)
			{
				if (ContainsExact(Plugin.DeepNorthRecipes.Value, normalizedRecipeName))
				{
					return ForgeTier.DeepNorth;
				}
				if (ContainsExact(Plugin.AshlandsRecipes.Value, normalizedRecipeName))
				{
					return ForgeTier.Ashlands;
				}
				if (ContainsExact(Plugin.MistlandsRecipes.Value, normalizedRecipeName))
				{
					return ForgeTier.Mistlands;
				}
				if (OutputContainsAny(recipe, "deepnorth,gold,nord,frostfire,thunderblood,protector,vanguard,caller"))
				{
					return ForgeTier.DeepNorth;
				}
				if (OutputContainsAny(recipe, "ashlands,flametal,niedhogg,slayer,ripper,eldner,berzerkr,splitner,dyrnwyn,askhide,armorashlands,helmetashlands"))
				{
					return ForgeTier.Ashlands;
				}
				if (OutputContainsAny(recipe, "jotunbane,demolisher,spinesnap,mistwalker,himminafl,krom,skollandhati,arbalest,carapace"))
				{
					return ForgeTier.Mistlands;
				}
				if (HasAnyResource(recipe, "gold,bloodgold,timberwood,frostcore,ice,nornthread,moosehide,sealhide,sealblubber,leatherstraps,crownjewel,faderember,memorialcoal,orbthunderblood,orbfrostfire,upgrader7armor,upgrader7weapon") || HasAnyResource(recipe, Plugin.DeepNorthTokens.Value))
				{
					return ForgeTier.DeepNorth;
				}
				if (HasAnyResource(recipe, "flametal,flametalnew,flametalorenew,grausten,proustitepowder,sulfurstone,bonemawmeat,morgenheart,volturemeat,smokepuff,celestialfeather,charredbone,charredcogwheel,asksvinhide,gemstoneblue,gemstonegreen,gemstonered,bloodstone,jade,iolite,upgrader6armor,upgrader6weapon") || HasAnyResource(recipe, Plugin.AshlandsTokens.Value))
				{
					return ForgeTier.Ashlands;
				}
				if (HasAnyResource(recipe, "blackcore,blackmarble,bluejute,sap,softtissue,yggdrasilwood,wisp,scalehide,mushroomjotunpuff,mushroommagecap,royaljelly,bilebag,bloodclot,carapace,mandible,seekermeat,eitr,refinedeitr,upgrader5armor,upgrader5weapon") || HasAnyResource(recipe, Plugin.MistlandsTokens.Value))
				{
					return ForgeTier.Mistlands;
				}
			}
			if (station == ForgeStationKind.Forge)
			{
				if (OutputContainsAny(recipe, "bronze"))
				{
					return null;
				}
				if (ContainsExact(Plugin.PlainsRecipes.Value, normalizedRecipeName))
				{
					return ForgeTier.Plains;
				}
				if (ContainsExact(Plugin.MountainRecipes.Value, normalizedRecipeName))
				{
					return ForgeTier.Mountain;
				}
				if (ContainsExact(Plugin.SwampRecipes.Value, normalizedRecipeName))
				{
					return ForgeTier.Swamp;
				}
				if (OutputContainsAny(recipe, "atgeirblackmetal,axeblackmetal,knifeblackmetal,swordblackmetal,pickaxeblackmetal,maceneedle,porcupine,shieldblackmetal,armorpadded,helmetpadded"))
				{
					return ForgeTier.Plains;
				}
				if (OutputContainsAny(recipe, "armorwolf,helmetdrake,bowdraugrfang,battleaxecrystal,knifesilver,macesilver,frostner,shieldsilver,spearwolf,swordsilver,capewolf"))
				{
					return ForgeTier.Mountain;
				}
				if (OutputContainsAny(recipe, "atgeiriron,axeiron,battleaxe,bowhuntsman,armoriron,helmetiron,maceiron,pickaxeiron,shieldbanded,shieldiron,shieldserpentscale,sledgeiron,spearelderbark,swordiron,ironnails"))
				{
					return ForgeTier.Swamp;
				}
				if (HasAnyResource(recipe, "blackmetal,blackmetalscrap,linenthread,flax,barley,loxpelt,needle,tar,upgrader4armor,upgrader4weapon") || HasAnyResource(recipe, Plugin.PlainsTokens.Value))
				{
					return ForgeTier.Plains;
				}
				if (HasAnyResource(recipe, "silver,silverore,wolfpelt,wolffang,freezegland,obsidian,crystal,onion,trophyhatchling,upgrader3armor,upgrader3weapon") || HasAnyResource(recipe, Plugin.MountainTokens.Value))
				{
					return ForgeTier.Mountain;
				}
				if (HasAnyResource(recipe, "iron,ironscrap,scrapiron,elderbark,root,guck,chain,ooze,bloodbag,entrails,witheredbone,trophydraugrelite,upgrader2armor,upgrader2weapon") || HasAnyResource(recipe, Plugin.SwampTokens.Value))
				{
					return ForgeTier.Swamp;
				}
			}
			if (station == ForgeStationKind.Workbench)
			{
				if (ContainsExact(Plugin.BlackForestRecipes.Value, normalizedRecipeName))
				{
					return ForgeTier.BlackForest;
				}
				if (ContainsExact(Plugin.MeadowsRecipes.Value, normalizedRecipeName))
				{
					return ForgeTier.Meadows;
				}
				if (OutputEqualsAny(recipe, "armortrollleatherchest,armortrollleatherlegs,helmettrollleather,capetrollhide,bowfinewood,sledgestagbreaker,sledgewood,shieldbonetower,arrowbronze") || OutputStartsWithAny(recipe, "armortroll,helmettroll"))
				{
					return ForgeTier.BlackForest;
				}
				if (OutputEqualsAny(recipe, "axeflint,bow,club,hammer,hoe,knifeflint,spearflint,shieldwood,shieldwoodtower,armorragschest,armorragslegs,armorleatherchest,armorleatherlegs,helmetleather,capedeerhide,arrowwood,arrowflint,arrowfire,pickaxeantler,torch") || OutputStartsWithAny(recipe, "armortunic,armorharvester"))
				{
					return ForgeTier.Meadows;
				}
				if (HasAnyResource(recipe, "iron,ironscrap,scrapiron,elderbark,root,guck,chain,silver,wolfpelt,wolffang,freezegland,obsidian,crystal,blackmetal,blackmetalscrap,linenthread,loxpelt,needle,tar,carapace,eitr,refinedeitr,flametal,flametalnew,flametalorenew,asksvinhide,gold,bloodgold,timberwood,nornthread"))
				{
					return null;
				}
				if (HasAnyResource(recipe, "trollhide,finewood,roundlog,corewood,bronze,surtlingcore,greydwarfeye,ancientseed,upgrader1armor,upgrader1weapon"))
				{
					return ForgeTier.BlackForest;
				}
				if (HasAnyResource(recipe, "wood,stone,flint,leatherscraps,deerhide,bonefragments,resin,feathers,hardantler,deertrophy,boarmeat,boarhide,upgrader0armor,upgrader0weapon"))
				{
					return ForgeTier.Meadows;
				}
			}
			return null;
		}

		internal static string GetDebugName(Recipe recipe)
		{
			if ((Object)(object)recipe == (Object)null)
			{
				return "<null>";
			}
			string text = (((Object)(object)recipe.m_item != (Object)null) ? ((Object)recipe.m_item).name : "<no item>");
			return ((Object)recipe).name + " -> " + text;
		}

		private static bool OutputContainsAny(Recipe recipe, string csv)
		{
			object value;
			if (recipe == null)
			{
				value = null;
			}
			else
			{
				ItemDrop item = recipe.m_item;
				value = ((item != null) ? ((Object)item).name : null);
			}
			string output = Normalize((string)value);
			if (output.Length > 0)
			{
				return Split(csv).Any((string token) => output.Contains(token));
			}
			return false;
		}

		private static bool OutputEqualsAny(Recipe recipe, string csv)
		{
			object value;
			if (recipe == null)
			{
				value = null;
			}
			else
			{
				ItemDrop item = recipe.m_item;
				value = ((item != null) ? ((Object)item).name : null);
			}
			string output = Normalize((string)value);
			if (output.Length > 0)
			{
				return Split(csv).Any((string token) => output == token);
			}
			return false;
		}

		private static bool OutputStartsWithAny(Recipe recipe, string csv)
		{
			object value;
			if (recipe == null)
			{
				value = null;
			}
			else
			{
				ItemDrop item = recipe.m_item;
				value = ((item != null) ? ((Object)item).name : null);
			}
			string output = Normalize((string)value);
			if (output.Length > 0)
			{
				return Split(csv).Any((string token) => output.StartsWith(token));
			}
			return false;
		}

		private static bool HasAnyResource(Recipe recipe, string csv)
		{
			if (recipe?.m_resources == null)
			{
				return false;
			}
			HashSet<string> hashSet = new HashSet<string>(Split(csv));
			if (hashSet.Count == 0)
			{
				return false;
			}
			Requirement[] resources = recipe.m_resources;
			foreach (Requirement obj in resources)
			{
				object value;
				if (obj == null)
				{
					value = null;
				}
				else
				{
					ItemDrop resItem = obj.m_resItem;
					value = ((resItem != null) ? ((Object)resItem).name : null);
				}
				string text = Normalize((string)value);
				if (text.Length > 0 && hashSet.Contains(text))
				{
					return true;
				}
			}
			return false;
		}

		private static bool ContainsExact(string csv, string normalizedRecipeName)
		{
			return Split(csv).Any((string value) => value == normalizedRecipeName);
		}

		private static IEnumerable<string> Split(string csv)
		{
			return from value in (csv ?? string.Empty).Split(new char[4] { ',', ';', '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries).Select(Normalize)
				where value.Length > 0
				select value;
		}

		private static string Normalize(string value)
		{
			return new string((value ?? string.Empty).Where(char.IsLetterOrDigit).Select(char.ToLowerInvariant).ToArray());
		}
	}
	internal static class ForgeTabs
	{
		private static readonly Dictionary<ForgeTier, Button> Buttons = new Dictionary<ForgeTier, Button>();

		private static readonly MethodInfo OpenCraftTabMethod = AccessTools.Method(typeof(InventoryGui), "OnTabCraftPressed", Type.EmptyTypes, (Type[])null);

		private static readonly FieldInfo SelectedRecipeField = AccessTools.Field(typeof(InventoryGui), "m_selectedRecipe");

		private static readonly FieldInfo AvailableRecipesField = AccessTools.Field(typeof(InventoryGui), "m_availableRecipes");

		private static readonly MethodInfo SetRecipeMethod = AccessTools.Method(typeof(InventoryGui), "SetRecipe", new Type[2]
		{
			typeof(int),
			typeof(bool)
		}, (Type[])null);

		private static GameObject _root;

		private static InventoryGui _gui;

		private static bool _openingTierTab;

		private static bool _refreshingPanel;

		private static Scrollbar _savedRecipeScrollbar;

		private static float _savedRecipeScrollValue;

		private static bool _hasSavedRecipeScroll;

		private static Recipe _savedSelectedRecipe;

		internal static void Attach(InventoryGui gui)
		{
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Expected O, but got Unknown
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Expected O, but got Unknown
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Expected O, but got Unknown
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Expected O, but got Unknown
			//IL_0200: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Expected O, but got Unknown
			if ((Object)(object)gui == (Object)null || (Object)(object)gui.m_tabCraft == (Object)null || (Object)(object)gui.m_tabUpgrade == (Object)null || (Object)(object)_root != (Object)null)
			{
				return;
			}
			_gui = gui;
			GameObject gameObject = ((Component)gui.m_tabCraft).gameObject;
			Transform parent = gameObject.transform.parent;
			_root = new GameObject("TieredBlackForgeTabs", new Type[1] { typeof(RectTransform) });
			RectTransform component = _root.GetComponent<RectTransform>();
			((Transform)component).SetParent(parent, false);
			component.anchorMin = Vector2.zero;
			component.anchorMax = Vector2.one;
			component.pivot = new Vector2(0.5f, 0.5f);
			component.anchoredPosition = Vector2.zero;
			component.sizeDelta = Vector2.zero;
			((Transform)component).SetAsLastSibling();
			RectTransform component2 = ((Component)gui.m_tabUpgrade).GetComponent<RectTransform>();
			CreateButton(gameObject, component2, ForgeTier.Mistlands, "Mistlands", 0);
			CreateButton(gameObject, component2, ForgeTier.Ashlands, "Ashlands", 1);
			CreateButton(gameObject, component2, ForgeTier.DeepNorth, "Deep North", 2);
			CreateButton(gameObject, component2, ForgeTier.Swamp, "Swamp", 0);
			CreateButton(gameObject, component2, ForgeTier.Mountain, "Mountain", 1);
			CreateButton(gameObject, component2, ForgeTier.Plains, "Plains", 2);
			CreateButton(gameObject, component2, ForgeTier.Meadows, "Meadows", 0);
			CreateButton(gameObject, component2, ForgeTier.BlackForest, "Black Forest", 1);
			ButtonClickedEvent originalCraftClick = gui.m_tabCraft.onClick;
			gui.m_tabCraft.onClick = new ButtonClickedEvent();
			((UnityEvent)gui.m_tabCraft.onClick).AddListener((UnityAction)delegate
			{
				if (!_openingTierTab)
				{
					ClearTierFilter();
				}
				((UnityEvent)originalCraftClick).Invoke();
				RefreshSelection();
				ResetRecipeScrollToTop(gui);
			});
			ButtonClickedEvent originalUpgradeClick = gui.m_tabUpgrade.onClick;
			gui.m_tabUpgrade.onClick = new ButtonClickedEvent();
			((UnityEvent)gui.m_tabUpgrade.onClick).AddListener((UnityAction)delegate
			{
				ClearTierFilter();
				((UnityEvent)originalUpgradeClick).Invoke();
				RefreshSelection();
				ResetRecipeScrollToTop(gui);
			});
			_root.SetActive(false);
			RefreshSelection();
		}

		private static void CreateButton(GameObject template, RectTransform upgradeRect, ForgeTier tier, string label, int index)
		{
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Expected O, but got Unknown
			//IL_0206: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Expected O, but got Unknown
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = Object.Instantiate<GameObject>(template, _root.transform, false);
			((Object)val).name = $"TierTab_{tier}";
			val.SetActive(true);
			Component[] components = val.GetComponents<Component>();
			foreach (Component val2 in components)
			{
				if ((Object)(object)val2 != (Object)null && ((object)val2).GetType().Name.IndexOf("Tab", StringComparison.OrdinalIgnoreCase) >= 0 && !(val2 is Button))
				{
					Object.Destroy((Object)(object)val2);
				}
			}
			RectTransform component = val.GetComponent<RectTransform>();
			Rect rect = upgradeRect.rect;
			float num = Mathf.Max(32f, ((Rect)(ref rect)).height);
			rect = upgradeRect.rect;
			float num2 = ((Rect)(ref rect)).width + 6f + (float)index * 106f;
			component.anchorMin = upgradeRect.anchorMin;
			component.anchorMax = upgradeRect.anchorMax;
			component.pivot = upgradeRect.pivot;
			component.sizeDelta = new Vector2(100f, num);
			component.anchoredPosition = upgradeRect.anchoredPosition + new Vector2(num2, 0f);
			CreateUnderline(val, template.transform.parent);
			TMP_Text componentInChildren = val.GetComponentInChildren<TMP_Text>(true);
			if ((Object)(object)componentInChildren != (Object)null)
			{
				TMP_Text componentInChildren2 = template.GetComponentInChildren<TMP_Text>(true);
				if ((Object)(object)componentInChildren2 != (Object)null)
				{
					componentInChildren.font = componentInChildren2.font;
					componentInChildren.fontSharedMaterial = componentInChildren2.fontSharedMaterial;
					componentInChildren.fontStyle = componentInChildren2.fontStyle;
					componentInChildren.alignment = componentInChildren2.alignment;
					((Graphic)componentInChildren).color = ((Graphic)componentInChildren2).color;
					componentInChildren.characterSpacing = componentInChildren2.characterSpacing;
					componentInChildren.fontSizeMax = componentInChildren2.fontSize;
				}
				componentInChildren.text = label.ToUpperInvariant();
				componentInChildren.enableAutoSizing = true;
				componentInChildren.fontSizeMin = 10f;
			}
			Button component2 = val.GetComponent<Button>();
			component2.onClick = new ButtonClickedEvent();
			((UnityEvent)component2.onClick).AddListener((UnityAction)delegate
			{
				Select(tier);
			});
			Buttons[tier] = component2;
		}

		private static void CreateUnderline(GameObject tab, Transform nativeTabsParent)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("TierTabUnderline", new Type[2]
			{
				typeof(RectTransform),
				typeof(Image)
			});
			val.transform.SetParent(tab.transform, false);
			val.transform.SetAsLastSibling();
			RectTransform component = val.GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0f, 0f);
			component.anchorMax = new Vector2(1f, 0f);
			component.pivot = new Vector2(0.5f, 0f);
			component.anchoredPosition = new Vector2(0f, -1f);
			component.sizeDelta = new Vector2(12f, 2f);
			Image component2 = val.GetComponent<Image>();
			((Graphic)component2).raycastTarget = false;
			Image val2 = FindNativeUnderline(nativeTabsParent);
			if ((Object)(object)val2 != (Object)null)
			{
				component2.sprite = val2.sprite;
				component2.overrideSprite = val2.overrideSprite;
				((Graphic)component2).material = ((Graphic)val2).material;
				((Graphic)component2).color = ((Graphic)val2).color;
				component2.type = val2.type;
				component2.preserveAspect = val2.preserveAspect;
			}
			else
			{
				((Graphic)component2).color = new Color(0.9f, 0.58f, 0.08f, 1f);
			}
		}

		private static Image FindNativeUnderline(Transform nativeTabsParent)
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)nativeTabsParent == (Object)null)
			{
				return null;
			}
			Image result = null;
			float num = float.MaxValue;
			Image[] componentsInChildren = ((Component)nativeTabsParent).GetComponentsInChildren<Image>(true);
			foreach (Image val in componentsInChildren)
			{
				if ((Object)(object)val == (Object)null || (Object)(object)((Graphic)val).rectTransform == (Object)null)
				{
					continue;
				}
				Rect rect = ((Graphic)val).rectTransform.rect;
				float num2 = Mathf.Abs(((Rect)(ref rect)).width);
				rect = ((Graphic)val).rectTransform.rect;
				float num3 = Mathf.Abs(((Rect)(ref rect)).height);
				if (!(num3 < 0.5f) && !(num3 > 8f) && !(num2 < 30f) && !(num2 < num3 * 5f) && !(((Graphic)val).color.a < 0.1f))
				{
					float num4 = ((((Graphic)val).color.r >= ((Graphic)val).color.b) ? 0f : 20f);
					float num5 = num3 + num4 - Mathf.Min(num2, 500f) * 0.001f;
					if (!(num5 >= num))
					{
						result = val;
						num = num5;
					}
				}
			}
			return result;
		}

		private static void Select(ForgeTier tier)
		{
			ForgeStationKind openStationKind = TierState.GetOpenStationKind();
			if (!TierState.IsTierForStation(tier, openStationKind))
			{
				return;
			}
			TierState.Selected = tier;
			_openingTierTab = true;
			try
			{
				if (OpenCraftTabMethod != null)
				{
					OpenCraftTabMethod.Invoke(_gui, null);
				}
				else
				{
					((UnityEvent)_gui.m_tabCraft.onClick).Invoke();
				}
			}
			finally
			{
				_openingTierTab = false;
			}
			RefreshSelection();
			ResetRecipeScrollToTop(_gui);
		}

		private static void ClearTierFilter()
		{
			TierState.Selected = null;
			RefreshSelection();
		}

		private static void RefreshSelection()
		{
			foreach (KeyValuePair<ForgeTier, Button> button in Buttons)
			{
				if ((Object)(object)button.Value != (Object)null)
				{
					((Selectable)button.Value).interactable = !TierState.Selected.HasValue || button.Key != TierState.Selected.Value;
				}
			}
			if (!((Object)(object)_gui == (Object)null) && TierState.Selected.HasValue)
			{
				if ((Object)(object)_gui.m_tabCraft != (Object)null)
				{
					((Selectable)_gui.m_tabCraft).interactable = !_refreshingPanel;
				}
				if ((Object)(object)_gui.m_tabUpgrade != (Object)null)
				{
					((Selectable)_gui.m_tabUpgrade).interactable = true;
				}
			}
		}

		internal static void SyncVisibility()
		{
			if ((Object)(object)_root == (Object)null)
			{
				return;
			}
			ForgeStationKind openStationKind = TierState.GetOpenStationKind();
			bool flag = openStationKind != ForgeStationKind.None;
			if (TierState.Selected.HasValue && !TierState.IsTierForStation(TierState.Selected.Value, openStationKind))
			{
				TierState.Selected = null;
			}
			if (_root.activeSelf != flag)
			{
				_root.SetActive(flag);
			}
			foreach (KeyValuePair<ForgeTier, Button> button in Buttons)
			{
				if ((Object)(object)button.Value != (Object)null)
				{
					((Component)button.Value).gameObject.SetActive(flag && TierState.IsTierForStation(button.Key, openStationKind));
				}
			}
			if (flag)
			{
				RefreshSelection();
			}
		}

		internal static bool IsBiomeCrafting(InventoryGui gui)
		{
			if ((Object)(object)gui != (Object)null && (Object)(object)gui == (Object)(object)_gui && TierState.Selected.HasValue)
			{
				return TierState.IsTierForStation(TierState.Selected.Value, TierState.GetOpenStationKind());
			}
			return false;
		}

		internal static bool BeginPanelRefresh(InventoryGui gui)
		{
			if (!IsBiomeCrafting(gui) || _refreshingPanel)
			{
				return false;
			}
			CaptureRecipeScrollPosition(gui);
			_refreshingPanel = true;
			if ((Object)(object)gui.m_tabCraft != (Object)null)
			{
				((Selectable)gui.m_tabCraft).interactable = false;
			}
			if ((Object)(object)gui.m_tabUpgrade != (Object)null)
			{
				((Selectable)gui.m_tabUpgrade).interactable = true;
			}
			return true;
		}

		internal static void EndPanelRefresh(bool ownsRefresh, bool restore)
		{
			if (!ownsRefresh)
			{
				return;
			}
			try
			{
				if (restore && IsBiomeCrafting(_gui))
				{
					RestoreSelectedRecipe();
					RestoreRecipeScrollPosition();
				}
			}
			finally
			{
				_hasSavedRecipeScroll = false;
				_savedSelectedRecipe = null;
				_savedRecipeScrollbar = null;
				_refreshingPanel = false;
				SyncVisibility();
			}
		}

		internal static void CaptureRecipeScrollPosition(InventoryGui gui)
		{
			_hasSavedRecipeScroll = false;
			_savedRecipeScrollbar = null;
			_savedSelectedRecipe = null;
			if ((Object)(object)gui == (Object)null || !TierState.Selected.HasValue)
			{
				return;
			}
			try
			{
				if (SelectedRecipeField != null)
				{
					_savedSelectedRecipe = GetRecipeFromEntry(SelectedRecipeField.GetValue(gui));
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogDebug((object)("Unable to capture the selected recipe: " + ex.Message));
			}
			Scrollbar val = FindRecipeScrollbar(gui);
			if (!((Object)(object)val == (Object)null))
			{
				_savedRecipeScrollbar = val;
				_savedRecipeScrollValue = val.value;
				_hasSavedRecipeScroll = true;
			}
		}

		private static Scrollbar FindRecipeScrollbar(InventoryGui gui)
		{
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Invalid comparison between Unknown and I4
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Invalid comparison between Unknown and I4
			if ((Object)(object)gui == (Object)null)
			{
				return null;
			}
			Scrollbar result = null;
			int num = int.MinValue;
			Scrollbar[] componentsInChildren = ((Component)gui).GetComponentsInChildren<Scrollbar>(true);
			foreach (Scrollbar val in componentsInChildren)
			{
				if (!((Object)(object)val == (Object)null))
				{
					string text = string.Empty;
					Transform val2 = ((Component)val).transform;
					while ((Object)(object)val2 != (Object)null && (Object)(object)val2 != (Object)(object)((Component)gui).transform.parent)
					{
						text = text + "/" + ((Object)val2).name.ToLowerInvariant();
						val2 = val2.parent;
					}
					int num2 = 0;
					if (text.Contains("recipe"))
					{
						num2 += 100;
					}
					if (text.Contains("craft"))
					{
						num2 += 50;
					}
					if (text.Contains("scroll"))
					{
						num2 += 10;
					}
					if (((Component)val).gameObject.activeInHierarchy)
					{
						num2 += 10;
					}
					if ((int)val.direction == 2 || (int)val.direction == 3)
					{
						num2 += 25;
					}
					if (num2 > num)
					{
						result = val;
						num = num2;
					}
				}
			}
			return result;
		}

		private static void ResetRecipeScrollToTop(InventoryGui gui)
		{
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Invalid comparison between Unknown and I4
			if ((Object)(object)gui == (Object)null)
			{
				return;
			}
			Scrollbar val = FindRecipeScrollbar(gui);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			ScrollRect[] componentsInChildren = ((Component)gui).GetComponentsInChildren<ScrollRect>(true);
			foreach (ScrollRect val2 in componentsInChildren)
			{
				if (!((Object)(object)val2 == (Object)null) && !((Object)(object)val2.verticalScrollbar != (Object)(object)val))
				{
					if ((Object)(object)val2.content != (Object)null)
					{
						LayoutRebuilder.ForceRebuildLayoutImmediate(val2.content);
					}
					val2.StopMovement();
					val2.verticalNormalizedPosition = 1f;
					return;
				}
			}
			val.value = (((int)val.direction == 3) ? 0f : 1f);
		}

		private static void RestoreRecipeScrollPosition()
		{
			if (_hasSavedRecipeScroll && !((Object)(object)_gui == (Object)null))
			{
				Scrollbar val = _savedRecipeScrollbar;
				if ((Object)(object)val == (Object)null)
				{
					val = FindRecipeScrollbar(_gui);
				}
				if (!((Object)(object)val == (Object)null))
				{
					val.value = _savedRecipeScrollValue;
				}
			}
		}

		private static Recipe GetRecipeFromEntry(object entry)
		{
			if (entry == null)
			{
				return null;
			}
			Recipe val = (Recipe)((entry is Recipe) ? entry : null);
			if (val != null)
			{
				return val;
			}
			Type type = entry.GetType();
			PropertyInfo propertyInfo = AccessTools.Property(type, "Recipe") ?? AccessTools.Property(type, "Key");
			if (propertyInfo != null)
			{
				object? value = propertyInfo.GetValue(entry, null);
				return (Recipe)((value is Recipe) ? value : null);
			}
			object? obj = (AccessTools.Field(type, "m_recipe") ?? AccessTools.Field(type, "Recipe"))?.GetValue(entry);
			return (Recipe)((obj is Recipe) ? obj : null);
		}

		private static void RestoreSelectedRecipe()
		{
			if ((Object)(object)_gui == (Object)null || (Object)(object)_savedSelectedRecipe == (Object)null)
			{
				return;
			}
			try
			{
				if (SetRecipeMethod == null || AvailableRecipesField == null)
				{
					Plugin.Log.LogWarning((object)"Recipe selection API unavailable; leaving the rebuilt recipe list unchanged.");
				}
				else
				{
					if (!(AvailableRecipesField.GetValue(_gui) is IList list))
					{
						return;
					}
					for (int i = 0; i < list.Count; i++)
					{
						Recipe recipeFromEntry = GetRecipeFromEntry(list[i]);
						if (!((Object)(object)recipeFromEntry == (Object)null) && (!((Object)(object)recipeFromEntry != (Object)(object)_savedSelectedRecipe) || string.Equals(((Object)recipeFromEntry).name, ((Object)_savedSelectedRecipe).name, StringComparison.Ordinal)))
						{
							SetRecipeMethod.Invoke(_gui, new object[2] { i, false });
							return;
						}
					}
					Plugin.Log.LogDebug((object)"Crafted recipe no longer available in the active tab.");
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Unable to restore the selected recipe after crafting: " + ex.Message));
			}
		}
	}
	[HarmonyPatch(typeof(InventoryGui), "Awake")]
	internal static class InventoryGuiAwakePatch
	{
		private static void Postfix(InventoryGui __instance)
		{
			ForgeTabs.Attach(__instance);
		}
	}
	[HarmonyPatch(typeof(InventoryGui), "UpdateCraftingPanel", new Type[] { typeof(bool) })]
	internal static class UpdateCraftingPanelPatch
	{
		private static void Prefix(InventoryGui __instance, out bool __state)
		{
			__state = ForgeTabs.BeginPanelRefresh(__instance);
		}

		private static void Postfix(ref bool __state)
		{
			bool ownsRefresh = __state;
			__state = false;
			ForgeTabs.EndPanelRefresh(ownsRefresh, restore: true);
			ForgeTabs.SyncVisibility();
		}

		private static Exception Finalizer(Exception __exception, bool __state)
		{
			ForgeTabs.EndPanelRefresh(__state, restore: false);
			return __exception;
		}
	}
	[HarmonyPatch]
	internal static class InventoryGuiBiomeCraftModePatch
	{
		private static IEnumerable<MethodBase> TargetMethods()
		{
			string[] array = new string[3] { "InCraftTab", "InUpradeTab", "InUpgradeTab" };
			foreach (string text in array)
			{
				MethodInfo methodInfo = AccessTools.Method(typeof(InventoryGui), text, Type.EmptyTypes, (Type[])null);
				if (methodInfo != null && methodInfo.ReturnType == typeof(bool))
				{
					yield return methodInfo;
				}
			}
		}

		private static void Postfix(InventoryGui __instance, MethodBase __originalMethod, ref bool __result)
		{
			if (ForgeTabs.IsBiomeCrafting(__instance))
			{
				__result = __originalMethod.Name == "InCraftTab";
			}
		}
	}
	[HarmonyPatch(typeof(InventoryGui), "UpdateRecipeList", new Type[] { typeof(List<Recipe>) })]
	internal static class UpdateRecipeListPatch
	{
		[HarmonyPriority(200)]
		private static void Prefix(ref List<Recipe> recipes)
		{
			ForgeStationKind station = TierState.GetOpenStationKind();
			if (recipes == null || station == ForgeStationKind.None)
			{
				return;
			}
			if (TierState.Selected.HasValue && !TierState.IsTierForStation(TierState.Selected.Value, station))
			{
				TierState.Selected = null;
			}
			if (!TierState.Selected.HasValue)
			{
				return;
			}
			int count = recipes.Count;
			foreach (Recipe recipe in recipes)
			{
				ForgeTier? tier = RecipeClassifier.GetTier(recipe, station);
				Plugin.Log.LogDebug((object)("Classification " + RecipeClassifier.GetDebugName(recipe) + " = " + (tier.HasValue ? tier.Value.ToString() : "non classee")));
			}
			recipes = recipes.Where((Recipe recipe) => TierState.Matches(recipe, station)).ToList();
			Plugin.Log.LogInfo((object)$"Onglet {TierState.Selected.Value}: {recipes.Count}/{count} recettes affichees.");
		}
	}
}