Decompiled source of LongBo v1.1.33

plugins/BatBoys-LongBo/LongBo.dll

Decompiled 10 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
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 UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("LongBo")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.1.33.0")]
[assembly: AssemblyInformationalVersion("1.1.33")]
[assembly: AssemblyProduct("LongBo")]
[assembly: AssemblyTitle("LongBo")]
[assembly: AssemblyVersion("1.1.33.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 LongBo
{
	[BepInPlugin("dev.longbo.polearms", "Long Bō", "1.1.33")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class LongBoPlugin : BaseUnityPlugin
	{
		private class Req
		{
			public string Item;

			public int Amount;

			public int PerLevel;

			public Req(string item, int amount, int perLevel)
			{
				Item = item;
				Amount = amount;
				PerLevel = perLevel;
			}
		}

		private class BoDef
		{
			public string Id;

			public string Name;

			public string Description;

			public string Group;

			public int MinLevel;

			public float Blunt;

			public float BluntPer;

			public float Pierce;

			public float PiercePer;

			public float Stamina;

			public float Durability;

			public float DurabilityPer;

			public float Block;

			public float Knockback;

			public float Weight;

			public bool SkipIfShogunBo;

			public Color Tint;

			public bool UseTint;

			public string Extra;

			public float ExtraAmt;

			public float ExtraPer;

			public Req[] Reqs;
		}

		private class Made
		{
			public GameObject Prefab;

			public object Recipe;

			public BoDef Def;
		}

		public const string Guid = "dev.longbo.polearms";

		private static ManualLogSource Log;

		private static ConfigFile Cfg;

		private static ConfigEntry<float> DamageMultiplier;

		private static bool Patched;

		private static bool ItemsReady;

		private static bool WorldReady;

		private static bool LoggedItemList;

		private static bool WarnedWait;

		private static bool WarnedStations;

		private static bool InRegisters;

		private static bool ItemsMade;

		private static bool FromShogun;

		private static bool LatePass;

		private static GameObject PrefabRoot;

		private static readonly List<Made> MadeItems = new List<Made>();

		private static readonly Dictionary<string, GameObject> Prefabs = new Dictionary<string, GameObject>();

		private static readonly BoDef[] Defs = new BoDef[8]
		{
			new BoDef
			{
				Id = "BBL_BoWood",
				Name = "Traveler's Bō",
				Description = "A long staff of plain wood. Someone walked a long road with it.",
				Group = "wood",
				MinLevel = 1,
				Blunt = 18f,
				BluntPer = 3f,
				Pierce = 13f,
				PiercePer = 2f,
				Stamina = 9f,
				Durability = 170f,
				DurabilityPer = 40f,
				Block = 12f,
				Knockback = 30f,
				Weight = 2.2f,
				SkipIfShogunBo = true,
				UseTint = false,
				Extra = "",
				ExtraAmt = 0f,
				ExtraPer = 0f,
				Reqs = new Req[3]
				{
					new Req("Wood", 20, 10),
					new Req("Resin", 5, 0),
					new Req("LeatherScraps", 4, 0)
				}
			},
			new BoDef
			{
				Id = "BBL_BoBronze",
				Name = "Bronze Bō",
				Description = "Bronze caps the wood, and a thin ring sits back from the tip. The first metal a clan will trust.",
				Group = "clan",
				MinLevel = 2,
				Blunt = 28f,
				BluntPer = 3f,
				Pierce = 12f,
				PiercePer = 1.5f,
				Stamina = 12f,
				Durability = 220f,
				DurabilityPer = 50f,
				Block = 16f,
				Knockback = 35f,
				Weight = 2.5f,
				UseTint = true,
				Tint = new Color(0.72f, 0.48f, 0.22f, 1f),
				Extra = "",
				ExtraAmt = 0f,
				ExtraPer = 0f,
				Reqs = new Req[3]
				{
					new Req("FineWood", 8, 0),
					new Req("Bronze", 10, 5),
					new Req("LeatherScraps", 2, 0)
				}
			},
			new BoDef
			{
				Id = "BBL_BoIron",
				Name = "Iron Bō",
				Description = "Iron on the ends, and a cord the swamp has stained. The poison in it deepens as the staff is raised.",
				Group = "clan",
				MinLevel = 3,
				Blunt = 40f,
				BluntPer = 4f,
				Pierce = 15f,
				PiercePer = 1.5f,
				Stamina = 12f,
				Durability = 250f,
				DurabilityPer = 50f,
				Block = 28f,
				Knockback = 40f,
				Weight = 2.6f,
				UseTint = true,
				Tint = new Color(0.42f, 0.44f, 0.46f, 1f),
				Extra = "Poison",
				ExtraAmt = 10f,
				ExtraPer = 2f,
				Reqs = new Req[3]
				{
					new Req("RoundLog", 8, 0),
					new Req("Iron", 16, 8),
					new Req("DeerHide", 2, 0)
				}
			},
			new BoDef
			{
				Id = "BBL_BoSilver",
				Name = "Silver Bō",
				Description = "A thread of silver set into the bare wood. Spirits know it, and it bites harder when the staff is raised.",
				Group = "clan",
				MinLevel = 4,
				Blunt = 45f,
				BluntPer = 3f,
				Pierce = 15f,
				PiercePer = 2f,
				Stamina = 12f,
				Durability = 300f,
				DurabilityPer = 50f,
				Block = 36f,
				Knockback = 45f,
				Weight = 2.5f,
				UseTint = true,
				Tint = new Color(0.78f, 0.8f, 0.84f, 1f),
				Extra = "Spirit",
				ExtraAmt = 15f,
				ExtraPer = 2f,
				Reqs = new Req[3]
				{
					new Req("RoundLog", 6, 0),
					new Req("Silver", 12, 6),
					new Req("WolfFang", 2, 0)
				}
			},
			new BoDef
			{
				Id = "BBL_BoBlackmetal",
				Name = "Blackmetal Bō",
				Description = "Dark metal on the ends. The light, such as it is, stays in the cord.",
				Group = "clan",
				MinLevel = 4,
				Blunt = 65f,
				BluntPer = 5f,
				Pierce = 25f,
				PiercePer = 2f,
				Stamina = 13f,
				Durability = 350f,
				DurabilityPer = 50f,
				Block = 48f,
				Knockback = 50f,
				Weight = 2.4f,
				UseTint = true,
				Tint = new Color(0.28f, 0.24f, 0.32f, 1f),
				Extra = "",
				ExtraAmt = 0f,
				ExtraPer = 0f,
				Reqs = new Req[3]
				{
					new Req("FineWood", 8, 0),
					new Req("BlackMetal", 16, 8),
					new Req("LinenThread", 2, 0)
				}
			},
			new BoDef
			{
				Id = "BBL_BoStorm",
				Name = "Storm Bō",
				Description = "Pale wood of Yggdrasil. The wind on a blow sweeps a foe off their feet.",
				Group = "dragon",
				MinLevel = 1,
				Blunt = 75f,
				BluntPer = 4f,
				Pierce = 30f,
				PiercePer = 2f,
				Stamina = 14f,
				Durability = 400f,
				DurabilityPer = 50f,
				Block = 58f,
				Knockback = 75f,
				Weight = 2.4f,
				UseTint = true,
				Tint = new Color(0.28f, 0.55f, 0.5f, 1f),
				Extra = "Lightning",
				ExtraAmt = 20f,
				ExtraPer = 2f,
				Reqs = new Req[3]
				{
					new Req("YggdrasilWood", 8, 0),
					new Req("Carapace", 12, 6),
					new Req("Eitr", 4, 0)
				}
			},
			new BoDef
			{
				Id = "BBL_BoInfernal",
				Name = "Infernal Bō",
				Description = "Charred wood and copper caps. The cord still holds the fire.",
				Group = "dragon",
				MinLevel = 1,
				Blunt = 90f,
				BluntPer = 5f,
				Pierce = 35f,
				PiercePer = 2f,
				Stamina = 15f,
				Durability = 500f,
				DurabilityPer = 50f,
				Block = 70f,
				Knockback = 55f,
				Weight = 2.5f,
				UseTint = true,
				Tint = new Color(0.75f, 0.32f, 0.14f, 1f),
				Extra = "Fire",
				ExtraAmt = 20f,
				ExtraPer = 2f,
				Reqs = new Req[3]
				{
					new Req("Blackwood", 8, 0),
					new Req("FlametalNew", 16, 8),
					new Req("CharredBone", 4, 0)
				}
			},
			new BoDef
			{
				Id = "BBL_BoRime",
				Name = "Rime Bō",
				Description = "Frozen wood, ice at the tips, and frost that caught on the cord and stayed.",
				Group = "dragon",
				MinLevel = 1,
				Blunt = 120f,
				BluntPer = 5f,
				Pierce = 45f,
				PiercePer = 2f,
				Stamina = 15f,
				Durability = 500f,
				DurabilityPer = 50f,
				Block = 84f,
				Knockback = 60f,
				Weight = 2.5f,
				UseTint = true,
				Tint = new Color(0.62f, 0.74f, 0.8f, 1f),
				Extra = "Frost",
				ExtraAmt = 20f,
				ExtraPer = 2f,
				Reqs = new Req[3]
				{
					new Req("Frostwood", 10, 0),
					new Req("Gold", 16, 8),
					new Req("FrozenFuel", 2, 0)
				}
			}
		};

		private static object TargetDb;

		private static string Claimed;

		private static object ClaimedStationRef;

		private static Component ClanKnown;

		private static Component DragonKnown;

		private static bool LearnedOnce;

		private static readonly HashSet<string> SeenStations = new HashSet<string>();

		private static object BoundDb;

		private static object BoundScene;

		private static bool Announced;

		private static MethodInfo HashMethodInfo;

		private static bool HashLooked;

		private static bool WarnedStatus;

		private static string WearFor;

		private static readonly Dictionary<string, object> WearCache = new Dictionary<string, object>();

		private const BindingFlags Flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;

		[Conditional("LONGBO_TRACE")]
		private static void Trace(string message)
		{
			Log.LogInfo((object)message);
		}

		private void Awake()
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected O, but got Unknown
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			Cfg = ((BaseUnityPlugin)this).Config;
			DamageMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Damage multiplier", 1f, "Scales blunt, pierce, elemental damage, and every per-level gain. 1 is the atgeir sheet. Use the same value on the server and every client.");
			if (!Patched)
			{
				Patched = true;
				Harmony val = new Harmony("dev.longbo.polearms");
				PatchObjectList(val);
				PatchShutdown(val);
				PatchAwake(val, "ZNetScene", "AfterZNetScene");
				PatchAwake(val, "ZNet", "AfterZNetScene");
				PatchVnei(val);
				PatchCraftingUi(val);
				Type type = AccessTools.TypeByName("ItemDrop");
				MethodInfo methodInfo = ((type == null) ? null : AccessTools.Method(type, "Awake", (Type[])null, (Type[])null));
				if (methodInfo != null)
				{
					val.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(LongBoPlugin), "AfterItemDropAwake", (Type[])null, (Type[])null))
					{
						priority = 0
					}, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
			}
		}

		private static void PatchObjectList(Harmony harmony)
		{
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: 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_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Expected O, but got Unknown
			//IL_00ab: Expected O, but got Unknown
			Type type = AccessTools.TypeByName("ObjectDB");
			if (type == null)
			{
				return;
			}
			string[] array = new string[2] { "CopyOtherDB", "UpdateRegisters" };
			foreach (string name in array)
			{
				MethodInfo methodInfo = FindMethod(type, name);
				if (!(methodInfo == null))
				{
					harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(AccessTools.Method(typeof(LongBoPlugin), "BeforeItemList", (Type[])null, (Type[])null))
					{
						priority = 800
					}, new HarmonyMethod(AccessTools.Method(typeof(LongBoPlugin), "AfterItemList", (Type[])null, (Type[])null))
					{
						priority = 0
					}, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
			}
		}

		private static void PatchShutdown(Harmony harmony)
		{
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Expected O, but got Unknown
			Type type = AccessTools.TypeByName("ZNet");
			MethodInfo methodInfo = FindMethod(type, "Shutdown");
			if (methodInfo == null)
			{
				methodInfo = FindMethod(type, "OnDestroy");
			}
			if (methodInfo == null)
			{
				Log.LogError((object)"Could not patch ZNet.Shutdown");
				return;
			}
			harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(AccessTools.Method(typeof(LongBoPlugin), "BeforeShutdown", (Type[])null, (Type[])null))
			{
				priority = 800
			}, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}

		public static void BeforeItemList(object __instance)
		{
			try
			{
				DropDead(__instance);
			}
			catch (Exception ex)
			{
				Log.LogError((object)("Long Bō could not clean the item list: " + ex.Message));
			}
		}

		public static void BeforeShutdown()
		{
			try
			{
				UnhookWorld();
			}
			catch (Exception ex)
			{
				Log.LogError((object)("Long Bō could not leave the world cleanly: " + ex.Message));
			}
		}

		private static void UnhookWorld()
		{
			object obj = Db();
			DropDead(obj);
			IList list = ((obj == null) ? null : (Get(obj, "m_items") as IList));
			IList list2 = ((obj == null) ? null : (Get(obj, "m_recipes") as IList));
			foreach (Made madeItem in MadeItems)
			{
				if (madeItem.Def != null)
				{
					RemoveNamed(list, madeItem.Def.Id);
					RemoveNamed(list2, "Recipe_" + madeItem.Def.Id);
				}
			}
			object obj2 = ZNet();
			IList list3 = ((obj2 == null) ? null : (Get(obj2, "m_prefabs") as IList));
			IDictionary dictionary = ((obj2 == null) ? null : (Get(obj2, "m_namedPrefabs") as IDictionary));
			foreach (Made madeItem2 in MadeItems)
			{
				if (madeItem2.Prefab == null)
				{
					continue;
				}
				if (list3 != null)
				{
					for (int num = list3.Count - 1; num >= 0; num--)
					{
						if (list3[num] == madeItem2.Prefab)
						{
							list3.RemoveAt(num);
						}
					}
				}
				if (dictionary != null)
				{
					object obj3 = RealHash(((Object)madeItem2.Prefab).name);
					if (obj3 != null && dictionary.Contains(obj3) && dictionary[obj3] == madeItem2.Prefab)
					{
						dictionary.Remove(obj3);
					}
				}
			}
			ItemsReady = false;
			WorldReady = false;
			BoundDb = null;
			BoundScene = null;
			Announced = false;
		}

		private static void DropDead(object db)
		{
			if (db != null)
			{
				DropDeadList(Get(db, "m_items") as IList);
				DropDeadList(Get(db, "m_recipes") as IList);
			}
		}

		private static void DropDeadList(IList list)
		{
			if (list == null)
			{
				return;
			}
			for (int num = list.Count - 1; num >= 0; num--)
			{
				if (!Alive(list[num]))
				{
					list.RemoveAt(num);
				}
			}
		}

		private static bool Alive(object obj)
		{
			Object val = (Object)((obj is Object) ? obj : null);
			if (val == null)
			{
				return false;
			}
			try
			{
				return val.name != null;
			}
			catch
			{
				return false;
			}
		}

		private static MethodInfo FindMethod(Type type, string name)
		{
			if (type == null)
			{
				return null;
			}
			MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (MethodInfo methodInfo in methods)
			{
				if (methodInfo.Name == name)
				{
					return methodInfo;
				}
			}
			return null;
		}

		public static void AfterItemList(object __instance)
		{
			if (InRegisters)
			{
				return;
			}
			try
			{
				if (!Playing())
				{
					ShowOnMenu(__instance ?? Db());
				}
				else
				{
					Publish();
				}
			}
			catch (Exception ex)
			{
				Log.LogError((object)("Long Bō item list pass failed: " + ex));
			}
		}

		private static object ItemDb()
		{
			return TargetDb ?? Db();
		}

		private static void ShowOnMenu(object db)
		{
			if (db == null || !VanillaReady())
			{
				return;
			}
			TargetDb = db;
			try
			{
				if (MadeItems.Count == 0 || !AttachExisting(db))
				{
					EnsureItems(finalChance: true);
				}
				ApplyAllHitStatus();
				RefreshItemHashes();
			}
			finally
			{
				TargetDb = null;
			}
		}

		private static bool AttachExisting(object db)
		{
			if (db == null || MadeItems.Count == 0)
			{
				return false;
			}
			IList list = Get(db, "m_items") as IList;
			IList list2 = Get(db, "m_recipes") as IList;
			if (list == null)
			{
				return false;
			}
			foreach (Made madeItem in MadeItems)
			{
				if (madeItem.Def == null || !Alive(madeItem.Prefab))
				{
					return false;
				}
				if (FindInList(list, madeItem.Def.Id) == null)
				{
					list.Add(madeItem.Prefab);
				}
				if (list2 != null && Alive(madeItem.Recipe) && !ListHas(list2, "Recipe_" + madeItem.Def.Id))
				{
					list2.Add(madeItem.Recipe);
				}
			}
			return true;
		}

		private static void PatchCraftingUi(Harmony harmony)
		{
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Expected O, but got Unknown
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Expected O, but got Unknown
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Expected O, but got Unknown
			Type type = AccessTools.TypeByName("InventoryGui");
			if (type != null)
			{
				string[] array = new string[2] { "UpdateRecipeList", "UpdateCraftingPanel" };
				foreach (string text in array)
				{
					MethodInfo methodInfo = AccessTools.Method(type, text, (Type[])null, (Type[])null);
					if (!(methodInfo == null))
					{
						harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(AccessTools.Method(typeof(LongBoPlugin), "BeforeRecipeList", (Type[])null, (Type[])null))
						{
							priority = 800
						}, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
						break;
					}
				}
			}
			Type type2 = AccessTools.TypeByName("Player");
			MethodInfo methodInfo2 = ((type2 == null) ? null : AccessTools.Method(type2, "SetCraftingStation", (Type[])null, (Type[])null));
			if (methodInfo2 != null)
			{
				harmony.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(LongBoPlugin), "AfterSetStation", (Type[])null, (Type[])null))
				{
					priority = 0
				}, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			else
			{
				Log.LogWarning((object)"Player.SetCraftingStation was not found. The Shogun forges may not list the staffs.");
			}
			Type type3 = AccessTools.TypeByName("CraftingStation");
			MethodInfo methodInfo3 = ((type3 == null) ? null : type3.GetMethod("Start", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic));
			if (methodInfo3 != null)
			{
				harmony.Patch((MethodBase)methodInfo3, (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(LongBoPlugin), "AfterCraftingStationAwake", (Type[])null, (Type[])null))
				{
					priority = 0
				}, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
		}

		public static void AfterCraftingStationAwake(Component __instance)
		{
			try
			{
				if (__instance != null && __instance.gameObject != null)
				{
					PropertyInfo property = ((object)__instance.gameObject).GetType().GetProperty("activeInHierarchy");
					if (!(property != null) || !(property.GetValue(__instance.gameObject, null) is bool flag) || flag)
					{
						AdoptStation(__instance);
					}
				}
			}
			catch (Exception ex)
			{
				Log.LogError((object)("Long Bō forge claim failed: " + ex));
			}
		}

		public static void BeforeRecipeList()
		{
			try
			{
				Type type = AccessTools.TypeByName("Player");
				object obj = ((type == null) ? null : AccessTools.Field(type, "m_localPlayer")?.GetValue(null));
				if (obj != null)
				{
					AdoptStation(Get(obj, "m_currentStation"));
				}
			}
			catch (Exception ex)
			{
				Log.LogError((object)("Long Bō station claim failed: " + ex));
			}
		}

		public static void AfterSetStation(object __0)
		{
			try
			{
				AdoptStation(__0);
			}
			catch (Exception ex)
			{
				Log.LogError((object)("Long Bō station claim failed: " + ex));
			}
		}

		private static void AdoptStation(object station)
		{
			if (station == null || MadeItems.Count == 0)
			{
				return;
			}
			Component val = (Component)((station is Component) ? station : null);
			if (val == null || val.gameObject == null || ClaimedStationRef == val)
			{
				return;
			}
			string text = StationPrefabName(val.gameObject);
			if (text == null)
			{
				text = MatchLearned(station);
			}
			if (text == null)
			{
				NoteStation(val, claimed: false);
				return;
			}
			ClaimedStationRef = val;
			bool flag = text == "Forgeshogun_black";
			string text2 = text + ":" + MadeItems.Count;
			if (Claimed != text2)
			{
				Claimed = text2;
			}
			NoteStation(val, claimed: true);
			foreach (Made madeItem in MadeItems)
			{
				if (madeItem.Def.Group == "dragon" == flag)
				{
					Set(madeItem.Recipe, "m_craftingStation", station);
					Set(madeItem.Recipe, "m_repairStation", station);
				}
			}
			Teach(station);
		}

		private static string MatchLearned(object station)
		{
			LearnFromShogun();
			string text = Convert.ToString(Get(station, "m_name"));
			if (string.IsNullOrEmpty(text))
			{
				return null;
			}
			if (ClanKnown != null && text == Convert.ToString(Get(ClanKnown, "m_name")))
			{
				return "Forgeshogun_stone";
			}
			if (DragonKnown != null && text == Convert.ToString(Get(DragonKnown, "m_name")))
			{
				return "Forgeshogun_black";
			}
			return null;
		}

		private static void LearnFromShogun()
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			if ((LearnedOnce && ClanKnown != null) || !(Get(Db(), "m_recipes") is IList list))
			{
				return;
			}
			foreach (object item in list)
			{
				string text = ((!(item is Object)) ? "" : ((Object)item).name);
				if (text != null && text.StartsWith("Recipe_BBL_"))
				{
					continue;
				}
				object obj = Get(item, "m_craftingStation");
				Component val = (Component)((obj is Component) ? obj : null);
				if (val != null && val.gameObject != null)
				{
					object obj2 = Get(item, "m_item");
					Component val2 = (Component)((obj2 is Component) ? obj2 : null);
					string text2 = ((val2 != null && val2.gameObject != null) ? ((Object)val2.gameObject).name : "");
					string text3 = StationPrefabName(val.gameObject);
					if (text3 == "Forgeshogun_black")
					{
						DragonKnown = val;
					}
					else if (text3 == "Forgeshogun_stone")
					{
						ClanKnown = val;
					}
					else if (text2.StartsWith("SER_") && ClanKnown == null)
					{
						ClanKnown = val;
					}
				}
			}
			if (ClanKnown != null || DragonKnown != null)
			{
				LearnedOnce = true;
				if (ClanKnown != null)
				{
				}
				if (DragonKnown == null)
				{
				}
			}
		}

		private static void Teach(object station)
		{
			Type type = AccessTools.TypeByName("Player");
			object obj = ((type == null) ? null : AccessTools.Field(type, "m_localPlayer")?.GetValue(null));
			if (obj == null)
			{
				return;
			}
			Remember(Get(obj, "m_knownStations"), Convert.ToString(Get(station, "m_name")));
			foreach (Made madeItem in MadeItems)
			{
				if (!(Get(madeItem.Recipe, "m_resources") is Array array))
				{
					continue;
				}
				foreach (object item in array)
				{
					object obj2 = Get(item, "m_resItem");
					Component val = (Component)((obj2 is Component) ? obj2 : null);
					if (val != null)
					{
						object target = Get(Get(val, "m_itemData"), "m_shared");
						Remember(Get(obj, "m_knownMaterial"), Convert.ToString(Get(target, "m_name")));
					}
				}
			}
		}

		private static void Remember(object collection, string value)
		{
			if (collection == null || string.IsNullOrEmpty(value))
			{
				return;
			}
			Type type = collection.GetType();
			MethodInfo method = type.GetMethod("Contains");
			bool flag = default(bool);
			int num;
			if (method != null)
			{
				object obj = method.Invoke(collection, new object[1] { value });
				if (obj is bool)
				{
					flag = (bool)obj;
					num = 1;
				}
				else
				{
					num = 0;
				}
			}
			else
			{
				num = 0;
			}
			if (((uint)num & (flag ? 1u : 0u)) == 0)
			{
				MethodInfo method2 = type.GetMethod("Add");
				if (method2 != null)
				{
					method2.Invoke(collection, new object[1] { value });
				}
			}
		}

		private static void NoteStation(Component station, bool claimed)
		{
			string item = (claimed ? "claimed " : "ignored ") + StationChain(station.gameObject) + " name=" + Get(station, "m_name");
			if (SeenStations.Add(item))
			{
			}
		}

		private static string StationChain(GameObject go)
		{
			List<string> list = new List<string>();
			Transform val = go.transform;
			for (int i = 0; i < 6; i++)
			{
				if (val == null)
				{
					break;
				}
				list.Add(((Object)val).name);
				PropertyInfo property = ((object)val).GetType().GetProperty("parent");
				val = (Transform)((property == null) ? null : /*isinst with value type is only supported in some contexts*/);
			}
			return string.Join(" / ", list.ToArray());
		}

		private static string StationPrefabName(GameObject go)
		{
			Transform val = go.transform;
			while (val != null)
			{
				string text = ((Object)val).name;
				int num = text.IndexOf('(');
				if (num >= 0)
				{
					text = text.Substring(0, num);
				}
				if (text == "Forgeshogun_stone" || text == "Forgeshogun_black")
				{
					return text;
				}
				PropertyInfo property = ((object)val).GetType().GetProperty("parent");
				val = (Transform)((property == null) ? null : /*isinst with value type is only supported in some contexts*/);
			}
			return null;
		}

		private static void PatchAwake(Harmony harmony, string typeName, string postfix)
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Expected O, but got Unknown
			Type type = AccessTools.TypeByName(typeName);
			MethodInfo methodInfo = ((type == null) ? null : AccessTools.Method(type, "Awake", (Type[])null, (Type[])null));
			if (methodInfo == null)
			{
				Log.LogError((object)("Could not patch " + typeName + ".Awake"));
				return;
			}
			MethodInfo methodInfo2 = AccessTools.Method(typeof(LongBoPlugin), postfix, (Type[])null, (Type[])null);
			HarmonyMethod val = new HarmonyMethod(methodInfo2)
			{
				priority = 0
			};
			harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}

		private static void PatchVnei(Harmony harmony)
		{
			//IL_0053: 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_006c: Expected O, but got Unknown
			Type type = QuietType("Indexing", "VNEI.Logic");
			MethodInfo methodInfo = ((type == null) ? null : AccessTools.Method(type, "IndexAll", (Type[])null, (Type[])null));
			if (!(methodInfo == null))
			{
				MethodInfo methodInfo2 = AccessTools.Method(typeof(LongBoPlugin), "BeforeVneiIndex", (Type[])null, (Type[])null);
				harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(methodInfo2)
				{
					priority = 800
				}, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
		}

		public static void BeforeVneiIndex()
		{
			try
			{
				Publish();
			}
			catch (Exception ex)
			{
				Log.LogError((object)("Long Bō VNEI pass failed: " + ex));
			}
		}

		private static void Publish()
		{
			if (!Playing())
			{
				return;
			}
			object obj = Db();
			object obj2 = ZNet();
			if (obj != BoundDb)
			{
				ItemsReady = false;
			}
			if (obj2 != BoundScene)
			{
				WorldReady = false;
			}
			if (ItemsReady && WorldReady)
			{
				return;
			}
			if (!ItemsReady)
			{
				if (!VanillaReady() && !LatePass)
				{
					return;
				}
				EnsureItems(finalChance: true);
				if (!VanillaReady())
				{
					return;
				}
				FillRecipes();
				RefreshItemHashes();
				ItemsReady = Listed();
				if (ItemsReady)
				{
					BoundDb = obj;
				}
			}
			if (!WorldReady && StationsReady())
			{
				BindStations();
				RegisterWorldPrefabs();
				WorldReady = true;
				BoundScene = obj2;
			}
			ApplyAllHitStatus();
			if (ItemsReady && WorldReady && !Announced)
			{
				Announced = true;
				Log.LogInfo((object)("Registered " + MadeItems.Count + " staffs."));
			}
		}

		public static void AfterZNetScene()
		{
			if (!Playing())
			{
				return;
			}
			LatePass = true;
			try
			{
				Publish();
			}
			catch (Exception ex)
			{
				Log.LogError((object)("Long Bō world pass failed: " + ex));
			}
		}

		private static bool Playing()
		{
			Type type = AccessTools.TypeByName("ZNet");
			PropertyInfo propertyInfo = ((type == null) ? null : AccessTools.Property(type, "instance"));
			object obj = ((propertyInfo == null) ? null : propertyInfo.GetValue(null, null));
			if (obj == null || type == null)
			{
				return false;
			}
			if (Get(obj, "m_world") != null)
			{
				return true;
			}
			MethodInfo method = type.GetMethod("GetWorldName", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (method != null && method.GetParameters().Length == 0)
			{
				string value = method.Invoke(obj, null) as string;
				if (!string.IsNullOrEmpty(value))
				{
					return true;
				}
			}
			return false;
		}

		private static void EnsureItems(bool finalChance)
		{
			GameObject val = FindBo();
			bool flag = val != null;
			if (ItemsMade)
			{
				if (flag && !FromShogun)
				{
					ForgetItems();
				}
				else
				{
					if (Listed() || AttachExisting(ItemDb()))
					{
						return;
					}
					ForgetItems();
				}
			}
			if (!flag && !LatePass)
			{
				if (!finalChance)
				{
				}
				return;
			}
			if (!flag)
			{
				string[] array = new string[4] { "StaffFireball", "StaffIce", "StaffSkeleton", "StaffShield" };
				foreach (string name in array)
				{
					val = FindPrefab(name);
					if (val != null)
					{
						NoteMissingBo();
						break;
					}
				}
			}
			if (val == null)
			{
				Log.LogError((object)"No staff prefab to clone. Long Bō added nothing.");
				NoteMissingBo();
				return;
			}
			BoDef[] defs = Defs;
			foreach (BoDef boDef in defs)
			{
				if (!(boDef.SkipIfShogunBo && flag))
				{
					try
					{
						MakeOne(val, boDef, flag);
					}
					catch (Exception ex)
					{
						Log.LogError((object)("Failed to add " + boDef.Name + ": " + ex));
					}
				}
			}
			FromShogun = flag;
			ItemsMade = MadeItems.Count > 0;
			if (ItemsMade)
			{
				RefreshItemHashes();
			}
		}

		private static void FillRecipes()
		{
			if (MadeItems.Count == 0)
			{
				return;
			}
			int num = 0;
			int num2 = 0;
			foreach (Made madeItem in MadeItems)
			{
				if (madeItem.Def != null && madeItem.Recipe != null && RecipeMissing(madeItem))
				{
					Array value = BuildReqs(madeItem.Def);
					Set(madeItem.Recipe, "m_resources", value);
					if (RecipeMissing(madeItem))
					{
						num2++;
					}
					else
					{
						num++;
					}
				}
			}
			if (num > 0)
			{
			}
			if (num2 > 0)
			{
				NoteItemList();
			}
		}

		private static bool RecipeMissing(Made made)
		{
			Req[] reqs = made.Def.Reqs;
			foreach (Req req in reqs)
			{
				if (FindPrefab(ResolveItem(req.Item)) == null)
				{
					return true;
				}
			}
			if (!(Get(made.Recipe, "m_resources") is Array { Length: not 0 } array))
			{
				return made.Def.Reqs.Length != 0;
			}
			foreach (object item in array)
			{
				if (Get(item, "m_resItem") == null)
				{
					return true;
				}
			}
			return false;
		}

		private static void NoteItemList()
		{
			if (LoggedItemList)
			{
				return;
			}
			LoggedItemList = true;
			IList list = Get(Db(), "m_items") as IList;
			int num = list?.Count ?? 0;
			Log.LogWarning((object)("Materials are still missing. The item list has " + num + " entries."));
			if (list == null)
			{
				return;
			}
			int num2 = 0;
			foreach (object item in list)
			{
				GameObject val = (GameObject)((item is GameObject) ? item : null);
				if (val != null && ((Object)val).name != null)
				{
					string name = ((Object)val).name;
					if ((name.IndexOf("Wood", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("Bronze", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("Iron", StringComparison.OrdinalIgnoreCase) >= 0) && ++num2 >= 12)
					{
						break;
					}
				}
			}
		}

		private static GameObject FindBo()
		{
			string[] array = new string[3] { "SER_Bo", "SER_BO", "Ser_Bo" };
			foreach (string name in array)
			{
				GameObject val = FindPrefab(name);
				if (val != null)
				{
					return val;
				}
			}
			foreach (GameObject item in AllPrefabs())
			{
				if (item == null || string.IsNullOrEmpty(((Object)item).name))
				{
					continue;
				}
				if (((Object)item).name.Equals("SER_Bo", StringComparison.OrdinalIgnoreCase))
				{
					return item;
				}
				if (((Object)item).name.StartsWith("SER", StringComparison.OrdinalIgnoreCase) && ((Object)item).name.IndexOf("bokken", StringComparison.OrdinalIgnoreCase) < 0 && ((Object)item).name.IndexOf("kanobo", StringComparison.OrdinalIgnoreCase) < 0)
				{
					if (((Object)item).name.EndsWith("_Bo", StringComparison.OrdinalIgnoreCase))
					{
						return item;
					}
					Type type = AccessTools.TypeByName("ItemDrop");
					Component val2 = ((type == null) ? null : item.GetComponent(type));
					object target = ((val2 == null) ? null : Get(Get(val2, "m_itemData"), "m_shared"));
					string text = (Get(target, "m_description") as string) ?? "";
					string text2 = (Get(target, "m_name") as string) ?? "";
					if (text.IndexOf("long wooden staff", StringComparison.OrdinalIgnoreCase) >= 0)
					{
						return item;
					}
					if (text2.IndexOf("Bō", StringComparison.Ordinal) >= 0)
					{
						return item;
					}
				}
			}
			return null;
		}

		private static List<GameObject> AllPrefabs()
		{
			List<GameObject> seen = new List<GameObject>();
			object obj = Db();
			if (obj != null)
			{
				Take(Get(obj, "m_items") as IList);
			}
			object obj2 = ZNet();
			if (obj2 != null)
			{
				Take(Get(obj2, "m_prefabs") as IList);
			}
			return seen;
			void Take(IList list)
			{
				if (list == null)
				{
					return;
				}
				foreach (object item in list)
				{
					GameObject val = (GameObject)((item is GameObject) ? item : null);
					if (val != null)
					{
						seen.Add(val);
					}
				}
			}
		}

		private static void NoteMissingBo()
		{
			object obj = ZNet();
			IList list = ((obj == null) ? null : (Get(obj, "m_prefabs") as IList));
			if (list == null)
			{
				return;
			}
			int num = 0;
			foreach (object item in list)
			{
				GameObject val = (GameObject)((item is GameObject) ? item : null);
				if (val == null || ((Object)val).name == null || ((Object)val).name.IndexOf("bo", StringComparison.OrdinalIgnoreCase) < 0 || ((Object)val).name.IndexOf("SER", StringComparison.OrdinalIgnoreCase) < 0 || ++num < 12)
				{
					continue;
				}
				break;
			}
			if (num != 0)
			{
			}
		}

		private static bool Listed()
		{
			if (MadeItems.Count == 0)
			{
				return false;
			}
			if (!(Get(ItemDb(), "m_items") is IList list))
			{
				return false;
			}
			foreach (Made madeItem in MadeItems)
			{
				if (madeItem.Def == null)
				{
					return false;
				}
				if (FindInList(list, madeItem.Def.Id) == null)
				{
					return false;
				}
			}
			return true;
		}

		private static void ForgetItems()
		{
			object obj = Db();
			IList list = ((obj == null) ? null : (Get(obj, "m_items") as IList));
			IList list2 = ((obj == null) ? null : (Get(obj, "m_recipes") as IList));
			object obj2 = ZNet();
			IList list3 = ((obj2 == null) ? null : (Get(obj2, "m_prefabs") as IList));
			IDictionary dictionary = ((obj2 == null) ? null : (Get(obj2, "m_namedPrefabs") as IDictionary));
			foreach (Made madeItem in MadeItems)
			{
				if (madeItem.Def != null)
				{
					RemoveNamed(list, madeItem.Def.Id);
					RemoveNamed(list2, "Recipe_" + madeItem.Def.Id);
				}
				if (list3 != null && madeItem.Prefab != null)
				{
					for (int num = list3.Count - 1; num >= 0; num--)
					{
						if (list3[num] == madeItem.Prefab)
						{
							list3.RemoveAt(num);
						}
					}
				}
				if (dictionary != null && madeItem.Prefab != null)
				{
					object obj3 = RealHash(((Object)madeItem.Prefab).name);
					if (obj3 != null && dictionary.Contains(obj3) && dictionary[obj3] == madeItem.Prefab)
					{
						dictionary.Remove(obj3);
					}
				}
				if (madeItem.Prefab != null)
				{
					Object.Destroy((Object)(object)madeItem.Prefab);
				}
				if (madeItem.Recipe != null)
				{
					object recipe = madeItem.Recipe;
					Object.Destroy((Object)((recipe is Object) ? recipe : null));
				}
			}
			MadeItems.Clear();
			Prefabs.Clear();
			ItemsMade = false;
			FromShogun = false;
			ItemsReady = false;
			WorldReady = false;
			BoundDb = null;
			BoundScene = null;
			Announced = false;
			ClaimedStationRef = null;
			ClanKnown = null;
			DragonKnown = null;
			LearnedOnce = false;
		}

		public static void AfterItemDropAwake(Component __instance)
		{
			try
			{
				if (__instance != null && __instance.gameObject != null)
				{
					string text = ((Object)__instance.gameObject).name;
					int num = text.IndexOf('(');
					if (num >= 0)
					{
						text = text.Substring(0, num);
					}
					text = text.Trim();
					if (Prefabs.TryGetValue(text, out var value) && value != null)
					{
						object target = Get(__instance, "m_itemData");
						Set(target, "m_dropPrefab", value);
					}
				}
			}
			catch (Exception)
			{
			}
		}

		private static void MakeOne(GameObject source, BoDef def, bool realBo)
		{
			if (Cfg.Bind<bool>(def.Id, "Enabled", true, "Craft and spawn " + def.Name + ".").Value)
			{
				float num = MathfClamp(DamageMultiplier.Value, 0.05f, 10f);
				float blunt = Cfg.Bind<float>(def.Id, "Blunt", def.Blunt, "Quality 1 blunt.").Value * num;
				float blunt2 = Cfg.Bind<float>(def.Id, "Blunt per quality", def.BluntPer, "Blunt added for each quality above 1.").Value * num;
				float pierce = Cfg.Bind<float>(def.Id, "Pierce", def.Pierce, "Quality 1 pierce, added on top of blunt.").Value * num;
				float pierce2 = Cfg.Bind<float>(def.Id, "Pierce per quality", def.PiercePer, "Pierce added for each quality above 1.").Value * num;
				string text = ExtraField(def.Extra);
				float extra = 0f;
				float extra2 = 0f;
				if (text != null)
				{
					extra = Cfg.Bind<float>(def.Id, def.Extra, def.ExtraAmt, "Quality 1 " + def.Extra.ToLower() + ", added on top of blunt.").Value * num;
					extra2 = Cfg.Bind<float>(def.Id, def.Extra + " per quality", def.ExtraPer, def.Extra + " added for each quality above 1.").Value * num;
				}
				GameObject val = CloneInactive(source, def.Id);
				Type type = AccessTools.TypeByName("ItemDrop");
				Component component = val.GetComponent(type);
				object target = Get(component, "m_itemData");
				object obj = Get(target, "m_shared");
				Set(obj, "m_name", def.Name);
				Set(obj, "m_description", def.Description);
				Set(obj, "m_dlc", "");
				Set(obj, "m_maxQuality", 4);
				Set(obj, "m_weight", def.Weight);
				Set(obj, "m_maxDurability", def.Durability);
				Set(obj, "m_durabilityPerLevel", def.DurabilityPer);
				Set(obj, "m_blockPower", def.Block);
				Set(obj, "m_blockPowerPerLevel", 0f);
				Set(obj, "m_timedBlockBonus", 2f);
				Set(obj, "m_attackForce", def.Knockback);
				Set(target, "m_durability", def.Durability);
				Set(target, "m_quality", 1);
				Set(target, "m_dropPrefab", val);
				WriteDamages(obj, "m_damages", blunt, pierce, text, extra);
				WriteDamages(obj, "m_damagesPerLevel", blunt2, pierce2, text, extra2);
				FieldInfo field = obj.GetType().GetField("m_icons", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				Component component2 = source.GetComponent(type);
				object target2 = ((component2 == null) ? null : Get(Get(component2, "m_itemData"), "m_shared"));
				object obj2 = Get(target2, "m_icons");
				if (field != null && obj2 != null)
				{
					field.SetValue(obj, obj2);
				}
				else if (field != null && field.GetValue(obj) == null && field.FieldType.IsArray)
				{
					field.SetValue(obj, Array.CreateInstance(field.FieldType.GetElementType(), 0));
				}
				SetStamina(Get(obj, "m_attack"), def.Stamina);
				SetStamina(Get(obj, "m_secondaryAttack"), def.Stamina * 2f);
				ApplyHitStatus(obj, def.Extra);
				if (!realBo)
				{
					StripMagic(val);
				}
				ShowMesh(val);
				StripMagic(val);
				ParkPrefab(val);
				Dress(val, def);
				Prefabs[def.Id] = val;
				Component val2 = FindChild(val, "attach");
				Type type2 = AccessTools.TypeByName("Recipe");
				ScriptableObject val3 = ScriptableObject.CreateInstance(type2);
				((Object)val3).name = "Recipe_" + def.Id;
				Set(val3, "m_item", component);
				Set(val3, "m_amount", 1);
				Set(val3, "m_enabled", true);
				Set(val3, "m_minStationLevel", 1);
				Set(val3, "m_resources", BuildReqs(def));
				object target3 = ItemDb();
				IList list = (IList)Get(target3, "m_items");
				RemoveNamed(list, def.Id);
				list.Add(val);
				IList list2 = (IList)Get(target3, "m_recipes");
				RemoveNamed(list2, "Recipe_" + def.Id);
				list2.Add(val3);
				MadeItems.Add(new Made
				{
					Prefab = val,
					Recipe = val3,
					Def = def
				});
				string text2 = ((text == null) ? "" : (" " + def.Extra.ToLower() + " " + extra + " +" + extra2));
			}
		}

		private static void RefreshItemHashes()
		{
			object obj = ItemDb();
			if (obj == null)
			{
				return;
			}
			MethodInfo methodInfo = FindMethod(obj.GetType(), "UpdateRegisters");
			if (methodInfo == null)
			{
				methodInfo = FindMethod(obj.GetType(), "UpdateItemHashes");
			}
			if (methodInfo != null && methodInfo.GetParameters().Length == 0 && !InRegisters)
			{
				InRegisters = true;
				try
				{
					methodInfo.Invoke(obj, null);
				}
				finally
				{
					InRegisters = false;
				}
			}
			if (!(Get(obj, "m_itemByHash") is IDictionary dictionary))
			{
				return;
			}
			foreach (KeyValuePair<string, GameObject> prefab in Prefabs)
			{
				object obj2 = RealHash(prefab.Key);
				if (obj2 != null && prefab.Value != null)
				{
					dictionary[obj2] = prefab.Value;
				}
			}
		}

		private static Component FindChild(GameObject go, string name)
		{
			if (go == null)
			{
				return null;
			}
			Transform[] componentsInChildren = go.GetComponentsInChildren<Transform>(true);
			if (componentsInChildren == null)
			{
				return null;
			}
			Transform[] array = componentsInChildren;
			foreach (Transform val in array)
			{
				if (val != null && ((Component)val).gameObject != null && ((Object)((Component)val).gameObject).name == name)
				{
					return (Component)(object)val;
				}
			}
			return null;
		}

		private static Array BuildReqs(BoDef def)
		{
			Type type = AccessTools.TypeByName("Piece");
			Type nestedType = type.GetNestedType("Requirement");
			List<object> list = new List<object>();
			Req[] reqs = def.Reqs;
			foreach (Req req in reqs)
			{
				string name = ResolveItem(req.Item);
				GameObject val = FindPrefab(name);
				if (val == null)
				{
					if (VanillaReady())
					{
						Log.LogWarning((object)(def.Name + " is missing material " + req.Item + ". That part of the recipe was skipped."));
					}
					else if (!WarnedWait)
					{
						WarnedWait = true;
					}
				}
				else
				{
					Component component = val.GetComponent(AccessTools.TypeByName("ItemDrop"));
					object obj = Activator.CreateInstance(nestedType);
					Set(obj, "m_resItem", component);
					Set(obj, "m_amount", req.Amount);
					Set(obj, "m_amountPerLevel", req.PerLevel);
					Set(obj, "m_recover", true);
					list.Add(obj);
				}
			}
			Array array = Array.CreateInstance(nestedType, list.Count);
			for (int j = 0; j < list.Count; j++)
			{
				array.SetValue(list[j], j);
			}
			return array;
		}

		private static bool VanillaReady()
		{
			return FindPrefab("Wood") != null || FindPrefab("FineWood") != null;
		}

		private static string ResolveItem(string name)
		{
			if (FindPrefab(name) != null)
			{
				return name;
			}
			if (name == "FlametalNew" && FindPrefab("Flametal") != null)
			{
				return "Flametal";
			}
			return name;
		}

		private static void BindStations()
		{
			if (MadeItems.Count == 0)
			{
				return;
			}
			if (!StationsReady())
			{
				if (!WarnedStations)
				{
					WarnedStations = true;
				}
				return;
			}
			foreach (Made madeItem in MadeItems)
			{
				bool preferred;
				GameObject val = PickStation(madeItem.Def, out preferred);
				int num = ((!preferred) ? 1 : madeItem.Def.MinLevel);
				num = Cfg.Bind<int>(madeItem.Def.Id, "Station level", num, preferred ? "Minimum station level. Defaults to the Shogun table's level for this tier." : "Shogun table was missing, so this crafts at station level 1 on the fallback bench.").Value;
				if (val == null)
				{
					Log.LogWarning((object)(madeItem.Def.Name + " has no crafting station. It will craft from the inventory."));
					Set(madeItem.Recipe, "m_minStationLevel", 1);
					continue;
				}
				Component val2 = StationOn(val, AccessTools.TypeByName("CraftingStation"));
				Set(madeItem.Recipe, "m_craftingStation", val2);
				Set(madeItem.Recipe, "m_repairStation", val2);
				Set(madeItem.Recipe, "m_minStationLevel", Math.Max(1, num));
				string text = ((val2 == null) ? ((Object)val).name : Convert.ToString(Get(val2, "m_name")));
			}
			LearnFromShogun();
			if (ClanKnown != null)
			{
				PointGroup(ClanKnown, dragon: false);
			}
			if (DragonKnown != null)
			{
				PointGroup(DragonKnown, dragon: true);
			}
		}

		private static bool StationsReady()
		{
			return FindPrefab("forge") != null || FindPrefab("piece_workbench") != null || FindPrefab("Forgeshogun_stone") != null || FindPrefab("Forgeshogun_black") != null;
		}

		private static void PointGroup(object station, bool dragon)
		{
			foreach (Made madeItem in MadeItems)
			{
				if (madeItem.Def.Group == "dragon" == dragon)
				{
					Set(madeItem.Recipe, "m_craftingStation", station);
					Set(madeItem.Recipe, "m_repairStation", station);
				}
			}
		}

		private static GameObject PickStation(BoDef def, out bool preferred)
		{
			string value = Cfg.Bind<string>(def.Id, "Station prefabs", "", "Optional comma-separated prefab names. First one that exists wins. Empty uses the default list.").Value;
			string[] array = (string.IsNullOrEmpty(value) ? DefaultStations(def.Group) : value.Split(new char[1] { ',' }));
			for (int i = 0; i < array.Length; i++)
			{
				string text = array[i].Trim();
				if (text.Length != 0)
				{
					GameObject val = FindPrefab(text);
					Type craftingType = AccessTools.TypeByName("CraftingStation");
					if (val != null && StationOn(val, craftingType) != null)
					{
						preferred = (string.IsNullOrEmpty(value) ? (text == DefaultStations(def.Group)[0]) : (i == 0));
						return val;
					}
				}
			}
			preferred = false;
			return null;
		}

		private static string[] DefaultStations(string group)
		{
			if (group == "dragon")
			{
				return new string[3] { "Forgeshogun_black", "blackforge", "forge" };
			}
			if (group == "clan")
			{
				return new string[2] { "Forgeshogun_stone", "forge" };
			}
			return new string[2] { "Forgeshogun_stone", "piece_workbench" };
		}

		private static Component StationOn(GameObject prefab, Type craftingType)
		{
			if (prefab == null || craftingType == null)
			{
				return null;
			}
			Component component = prefab.GetComponent(craftingType);
			if (component != null)
			{
				return component;
			}
			MethodInfo method = typeof(GameObject).GetMethod("GetComponentInChildren", new Type[2]
			{
				typeof(Type),
				typeof(bool)
			});
			if (method != null)
			{
				object? obj = method.Invoke(prefab, new object[2] { craftingType, true });
				return (Component)((obj is Component) ? obj : null);
			}
			method = typeof(GameObject).GetMethod("GetComponentInChildren", new Type[1] { typeof(Type) });
			if (method == null)
			{
				return null;
			}
			object? obj2 = method.Invoke(prefab, new object[1] { craftingType });
			return (Component)((obj2 is Component) ? obj2 : null);
		}

		private static GameObject CloneInactive(GameObject source, string name)
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Expected O, but got Unknown
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			if (PrefabRoot == null)
			{
				PrefabRoot = new GameObject("LongBoPrefabs");
				PrefabRoot.SetActive(false);
				Object.DontDestroyOnLoad((Object)(object)PrefabRoot);
			}
			GameObject val = (GameObject)Object.Instantiate((Object)(object)source, PrefabRoot.transform);
			((Object)val).name = name;
			return val;
		}

		private static void RegisterWorldPrefabs()
		{
			object obj = ZNet();
			if (obj == null)
			{
				return;
			}
			IList list = Get(obj, "m_prefabs") as IList;
			IDictionary dictionary = Get(obj, "m_namedPrefabs") as IDictionary;
			foreach (Made madeItem in MadeItems)
			{
				if (madeItem.Prefab == null)
				{
					continue;
				}
				if (list != null && !ContainsGo(list, madeItem.Prefab))
				{
					list.Add(madeItem.Prefab);
				}
				if (dictionary == null)
				{
					continue;
				}
				object obj2 = RealHash(((Object)madeItem.Prefab).name);
				if (obj2 == null)
				{
					Log.LogError((object)(((Object)madeItem.Prefab).name + " was not added to the spawn list. Valheim's hash method was not found, and a guessed hash could replace a vanilla prefab."));
					continue;
				}
				if (dictionary.Contains(obj2))
				{
					object? obj3 = dictionary[obj2];
					GameObject val = (GameObject)((obj3 is GameObject) ? obj3 : null);
					if (val != null && val != madeItem.Prefab && ((Object)val).name != ((Object)madeItem.Prefab).name)
					{
						Log.LogError((object)("Refusing to replace " + ((Object)val).name + " with " + ((Object)madeItem.Prefab).name + "."));
						continue;
					}
				}
				dictionary[obj2] = madeItem.Prefab;
			}
		}

		private static object RealHash(string text)
		{
			MethodInfo methodInfo = HashMethod();
			if (methodInfo == null || string.IsNullOrEmpty(text))
			{
				return null;
			}
			return methodInfo.Invoke(null, new object[1] { text });
		}

		private static MethodInfo HashMethod()
		{
			if (HashLooked)
			{
				return HashMethodInfo;
			}
			HashLooked = true;
			string[] array = new string[2] { "StringExtensionMethods", "StringExtension" };
			foreach (string name in array)
			{
				Type type = QuietType(name, null);
				if (!(type == null))
				{
					HashMethodInfo = AccessTools.Method(type, "GetStableHashCode", new Type[1] { typeof(string) }, (Type[])null);
					if (HashMethodInfo != null)
					{
						return HashMethodInfo;
					}
				}
			}
			Log.LogError((object)"GetStableHashCode was not found. Staff spawn registration was skipped so a bad hash cannot overwrite Wood or any other vanilla prefab.");
			return null;
		}

		private static Type QuietType(string name, string ns)
		{
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			foreach (Assembly assembly in assemblies)
			{
				Type[] types;
				try
				{
					types = assembly.GetTypes();
				}
				catch (ReflectionTypeLoadException ex)
				{
					types = ex.Types;
				}
				catch
				{
					continue;
				}
				if (types == null)
				{
					continue;
				}
				Type[] array = types;
				foreach (Type type in array)
				{
					if (!(type == null) && !(type.Name != name) && (ns == null || !(type.Namespace != ns)))
					{
						return type;
					}
				}
			}
			return null;
		}

		private static string ExtraField(string extra)
		{
			return extra switch
			{
				"Poison" => "m_poison", 
				"Pierce" => "m_pierce", 
				"Spirit" => "m_spirit", 
				"Lightning" => "m_lightning", 
				"Fire" => "m_fire", 
				"Frost" => "m_frost", 
				_ => null, 
			};
		}

		private static string StatusName(string extra)
		{
			return extra switch
			{
				"Poison" => "Poison", 
				"Fire" => "Burning", 
				"Frost" => "Frost", 
				"Lightning" => "Lightning", 
				_ => null, 
			};
		}

		private static void ApplyAllHitStatus()
		{
			if (MadeItems.Count == 0)
			{
				return;
			}
			Type type = AccessTools.TypeByName("ItemDrop");
			foreach (Made madeItem in MadeItems)
			{
				if (madeItem.Def != null && madeItem.Prefab != null && !(type == null))
				{
					Component component = madeItem.Prefab.GetComponent(type);
					ApplyHitStatus(Get(Get(component, "m_itemData"), "m_shared"), madeItem.Def.Extra);
				}
			}
		}

		private static void ApplyHitStatus(object shared, string extra)
		{
			string text = StatusName(extra);
			if (shared == null || text == null)
			{
				return;
			}
			object obj = FindStatus(text);
			if (obj == null)
			{
				if (!WarnedStatus)
				{
					WarnedStatus = true;
					Log.LogWarning((object)("Could not find the " + text + " status effect yet. The hit will still carry the damage."));
				}
			}
			else
			{
				Set(Get(shared, "m_attack"), "m_attackStatusEffect", obj);
				Set(Get(shared, "m_secondaryAttack"), "m_attackStatusEffect", obj);
			}
		}

		private static object FindStatus(string name)
		{
			object obj = Db();
			if (obj == null)
			{
				return null;
			}
			string[] array = new string[2] { "m_StatusEffects", "m_statusEffects" };
			foreach (string field in array)
			{
				if (!(Get(obj, field) is IList list))
				{
					continue;
				}
				foreach (object item in list)
				{
					Object val = (Object)((item is Object) ? item : null);
					if (val != null && val.name == name)
					{
						return item;
					}
				}
			}
			return null;
		}

		private static void WriteDamages(object shared, string field, float blunt, float pierce, string extraField, float extra)
		{
			object obj = Get(shared, field);
			if (obj == null)
			{
				FieldInfo field2 = shared.GetType().GetField(field, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (field2 == null)
				{
					return;
				}
				obj = Activator.CreateInstance(field2.FieldType);
			}
			object obj2 = obj;
			FieldInfo[] fields = obj2.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (FieldInfo fieldInfo in fields)
			{
				if (!(fieldInfo.FieldType != typeof(float)))
				{
					float num = 0f;
					if (fieldInfo.Name == "m_blunt")
					{
						num = blunt;
					}
					else if (fieldInfo.Name == "m_pierce")
					{
						num = pierce;
					}
					else if (extraField != null && fieldInfo.Name == extraField)
					{
						num = extra;
					}
					fieldInfo.SetValue(obj2, num);
				}
			}
			Set(shared, field, obj2);
		}

		private static void SetStamina(object attack, float stamina)
		{
			if (attack != null)
			{
				FieldInfo field = attack.GetType().GetField("m_attackStamina", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (field != null)
				{
					field.SetValue(attack, stamina);
				}
			}
		}

		private static void Tint(GameObject go, Color color)
		{
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			Renderer[] componentsInChildren = go.GetComponentsInChildren<Renderer>(true);
			if (componentsInChildren == null)
			{
				return;
			}
			Renderer[] array = componentsInChildren;
			foreach (Renderer val in array)
			{
				if (val == null || (!(val is MeshRenderer) && !(val is SkinnedMeshRenderer)))
				{
					continue;
				}
				Material[] materials = val.materials;
				if (materials == null)
				{
					continue;
				}
				Material[] array2 = materials;
				foreach (Material val2 in array2)
				{
					if (val2 != null && val2.HasProperty("_Color"))
					{
						val2.SetColor("_Color", color);
					}
				}
				val.materials = materials;
			}
		}

		private static void ParkPrefab(GameObject go)
		{
			go.SetActive(true);
			Transform transform = go.transform;
			PropertyInfo property = ((object)transform).GetType().GetProperty("localPosition");
			PropertyInfo property2 = ((object)transform).GetType().GetProperty("localRotation");
			if (property != null && property.CanWrite)
			{
				property.SetValue(transform, Activator.CreateInstance(property.PropertyType), null);
			}
			if (property2 != null && property2.CanWrite)
			{
				object obj = Activator.CreateInstance(property2.PropertyType);
				FieldInfo field = property2.PropertyType.GetField("w");
				if (field != null)
				{
					field.SetValue(obj, 1f);
				}
				property2.SetValue(transform, obj, null);
			}
		}

		private static void Dress(GameObject clone, BoDef def)
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: 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_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: 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_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_021a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0226: Unknown result type (might be due to invalid IL or missing references)
			//IL_0243: Unknown result type (might be due to invalid IL or missing references)
			//IL_024f: Unknown result type (might be due to invalid IL or missing references)
			//IL_029a: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0306: Unknown result type (might be due to invalid IL or missing references)
			//IL_0323: Unknown result type (might be due to invalid IL or missing references)
			//IL_032f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0338: Unknown result type (might be due to invalid IL or missing references)
			//IL_036b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0370: Unknown result type (might be due to invalid IL or missing references)
			//IL_0383: Unknown result type (might be due to invalid IL or missing references)
			//IL_0388: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_040e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0413: Unknown result type (might be due to invalid IL or missing references)
			//IL_0423: Unknown result type (might be due to invalid IL or missing references)
			//IL_0428: Unknown result type (might be due to invalid IL or missing references)
			//IL_045b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0460: Unknown result type (might be due to invalid IL or missing references)
			//IL_0473: Unknown result type (might be due to invalid IL or missing references)
			//IL_0478: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0502: Unknown result type (might be due to invalid IL or missing references)
			//IL_050e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0517: Unknown result type (might be due to invalid IL or missing references)
			Component obj = FindChild(clone, "Staff");
			Transform val = (Transform)(object)((obj is Transform) ? obj : null);
			if (val == null)
			{
				Log.LogWarning((object)(def.Name + " has no Staff mesh to dress."));
				return;
			}
			Look(def.Id, out var wood, out var metal, out var wrap, out var glow, out var metalness, out var gloss, out var capLen);
			TintStaff(val, wood, wrap);
			WearFor = def.Id;
			Color glow2 = default(Color);
			((Color)(ref glow2))..ctor(0f, 0f, 0f, 1f);
			if (def.Id == "BBL_BoBronze")
			{
				EndCap(val, 0.2606f, capLen, metal, metalness, gloss, glow2);
				EndCap(val, -0.2606f, capLen, metal, metalness, gloss, glow2);
				Band(val, "ring_tip", 0.2f, 0.012f, 0.0064f, metal, metalness, gloss, glow2);
				Band(val, "ring_butt", -0.2f, 0.012f, 0.0064f, metal, metalness, gloss, glow2);
			}
			else if (def.Id == "BBL_BoIron")
			{
				EndCap(val, 0.2606f, capLen, metal, metalness, gloss, glow2);
				EndCap(val, -0.2606f, capLen, metal, metalness, gloss, glow2);
			}
			else if (def.Id == "BBL_BoSilver")
			{
				Color glow3 = default(Color);
				((Color)(ref glow3))..ctor(glow.r * 0.35f, glow.g * 0.35f, glow.b * 0.35f, 1f);
				EndCap(val, 0.2606f, capLen, metal, metalness, gloss, glow3);
				EndCap(val, -0.2606f, capLen, metal, metalness, gloss, glow3);
				Color color = default(Color);
				((Color)(ref color))..ctor(0.42f, 0.55f, 0.98f, 1f);
				Color glow4 = default(Color);
				((Color)(ref glow4))..ctor(0.16f, 0.24f, 0.5f, 1f);
				Band(val, "inlay_tip", 0.175f, 0.01f, 0.006f, color, 0.95f, 0.8f, glow4);
				Band(val, "inlay_butt", -0.175f, 0.01f, 0.006f, color, 0.95f, 0.8f, glow4);
			}
			else if (def.Id == "BBL_BoBlackmetal")
			{
				Color color2 = default(Color);
				((Color)(ref color2))..ctor(0.26f, 0.2f, 0.32f, 1f);
				EndCap(val, 0.2606f, capLen, color2, 0.7f, 0.35f, glow2);
				EndCap(val, -0.2606f, capLen, color2, 0.7f, 0.35f, glow2);
				Color color3 = default(Color);
				((Color)(ref color3))..ctor(0.64f, 0.42f, 0.8f, 1f);
				Band(val, "collar_a", 0.04f, 0.012f, 0.0082f, color3, 0.85f, 0.6f, glow);
				Band(val, "collar_b", -0.04f, 0.012f, 0.0082f, color3, 0.85f, 0.6f, glow);
				GlowCord(val, glow);
			}
			else if (def.Id == "BBL_BoStorm")
			{
				EndCap(val, 0.2606f, 0.04f, metal, metalness, gloss, glow2);
				EndCap(val, -0.2606f, 0.04f, metal, metalness, gloss, glow2);
				Band(val, "band_a", -0.17f, 0.024f, 0.0082f, metal, 0.35f, 0.4f, glow);
				Band(val, "band_b", 0.08f, 0.016f, 0.0082f, metal, 0.35f, 0.4f, glow);
				GlowCord(val, glow);
			}
			else if (def.Id == "BBL_BoInfernal")
			{
				EndCap(val, 0.2606f, capLen, metal, metalness, gloss, glow);
				EndCap(val, -0.2606f, capLen, metal, metalness, gloss, glow);
			}
			else if (def.Id == "BBL_BoRime")
			{
				EndCap(val, 0.2606f, 0.04f, metal, metalness, gloss, glow);
				EndCap(val, -0.2606f, 0.04f, metal, metalness, gloss, glow);
				Color color4 = default(Color);
				((Color)(ref color4))..ctor(0.9f, 0.97f, 1f, 1f);
				Band(val, "frost_tip", 0.19f, 0.01f, 0.0062f, color4, 0.4f, 0.6f, glow);
				Band(val, "frost_butt", -0.19f, 0.01f, 0.0062f, color4, 0.4f, 0.6f, glow);
				Band(val, "frost_ring", 0.044f, 0.014f, 0.0072f, color4, 0.35f, 0.55f, glow);
				GlowCord(val, glow);
			}
		}

		private static void Look(string id, out Color wood, out Color metal, out Color wrap, out Color glow, out float metalness, out float gloss, out float capLen)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_021c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0221: Unknown result type (might be due to invalid IL or missing references)
			//IL_023b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0240: Unknown result type (might be due to invalid IL or missing references)
			//IL_025a: Unknown result type (might be due to invalid IL or missing references)
			//IL_025f: Unknown result type (might be due to invalid IL or missing references)
			//IL_027a: Unknown result type (might be due to invalid IL or missing references)
			//IL_027f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0302: Unknown result type (might be due to invalid IL or missing references)
			//IL_0307: Unknown result type (might be due to invalid IL or missing references)
			//IL_0322: Unknown result type (might be due to invalid IL or missing references)
			//IL_0327: Unknown result type (might be due to invalid IL or missing references)
			//IL_036c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0371: Unknown result type (might be due to invalid IL or missing references)
			//IL_038b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0390: Unknown result type (might be due to invalid IL or missing references)
			//IL_03aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_03af: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0414: Unknown result type (might be due to invalid IL or missing references)
			//IL_0419: Unknown result type (might be due to invalid IL or missing references)
			//IL_0433: Unknown result type (might be due to invalid IL or missing references)
			//IL_0438: Unknown result type (might be due to invalid IL or missing references)
			//IL_0452: Unknown result type (might be due to invalid IL or missing references)
			//IL_0457: Unknown result type (might be due to invalid IL or missing references)
			//IL_0472: Unknown result type (might be due to invalid IL or missing references)
			//IL_0477: Unknown result type (might be due to invalid IL or missing references)
			wood = new Color(1f, 1f, 1f, 1f);
			metal = new Color(0.72f, 0.48f, 0.22f, 1f);
			wrap = new Color(0.4f, 0.24f, 0.14f, 1f);
			glow = new Color(0f, 0f, 0f, 1f);
			metalness = 0.85f;
			gloss = 0.55f;
			capLen = 0.0525f;
			switch (id)
			{
			case "BBL_BoWood":
				wrap = new Color(0.45f, 0.28f, 0.16f, 1f);
				break;
			case "BBL_BoIron":
				wood = new Color(0.55f, 0.46f, 0.36f, 1f);
				metal = new Color(0.78f, 0.8f, 0.82f, 1f);
				wrap = new Color(0.46f, 0.58f, 0.32f, 1f);
				metalness = 0.92f;
				gloss = 0.62f;
				break;
			case "BBL_BoSilver":
				wood = new Color(0.58f, 0.42f, 0.26f, 1f);
				metal = new Color(0.62f, 0.72f, 0.95f, 1f);
				wrap = new Color(0.38f, 0.48f, 0.78f, 1f);
				glow = new Color(0.08f, 0.12f, 0.28f, 1f);
				metalness = 0.92f;
				gloss = 0.7f;
				break;
			case "BBL_BoBlackmetal":
				wood = new Color(0.2f, 0.18f, 0.22f, 1f);
				metal = new Color(0.58f, 0.46f, 0.72f, 1f);
				wrap = new Color(0.52f, 0.34f, 0.62f, 1f);
				glow = new Color(0.16f, 0.06f, 0.24f, 1f);
				metalness = 0.88f;
				gloss = 0.62f;
				break;
			case "BBL_BoStorm":
				wood = new Color(0.78f, 0.84f, 0.62f, 1f);
				metal = new Color(0.22f, 0.48f, 0.42f, 1f);
				wrap = new Color(0.28f, 0.62f, 0.54f, 1f);
				glow = new Color(0.05f, 0.22f, 0.16f, 1f);
				metalness = 0.4f;
				gloss = 0.4f;
				break;
			case "BBL_BoInfernal":
				wood = new Color(0.16f, 0.14f, 0.13f, 1f);
				metal = new Color(0.75f, 0.32f, 0.14f, 1f);
				wrap = new Color(0.62f, 0.2f, 0.08f, 1f);
				glow = new Color(0.45f, 0.1f, 0.02f, 1f);
				metalness = 0.8f;
				gloss = 0.45f;
				break;
			case "BBL_BoRime":
				wood = new Color(0.74f, 0.78f, 0.84f, 1f);
				metal = new Color(0.9f, 0.96f, 1f, 1f);
				wrap = new Color(0.55f, 0.78f, 0.95f, 1f);
				glow = new Color(0.28f, 0.48f, 0.7f, 1f);
				metalness = 0.72f;
				gloss = 0.58f;
				break;
			}
		}

		private static void EndCap(Transform staff, float z, float length, Color color, float metalness, float gloss, Color glow)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = Band(staff, (z >= 0f) ? "cap_tip" : "cap_butt", z, length, 0.0069f, color, metalness, gloss, glow);
			if (val != null)
			{
				ApplyWear(val, WearFor, (z >= 0f) ? 1 : 2);
			}
		}

		private static void GlowCord(Transform staff, Color glow)
		{
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			MeshRenderer component = ((Component)staff).GetComponent<MeshRenderer>();
			if (component == null || ((Renderer)component).materials == null)
			{
				return;
			}
			Material[] materials = ((Renderer)component).materials;
			for (int i = 0; i < materials.Length; i++)
			{
				if (materials[i] == null)
				{
					continue;
				}
				string text = ((((Object)materials[i]).name == null) ? "" : ((Object)materials[i]).name.ToLowerInvariant());
				if (text.Contains("handle") || text.Contains("wrap") || (i > 0 && !text.Contains("wood")))
				{
					materials[i].EnableKeyword("_EMISSION");
					if (materials[i].HasProperty("_EmissionColor"))
					{
						materials[i].SetColor("_EmissionColor", glow);
					}
				}
			}
			((Renderer)component).materials = materials;
		}

		private static void TintStaff(Transform staff, Color wood, Color wrap)
		{
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: 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_00c3: Unknown result type (might be due to invalid IL or missing references)
			MeshRenderer component = ((Component)staff).GetComponent<MeshRenderer>();
			if (component == null || ((Renderer)component).materials == null)
			{
				return;
			}
			Material[] materials = ((Renderer)component).materials;
			for (int i = 0; i < materials.Length; i++)
			{
				if (materials[i] != null && materials[i].HasProperty("_Color"))
				{
					string text = ((((Object)materials[i]).name == null) ? "" : ((Object)materials[i]).name.ToLowerInvariant());
					Color val = ((text.Contains("handle") || text.Contains("wrap") || (i > 0 && !text.Contains("wood"))) ? wrap : wood);
					materials[i].SetColor("_Color", val);
					materials[i].color = val;
				}
			}
			((Renderer)component).materials = materials;
		}

		private static GameObject Band(Transform parent, string name, float z, float length, float radius, Color color, float metalness, float gloss, Color glow)
		{
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: 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_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = NewCylinder(name);
			if (val == null)
			{
				return null;
			}
			val.transform.SetParent(parent, false);
			SetVec(val.transform, "localPosition", 0f, 0f, z);
			SetVec(val.transform, "localScale", radius / 0.5f, length / 2f, radius / 0.5f);
			SetRotX(val.transform, 90f);
			MeshRenderer component = val.GetComponent<MeshRenderer>();
			if (component == null)
			{
				return val;
			}
			MeshRenderer component2 = ((Component)parent).GetComponent<MeshRenderer>();
			Material donor = ((component2 != null && ((Renderer)component2).materials != null && ((Renderer)component2).materials.Length != 0) ? ((Renderer)component2).materials[0] : null);
			Material val2 = CopyMaterial(donor);
			if (val2 == null)
			{
				return val;
			}
			if (val2.HasProperty("_Color"))
			{
				val2.SetColor("_Color", color);
			}
			val2.color = color;
			SetFloat(val2, "_Metallic", metalness);
			SetFloat(val2, "_Glossiness", gloss);
			if (glow.r + glow.g + glow.b > 0.01f)
			{
				val2.EnableKeyword("_EMISSION");
				if (val2.HasProperty("_EmissionColor"))
				{
					val2.SetColor("_EmissionColor", glow);
				}
			}
			PropertyInfo property = ((object)component).GetType().GetProperty("sharedMaterial");
			if (property != null && property.CanWrite)
			{
				property.SetValue(component, val2, null);
			}
			return val;
		}

		private static void ApplyWear(GameObject piece, string id, int salt)
		{
			if (piece == null || string.IsNullOrEmpty(id))
			{
				return;
			}
			object obj = WearTexture(id, salt);
			if (obj == null)
			{
				return;
			}
			MeshRenderer component = piece.GetComponent<MeshRenderer>();
			if (component == null)
			{
				return;
			}
			PropertyInfo property = ((object)component).GetType().GetProperty("sharedMaterial");
			object obj2 = ((property == null) ? null : property.GetValue(component, null));
			if (obj2 == null)
			{
				return;
			}
			MethodInfo methodInfo = null;
			MethodInfo[] methods = obj2.GetType().GetMethods();
			foreach (MethodInfo methodInfo2 in methods)
			{
				if (!(methodInfo2.Name != "SetTexture"))
				{
					ParameterInfo[] parameters = methodInfo2.GetParameters();
					if (parameters.Length == 2 && parameters[0].ParameterType == typeof(string))
					{
						methodInfo = methodInfo2;
						break;
					}
				}
			}
			if (!(methodInfo == null))
			{
				methodInfo.Invoke(obj2, new object[2] { "_MainTex", obj });
			}
		}

		private static object WearTexture(string id, int salt)
		{
			string text = id + ":" + salt;
			if (WearCache.TryGetValue(text, out var value))
			{
				return value;
			}
			Type type = QuietType("Texture2D", "UnityEngine");
			Type type2 = QuietType("TextureFormat", "UnityEngine");
			Type type3 = QuietType("Color", "UnityEngine");
			if (type == null || type2 == null || type3 == null)
			{
				return null;
			}
			ConstructorInfo constructor = type.GetConstructor(new Type[4]
			{
				typeof(int),
				typeof(int),
				type2,
				typeof(bool)
			});
			if (constructor == null)
			{
				return null;
			}
			object obj = constructor.Invoke(new object[4]
			{
				128,
				128,
				Enum.Parse(type2, "RGBA32"),
				false
			});
			if (obj == null)
			{
				return null;
			}
			type.GetProperty("name")?.SetValue(obj, "wear_" + text, null);
			float[] rgb = new float[49152];
			for (int i = 0; i < rgb.Length; i++)
			{
				rgb[i] = 1f;
			}
			int num = StableHash(id) + salt * 97;
			Random rng = new Random((num == int.MinValue) ? 1 : Math.Abs(num));
			Action<int, int, float> action = delegate(int x, int y, float keep)
			{
				if ((uint)y < 128u)
				{
					x %= 128;
					if (x < 0)
					{
						x += 128;
					}
					int num7 = (y * 128 + x) * 3;
					rgb[num7] = ClampWear(rgb[num7] * keep);
					rgb[num7 + 1] = ClampWear(rgb[num7 + 1] * keep);
					rgb[num7 + 2] = ClampWear(rgb[num7 + 2] * keep);
				}
			};
			for (int num2 = 0; num2 < 3; num2++)
			{
				for (int num3 = 0; num3 < 128; num3++)
				{
					float arg = 0.68f - 0.12f * (float)((num3 * 13 + num2 + salt) & 3) / 3f;
					action(num3, num2, arg);
					action(num3, 127 - num2, arg);
				}
			}
			switch (id)
			{
			case "BBL_BoIron":
				Scratches(rng, 128, action, 5, 16, 34, 0.48f, 1);
				Patches(rng, 128, action, 2, 0.55f, 4);
				break;
			case "BBL_BoSilver":
				Scratches(rng, 128, action, 10, 12, 30, 0.58f, 0);
				break;
			case "BBL_BoBlackmetal":
				Scratches(rng, 128, action, 6, 10, 24, 1.5f, 0);
				break;
			case "BBL_BoStorm":
				Scratches(rng, 128, action, 7, 6, 16, 0.5f, 0);
				break;
			case "BBL_BoInfernal":
				Patches(rng, 128, action, 4, 0.45f, 6);
				Scratches(rng, 128, action, 3, 10, 18, 0.52f, 1);
				break;
			case "BBL_BoRime":
				Scratches(rng, 128, action, 4, 8, 18, 1.45f, 0);
				Patches(rng, 128, action, 2, 0.55f, 3);
				break;
			default:
				Scratches(rng, 128, action, 6, 14, 28, 0.5f, 1);
				Patches(rng, 128, action, 2, 0.58f, 4);
				break;
			}
			ConstructorInfo constructor2 = type3.GetConstructor(new Type[4]
			{
				typeof(float),
				typeof(float),
				typeof(float),
				typeof(float)
			});
			if (constructor2 == null)
			{
				return null;
			}
			Array array = Array.CreateInstance(type3, 16384);
			for (int num4 = 0; num4 < 16384; num4++)
			{
				array.SetValue(constructor2.Invoke(new object[4]
				{
					rgb[num4 * 3],
					rgb[num4 * 3 + 1],
					rgb[num4 * 3 + 2],
					1f
				}), num4);
			}
			MethodInfo methodInfo = null;
			MethodInfo[] methods = type.GetMethods();
			foreach (MethodInfo methodInfo2 in methods)
			{
				if (!(methodInfo2.Name != "SetPixels"))
				{
					ParameterInfo[] parameters = methodInfo2.GetParameters();
					if (parameters.Length == 1 && parameters[0].ParameterType.IsArray)
					{
						methodInfo = methodInfo2;
						break;
					}
				}
			}
			if (methodInfo == null)
			{
				return null;
			}
			methodInfo.Invoke(obj, new object[1] { array });
			MethodInfo[] methods2 = type.GetMethods();
			foreach (MethodInfo methodInfo3 in methods2)
			{
				if (methodInfo3.Name == "Apply" && methodInfo3.GetParameters().Length == 0)
				{
					methodInfo3.Invoke(obj, null);
					break;
				}
			}
			SetEnum(obj, "filterMode", "FilterMode", "Bilinear");
			SetEnum(obj, "wrapMode", "TextureWrapMode", "Repeat");
			WearCache[text] = obj;
			return obj;
		}

		private static void Scratches(Random rng, int n, Action<int, int, float> ink, int count, int minLen, int maxLen, float keep, int width)
		{
			for (int i = 0; i < count; i++)
			{
				int num = rng.Next(n);
				int num2 = rng.Next(8, n - 8);
				int num3 = rng.Next(minLen, maxLen);
				int num4 = rng.Next(3) - 1;
				int num5 = rng.Next(3) - 1;
				if (num4 == 0 && num5 == 0)
				{
					num4 = 1;
				}
				for (int j = 0; j < num3; j++)
				{
					for (int k = -width; k <= width; k++)
					{
						ink(num + num4 * j + k, num2 + num5 * j, keep);
					}
				}
			}
		}

		private static void Patches(Random rng, int n, Action<int, int, float> ink, int count, float keep, int rad)
		{
			for (int i = 0; i < count; i++)
			{
				int num = rng.Next(n);
				int num2 = rng.Next(10, n - 10);
				for (int j = -rad; j <= rad; j++)
				{
					for (int k = -rad; k <= rad; k++)
					{
						if (k * k + j * j <= rad * rad)
						{
							ink(num + k, num2 + j, keep);
						}
					}
				}
			}
		}

		private static float ClampWear(float value)
		{
			if (value < 0.4f)
			{
				return 0.4f;
			}
			if (value > 1.5f)
			{
				return 1.5f;
			}
			return value;
		}

		private static int StableHash(string text)
		{
			int num = 23;
			for (int i = 0; i < text.Length; i++)
			{
				num = num * 31 + text[i];
			}
			return num;
		}

		private static void SetEnum(object target, string prop, string enumName, string value)
		{
			PropertyInfo property = target.GetType().GetProperty(prop);
			Type type = QuietType(enumName, "UnityEngine");
			if (!(property == null) && !(type == null) && property.CanWrite)
			{
				property.SetValue(target, Enum.Parse(type, value), null);
			}
		}

		private static GameObject NewCylinder(string name)
		{
			Type type = QuietType("PrimitiveType", "UnityEngine");
			if (type == null)
			{
				return null;
			}
			MethodInfo method = typeof(GameObject).GetMethod("CreatePrimitive", new Type[1] { type });
			if (method == null)
			{
				return null;
			}
			object obj = Enum.Parse(type, "Cylinder");
			object? obj2 = method.Invoke(null, new object[1] { obj });
			GameObject val = (GameObject)((obj2 is GameObject) ? obj2 : null);
			if (val == null)
			{
				return null;
			}
			((Object)val).name = name;
			Type type2 = QuietType("Collider", "UnityEngine");
			Component val2 = ((type2 == null) ? null : val.GetComponent(type2));
			if (val2 != null)
			{
				DestroyNow(val2);
			}
			return val;
		}

		private static void DestroyNow(object obj)
		{
			MethodInfo methodInfo = null;
			MethodInfo[] methods = typeof(Object).GetMethods(BindingFlags.Static | BindingFlags.Public);
			foreach (MethodInfo methodInfo2 in methods)
			{
				if (!(methodInfo2.Name != "DestroyImmediate"))
				{
					ParameterInfo[] parameters = methodInfo2.GetParameters();
					if (parameters.Length >= 1 && typeof(Object).IsAssignableFrom(parameters[0].ParameterType))
					{
						methodInfo = methodInfo2;
						break;
					}
				}
			}
			if (!(methodInfo == null))
			{
				if (methodInfo.GetParameters().Length == 1)
				{
					methodInfo.Invoke(null, new object[1] { obj });
				}
				else
				{
					methodInfo.Invoke(null, new object[2] { obj, false });
				}
			}
		}

		private static Material CopyMaterial(Material donor)
		{
			ConstructorInfo constructor = typeof(Material).GetConstructor(new Type[1] { typeof(Material) });
			if (constructor != null && donor != null)
			{
				object obj = constructor.Invoke(new object[1] { donor });
				return (Material)((obj is Material) ? obj : null);
			}
			constructor = typeof(Material).GetConstructor(new Type[1] { QuietType("Shader", "UnityEngine") ?? typeof(object) });
			return null;
		}

		private static void SetFloat(Material mat, string name, float value)
		{
			if (mat != null && mat.HasProperty(name))
			{
				MethodInfo method = typeof(Material).GetMethod("SetFloat", new Type[2]
				{
					typeof(string),
					typeof(float)
				});
				if (method != null)
				{
					method.Invoke(mat, new object[2] { name, value });
				}
			}
		}

		private static void SetVec(object transform, string prop, float x, float y, float z)
		{
			PropertyInfo property = transform.GetType().GetProperty(prop);
			if (!(property == null) && property.CanWrite)
			{
				object obj = Activator.CreateInstance(property.PropertyType);
				Type propertyType = property.PropertyType;
				propertyType.GetField("x").SetValue(obj, x);
				propertyType.GetField("y").SetValue(obj, y);
				propertyType.GetField("z").SetValue(obj, z);
				property.SetValue(transform, obj, null);
			}
		}

		private static void SetRotX(object transform, float degrees)
		{
			PropertyInfo property = transform.GetType().GetProperty("localRotation");
			if (!(property == null) && property.CanWrite)
			{
				object obj = Activator.CreateInstance(property.PropertyType);
				Type propertyType = property.PropertyType;
				float num = degrees * 0.5f * (float)Math.PI / 180f;
				propertyType.GetField("x").SetValue(obj, (float)Math.Sin(num));
				propertyType.GetField("y").SetValue(obj, 0f);
				propertyType.GetField("z").SetValue(obj, 0f);
				propertyType.GetField("w").SetValue(obj, (float)Math.Cos(num));
				property.SetValue(transform, obj, null);
			}
		}

		private static void StripMagic(GameObject go)
		{
			string[] array = new string[4] { "ParticleSystem", "Light", "TrailRenderer", "AudioSource" };
			foreach (string name in array)
			{
				Type type = QuietType(name, "UnityEngine");
				if (type == null)
				{
					continue;
				}
				Component[] array2 = Kids(go, type);
				foreach (Component val in array2)
				{
					if (val != null && val.gameObject != null && val.gameObject != go)
					{
						val.gameObject.SetActive(false);
					}
				}
			}
		}

		private static void ShowMesh(GameObject go)
		{
			Renderer[] componentsInChildren = go.GetComponentsInChildren<Renderer>(true);
			if (componentsInChildren == null)
			{
				return;
			}
			Renderer[] array = componentsInChildren;
			foreach (Renderer val in array)
			{
				if (val == null)
				{
					continue;
				}
				string name = ((object)val).GetType().Name;
				if (name == "ParticleSystemRenderer" || name == "TrailRenderer")
				{
					((Component)val).gameObject.SetActive(false);
					continue;
				}
				WakeChain(go, ((Component)val).gameObject);
				PropertyInfo property = ((object)val).GetType().GetProperty("enabled");
				if (property != null && property.CanWrite)
				{
					property.SetValue(val, true, null);
				}
				if (name == "SkinnedMeshRenderer")
				{
					PropertyInfo property2 = ((object)val).GetType().GetProperty("updateWhenOffscreen");
					if (property2 != null && property2.CanWrite)
					{
						property2.SetValue(val, false, null);
					}
				}
			}
		}

		private static void WakeChain(GameObject root, GameObject node)
		{
			while (node != null)
			{
				node.SetActive(true);
				if (node == root)
				{
					break;
				}
				PropertyInfo property = ((object)node.transform).GetType().GetProperty("parent");
				Transform val = (Transform)((property == null) ? null : /*isinst with value type is only supported in some contexts*/);
				node = ((val == null) ? null : ((Component)val).gameObject);
			}
		}

		private static Component[] Kids(GameObject go, Type type)
		{
			if (go == null || type == null)
			{
				return (Component[])(object)new Component[0];
			}
			MethodInfo methodInfo = null;
			MethodInfo[] methods = typeof(GameObject).GetMethods();
			foreach (MethodInfo methodInfo2 in methods)
			{
				if (!(methodInfo2.Name != "GetComponentsInChildren") && !methodInfo2.IsGenericMethod)
				{
					ParameterInfo[] parameters = methodInfo2.GetParameters();
					if (parameters.Length == 2 && parameters[0].ParameterType == typeof(Type) && parameters[1].ParameterType == typeof(bool))
					{
						methodInfo = methodInfo2;
						break;
					}
				}
			}
			IEnumerable enumerable = ((methodInfo == null) ? null : (methodInfo.Invoke(go, new object[2] { type, true }) as IEnumerable));
			if (enumerable == null)
			{
				return (Component[])(object)new Component[0];
			}
			List<Component> list = new List<Component>();
			foreach (object item in enumerable)
			{
				Component val = (Component)((item is Component) ? item : null);
				if (val != null)
				{
					list.Add(val);
				}
			}
			return list.ToArray();
		}

		private static object Db()
		{
			Type type = AccessTools.TypeByName("ObjectDB");
			return AccessTools.Property(type, "instance").GetValue(null, null);
		}

		private static object ZNet()
		{
			Type type = AccessTools.TypeByName("ZNetScene");
			PropertyInfo propertyInfo = ((type == null) ? null : AccessTools.Property(type, "instance"));
			return (propertyInfo == null) ? null : propertyInfo.GetValue(null, null);
		}

		private static GameObject FindPrefab(string name)
		{
			if (string.IsNullOrEmpty(name))
			{
				return null;
			}
			Type type = AccessTools.TypeByName("ObjectDB");
			object obj = ((type == null) ? null : AccessTools.Property(type, "instance")?.GetValue(null, null));
			if (obj != null)
			{
				MethodInfo methodInfo = AccessTools.Method(type, "GetItemPrefab", new Type[1] { typeof(string) }, (Type[])null);
				if (methodInfo != null)
				{
					object? obj2 = methodInfo.Invoke(obj, new object[1] { name });
					GameObject val = (GameObject)((obj2 is GameObject) ? obj2 : null);
					if (val != null)
					{
						return val;
					}
				}
				IList list = Get(obj, "m_items") as IList;
				GameObject val2 = FindInList(list, name);
				if (val2 != null)
				{
					return val2;
				}
			}
			object obj3 = ZNet();
			if (obj3 != null)
			{
				if (Get(obj3, "m_namedPrefabs") is IDictionary dictionary)
				{
					object obj4 = RealHash(name);
					if (obj4 != null && dictionary.Contains(obj4))
					{
						object? obj5 = dictionary[obj4];
						return (GameObject)((obj5 is GameObject) ? obj5 : null);
					}
					foreach (object value in dictionary.Values)
					{
						GameObject val3 = (GameObject)((value is GameObject) ? value : null);
						if (val3 != null && string.Equals(((Object)val3).name, name, StringComparison.OrdinalIgnoreCase))
						{
							return val3;
						}
					}
				}
				GameObject val4 = FindInList(Get(obj3, "m_prefabs") as IList, name);
				if (val4 != null)
				{
					return val4;
				}
			}
			return null;
		}

		private static bool ListHas(IList list, string name)
		{
			if (list == null || string.IsNullOrEmpty(name))
			{
				return false;
			}
			foreach (object item in list)
			{
				Object val = (Object)((item is Object) ? item : null);
				if (!Alive(val) || !(val.name == name))
				{
					continue;
				}
				return true;
			}
			return false;
		}

		private static GameObject FindInList(IList list, string name)
		{
			if (list == null)
			{
				return null;
			}
			foreach (object item in list)
			{
				GameObject val = (GameObject)((item is GameObject) ? item : null);
				if (val != null && string.Equals(((Object)val).name, name, StringComparison.OrdinalIgnoreCase))
				{
					return val;
				}
			}
			return null;
		}

		private static bool ContainsGo(IList list, GameObject go)
		{
			foreach (object item in list)
			{
				if (item == go)
				{
					return true;
				}
			}
			return false;
		}

		private static void RemoveNamed(IList list, string name)
		{
			if (list == null)
			{
				return;
			}
			for (int num = list.Count - 1; num >= 0; num--)
			{
				object? obj = list[num];
				Object val = (Object)((obj is Object) ? obj : null);
				if (val != null && val.name == name)
				{
					list.RemoveAt(num);
				}
			}
		}

		private static object Get(object target, string field)
		{
			if (target == null)
			{
				return null;
			}
			FieldInfo field2 = target.GetType().GetField(field, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			return (field2 == null) ? null : field2.GetValue(target);
		}

		private static void Set(object target, string field, object value)
		{
			if (target != null)
			{
				FieldInfo field2 = target.GetType().GetField(field, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (!(field2 == null))
				{
					field2.SetValue(target, value);
				}
			}
		}

		private static float MathfClamp(float v, float a, float b)
		{
			if (v < a)
			{
				return a;
			}
			if (v > b)
			{
				return b;
			}
			return v;
		}
	}
}