Decompiled source of Bear Riding v1.0.0

plugins/BearRiding.dll

Decompiled 2 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BearRiding.Core;
using BearRiding.Dev;
using BearRiding.Gameplay;
using BearRiding.Visual;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("assembly_utils")]
[assembly: IgnoresAccessChecksTo("assembly_valheim")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace BearRiding
{
	public static class Cfg
	{
		public static ConfigEntry<string> Bears;

		public static ConfigEntry<bool> MountFightsOnItsOwn;

		public static ConfigEntry<int> TamingMinutes;

		public static ConfigEntry<string> BearFood;

		public static ConfigEntry<bool> Breeding;

		public static ConfigEntry<int> MaxBearsNearby;

		public static ConfigEntry<int> PregnancySeconds;

		public static ConfigEntry<int> CubGrowMinutes;

		public static ConfigEntry<float> BearbornChance;

		public static ConfigEntry<float> BearbornInheritChance;

		public static ConfigEntry<float> BearbornMaxGrowth;

		public static ConfigEntry<float> BearbornHealthPerLevel;

		public static ConfigEntry<float> BearbornDamagePerLevel;

		public static ConfigEntry<float> BearbornXpScale;

		public static ConfigEntry<bool> Hibernation;

		public static ConfigEntry<int> HibernationSeconds;

		public static ConfigEntry<float> ClawStamina;

		public static ConfigEntry<float> SlamStamina;

		public static ConfigEntry<float> LeapStamina;

		public static ConfigEntry<float> LeapUp;

		public static ConfigEntry<float> LeapForward;

		public static ConfigEntry<float> RunStaminaDrain;

		public static ConfigEntry<float> ArmorScale;

		public static ConfigEntry<float> HealthScale;

		public static readonly ConfigEntry<string>[] Stations = new ConfigEntry<string>[5];

		public static readonly Dictionary<TackKind, ConfigEntry<string>[]> Recipes = new Dictionary<TackKind, ConfigEntry<string>[]>();

		public static ConfigEntry<bool> ShowHints;

		private static readonly Dictionary<TackKind, string[]> DefaultRecipes = new Dictionary<TackKind, string[]>
		{
			[TackKind.Saddle] = new string[5] { "BjornHide:4,DeerHide:4,LeatherScraps:8,Bronze:4", "WolfPelt:3,TrollHide:3,Iron:4,Silver:2", "LoxPelt:3,LinenThread:10,BlackMetal:4", "ScaleHide:3,Carapace:6,JuteBlue:3", "AskHide:4,FlametalNew:4,MorgenSinew:2" },
			[TackKind.LightBarding] = new string[5] { "BjornHide:6,DeerHide:4,Bronze:4", "WolfPelt:4,TrollHide:4,Silver:4", "LinenThread:15,LoxPelt:3,BlackMetal:4", "JuteBlue:4,ScaleHide:3,Carapace:8", "AskHide:6,LinenThread:10,FlametalNew:4" },
			[TackKind.HeavyBarding] = new string[5] { "Bronze:16,BjornHide:4,LeatherScraps:8,BronzeNails:20", "Iron:16,Silver:6,WolfPelt:3,Chain:2", "BlackMetal:14,LoxPelt:3,LinenThread:10", "Carapace:18,ScaleHide:4,Eitr:4", "FlametalNew:16,AskHide:4,CharredBone:6" },
			[TackKind.Saddlebags] = new string[5] { "BjornHide:4,DeerHide:4,LeatherScraps:6,Bronze:2", "TrollHide:4,WolfPelt:2,Iron:2", "LoxPelt:3,LinenThread:15,BlackMetal:2", "JuteBlue:6,ScaleHide:3,YggdrasilWood:4", "AskHide:6,LinenThread:15,FlametalNew:2" }
		};

		private const string DefaultHarnessBind = "LinenThread:10,JuteBlue:4,BlackMetal:4";

		private const string DefaultHarnessUpgrade = "FlametalNew:8,AskHide:6,MorgenSinew:2";

		private static readonly string[] DefaultStations = new string[5] { "forge:1", "forge:2", "piece_artisanstation:1", "blackforge:1", "blackforge:3" };

		private static readonly string[] Biomes = new string[5] { "Black Forest", "Mountains", "Plains", "Mistlands", "Ashlands" };

		public static Tuning Current { get; private set; } = new Tuning();

		public static BornTuning Born { get; private set; } = new BornTuning();

		public static void Bind(ConfigFile c)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Expected O, but got Unknown
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Expected O, but got Unknown
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Expected O, but got Unknown
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Expected O, but got Unknown
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Expected O, but got Unknown
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Expected O, but got Unknown
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Expected O, but got Unknown
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Expected O, but got Unknown
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: Expected O, but got Unknown
			//IL_023e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0248: Expected O, but got Unknown
			//IL_027b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0285: Expected O, but got Unknown
			//IL_02b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c2: Expected O, but got Unknown
			//IL_02f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ff: Expected O, but got Unknown
			//IL_0320: Unknown result type (might be due to invalid IL or missing references)
			//IL_032a: Expected O, but got Unknown
			//IL_0356: Unknown result type (might be due to invalid IL or missing references)
			//IL_0360: Expected O, but got Unknown
			//IL_0393: Unknown result type (might be due to invalid IL or missing references)
			//IL_039d: Expected O, but got Unknown
			//IL_03d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03da: Expected O, but got Unknown
			//IL_040d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0417: Expected O, but got Unknown
			//IL_044a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0454: Expected O, but got Unknown
			//IL_0487: Unknown result type (might be due to invalid IL or missing references)
			//IL_0491: Expected O, but got Unknown
			//IL_04c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ce: Expected O, but got Unknown
			//IL_0501: Unknown result type (might be due to invalid IL or missing references)
			//IL_050b: Expected O, but got Unknown
			//IL_053e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0548: Expected O, but got Unknown
			//IL_05d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_05dc: Expected O, but got Unknown
			//IL_06fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0704: Expected O, but got Unknown
			//IL_0725: Unknown result type (might be due to invalid IL or missing references)
			//IL_072f: Expected O, but got Unknown
			//IL_0692: Unknown result type (might be due to invalid IL or missing references)
			//IL_069c: Expected O, but got Unknown
			ConfigurationManagerAttributes val = new ConfigurationManagerAttributes
			{
				IsAdminOnly = true
			};
			Bears = c.Bind<string>("1 - General", "Bears", "Bjorn,Bjorn_sleeping", new ConfigDescription("Prefab names of the bears that can be tamed, bred and wear bear tack, comma separated, '*' as wildcard. The spirit caller's summoned bear is never included. Takes effect after a restart; on a server every player should use the same list.", (AcceptableValueBase)null, new object[1] { val }));
			MountFightsOnItsOwn = c.Bind<bool>("1 - General", "MountFightsOnItsOwn", false, new ConfigDescription("A ridden bear that stands still may run after enemies by itself. Off: while you sit in the saddle, the bear only does what you tell it.", (AcceptableValueBase)null, new object[1] { val }));
			TamingMinutes = c.Bind<int>("2 - Taming", "TamingMinutes", 30, new ConfigDescription("Minutes a fed, calm bear needs near you to grow tame (the wolf needs 30). A Bearborn needs half as long again.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 240), new object[1] { val }));
			BearFood = c.Bind<string>("2 - Taming", "BearFood", "Blueberries,Raspberry,Honey,FishRaw,RawMeat,DeerMeat", new ConfigDescription("What a bear eats, comma separated item prefab names.", (AcceptableValueBase)null, new object[1] { val }));
			Breeding = c.Bind<bool>("3 - Breeding", "Breeding", true, new ConfigDescription("Tame, fed bears that stand near each other have cubs.", (AcceptableValueBase)null, new object[1] { val }));
			MaxBearsNearby = c.Bind<int>("3 - Breeding", "MaxBearsNearby", 4, new ConfigDescription("No more cubs once this many bears and cubs live within 10 m (lox and wolves use 4).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(2, 20), new object[1] { val }));
			PregnancySeconds = c.Bind<int>("3 - Breeding", "PregnancySeconds", 120, new ConfigDescription("Seconds from the bears' courtship to the birth (the lox takes 120).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(10, 3600), new object[1] { val }));
			CubGrowMinutes = c.Bind<int>("3 - Breeding", "CubGrowMinutes", 75, new ConfigDescription("Minutes a cub needs to grow into a bear (a wolf cub takes 50, a lox calf 100).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 600), new object[1] { val }));
			BearbornChance = c.Bind<float>("4 - Bearborn", "BearbornChance", 0.1f, new ConfigDescription("Chance that a wild bear is a Bearborn, rolled once per bear (0.10 = 1 in 10).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), new object[1] { val }));
			BearbornInheritChance = c.Bind<float>("4 - Bearborn", "BearbornInheritChance", 0.25f, new ConfigDescription("Chance that a cub of a Bearborn grows into a Bearborn itself.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), new object[1] { val }));
			BearbornMaxGrowth = c.Bind<float>("4 - Bearborn", "MaxGrowth", 0.3f, new ConfigDescription("How much bigger a Bearborn grows by level 10, on top of its star size (0.30 = 30 %).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), new object[1] { val }));
			BearbornHealthPerLevel = c.Bind<float>("4 - Bearborn", "HealthPerLevel", 0.1f, new ConfigDescription("Extra health per level, as a share of the bear's own (level 1 starts with +25 %).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), new object[1] { val }));
			BearbornDamagePerLevel = c.Bind<float>("4 - Bearborn", "DamagePerLevel", 0.05f, new ConfigDescription("Extra damage per level.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), new object[1] { val }));
			BearbornXpScale = c.Bind<float>("4 - Bearborn", "ExperienceScale", 1f, new ConfigDescription("Multiplies the experience a Bearborn gains (2 for every 25 m beside you, 15 for a kill).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 20f), new object[1] { val }));
			Hibernation = c.Bind<bool>("4 - Bearborn", "Hibernation", true, new ConfigDescription("A tame Bearborn that falls does not die: it sleeps off its wounds and wakes with 30 % health. A butcher knife still kills it.", (AcceptableValueBase)null, new object[1] { val }));
			HibernationSeconds = c.Bind<int>("4 - Bearborn", "HibernationSeconds", 60, new ConfigDescription("How long a fallen Bearborn sleeps.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(5, 600), new object[1] { val }));
			RunStaminaDrain = c.Bind<float>("5 - Riding", "RunStaminaDrain", 1f, new ConfigDescription("Mount stamina a running bear uses per second (halved at full riding skill, like the lox).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 20f), new object[1] { val }));
			ClawStamina = c.Bind<float>("5 - Riding", "ClawStamina", 10f, new ConfigDescription("Mount stamina for a claw strike or bite (attack button).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), new object[1] { val }));
			SlamStamina = c.Bind<float>("5 - Riding", "SlamStamina", 25f, new ConfigDescription("Mount stamina for the slam (secondary attack button): both paws on the ground, hitting everything around.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), new object[1] { val }));
			LeapStamina = c.Bind<float>("5 - Riding", "LeapStamina", 15f, new ConfigDescription("Mount stamina for a leap (jump button).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), new object[1] { val }));
			LeapUp = c.Bind<float>("5 - Riding", "LeapUp", 6f, new ConfigDescription("Upward push of a leap in m/s (6 clears about 1 m; the bear's own jump is 10).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 20f), new object[1] { val }));
			LeapForward = c.Bind<float>("5 - Riding", "LeapForward", 5f, new ConfigDescription("Forward push of a leap in m/s.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 20f), new object[1] { val }));
			ArmorScale = c.Bind<float>("6 - Strength", "ArmorScale", 1f, new ConfigDescription("Multiplies the armour of all barding and war harnesses.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 5f), new object[1] { val }));
			HealthScale = c.Bind<float>("6 - Strength", "HealthScale", 1f, new ConfigDescription("Multiplies the extra health of all barding and war harnesses.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 5f), new object[1] { val }));
			for (int i = 0; i < 5; i++)
			{
				Stations[i] = c.Bind<string>("7 - Stations", "Quality" + (i + 1), DefaultStations[i], new ConfigDescription($"Crafting station for quality {i + 1} ({Biomes[i]}), as prefab:level. " + ((i == 0) ? "Quality 1 is crafted here." : $"The upgrade to quality {i + 1} is done here.") + ((i == 3) ? " War harnesses are bound here." : ""), (AcceptableValueBase)null, new object[1] { val }));
			}
			foreach (KeyValuePair<TackKind, string[]> defaultRecipe in DefaultRecipes)
			{
				ConfigEntry<string>[] array = new ConfigEntry<string>[5];
				for (int j = 0; j < 5; j++)
				{
					array[j] = c.Bind<string>("8 - Recipes", defaultRecipe.Key.ToString() + "Q" + (j + 1), defaultRecipe.Value[j], new ConfigDescription(((j == 0) ? "Cost to craft the " : $"Cost to upgrade to quality {j + 1}: the ") + Lang.KindName(defaultRecipe.Key) + ", \"Item:amount,Item:amount\".", (AcceptableValueBase)null, new object[1] { val }));
				}
				Recipes[defaultRecipe.Key] = array;
			}
			ConfigEntry<string> val2 = c.Bind<string>("8 - Recipes", "WarHarnessQ4", "LinenThread:10,JuteBlue:4,BlackMetal:4", new ConfigDescription("Cost to bind a war harness, on top of a saddle, a barding and saddlebags of quality 4 or better (the harness takes the quality all three reach).", (AcceptableValueBase)null, new object[1] { val }));
			ConfigEntry<string> val3 = c.Bind<string>("8 - Recipes", "WarHarnessQ5", "FlametalNew:8,AskHide:6,MorgenSinew:2", new ConfigDescription("Cost to upgrade a war harness to quality 5.", (AcceptableValueBase)null, new object[1] { val }));
			Recipes[TackKind.LightWarHarness] = new ConfigEntry<string>[5] { null, null, null, val2, val3 };
			Recipes[TackKind.HeavyWarHarness] = Recipes[TackKind.LightWarHarness];
			ConfigEntry<float>[] array2 = new ConfigEntry<float>[6] { ArmorScale, HealthScale, BearbornMaxGrowth, BearbornHealthPerLevel, BearbornDamagePerLevel, BearbornXpScale };
			for (int k = 0; k < array2.Length; k++)
			{
				array2[k].SettingChanged += delegate
				{
					Retune();
				};
			}
			Retune();
			ShowHints = c.Bind<bool>("9 - Client", "ShowRidingHints", true, "Show the bear's riding keys (claws, slam, leap, dismount) as a message when you mount.");
		}

		internal static void Retune()
		{
			Current = new Tuning
			{
				ArmorScale = (ArmorScale?.Value ?? 1f),
				HealthScale = (HealthScale?.Value ?? 1f)
			};
			Born = new BornTuning
			{
				MaxGrowth = (BearbornMaxGrowth?.Value ?? 0.3f),
				HealthPerLevel = (BearbornHealthPerLevel?.Value ?? 0.1f),
				DamagePerLevel = (BearbornDamagePerLevel?.Value ?? 0.05f),
				XpScale = (BearbornXpScale?.Value ?? 1f)
			};
		}
	}
	public static class Items
	{
		[HarmonyPatch(typeof(ItemData), "GetIcon")]
		private static class IconPerQuality
		{
			private static void Postfix(ItemData __instance, ref Sprite __result)
			{
				TackKind tackKind = KindOf(__instance);
				if (tackKind != TackKind.None)
				{
					Sprite val = Icon(tackKind, __instance.m_quality);
					if ((Object)(object)val != (Object)null)
					{
						__result = val;
					}
				}
			}
		}

		[HarmonyPatch(typeof(ItemData), "GetTooltip", new Type[]
		{
			typeof(ItemData),
			typeof(int),
			typeof(bool),
			typeof(float),
			typeof(int),
			typeof(bool)
		})]
		private static class TackTooltip
		{
			private static void Postfix(ItemData item, int qualityLevel, bool crafting, ref string __result)
			{
				try
				{
					TackKind tackKind = KindOf(item);
					if (tackKind != TackKind.None)
					{
						int q = (TackRules.IsCombo(tackKind) ? Math.Max(qualityLevel, 4) : qualityLevel);
						__result = __result + "\n" + Describe(tackKind, q, crafting);
					}
				}
				catch (Exception ex)
				{
					BearRidingPlugin.Log.LogWarning((object)("Tooltip: " + ex.Message));
				}
			}
		}

		public static readonly TackKind[] Kinds = new TackKind[6]
		{
			TackKind.Saddle,
			TackKind.LightBarding,
			TackKind.HeavyBarding,
			TackKind.Saddlebags,
			TackKind.LightWarHarness,
			TackKind.HeavyWarHarness
		};

		private const string BasePrefab = "SaddleLox";

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

		private static readonly Dictionary<string, TackKind> ByToken = new Dictionary<string, TackKind>();

		private static readonly Dictionary<TackKind, Sprite[]> Icons = new Dictionary<TackKind, Sprite[]>();

		private static float Weight(TackKind k)
		{
			return k switch
			{
				TackKind.Saddle => 12f, 
				TackKind.LightBarding => 15f, 
				TackKind.HeavyBarding => 35f, 
				TackKind.Saddlebags => 8f, 
				TackKind.LightWarHarness => 30f, 
				_ => 50f, 
			};
		}

		public static string PrefabName(TackKind k)
		{
			return "BearRiding_" + k;
		}

		public static void Init()
		{
			PrefabManager.OnVanillaPrefabsAvailable += AddItems;
		}

		private static void AddItems()
		{
			try
			{
				TackKind[] kinds = Kinds;
				for (int i = 0; i < kinds.Length; i++)
				{
					AddItem(kinds[i]);
				}
			}
			catch (Exception ex)
			{
				BearRidingPlugin.Log.LogError((object)("Could not register the tack items: " + ex));
			}
			finally
			{
				PrefabManager.OnVanillaPrefabsAvailable -= AddItems;
			}
		}

		private static void AddItem(TackKind kind)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Expected O, but got Unknown
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			string text = "$" + Lang.Token(kind);
			Sprite[] array = (Sprite[])(object)new Sprite[5];
			bool num = GUIManager.IsHeadless();
			GameObject val = (GameObject)((!num) ? ((object)TackModel.BuildItem(kind, 1)) : ((object)new GameObject("BearRiding_Item_" + kind)));
			if (!num)
			{
				for (int i = 1; i <= 5; i++)
				{
					GameObject val2 = ((i == 1) ? val : TackModel.BuildItem(kind, i));
					array[i - 1] = RenderIcon(val2, kind);
					if (i > 1)
					{
						Object.DestroyImmediate((Object)(object)val2);
					}
				}
			}
			Icons[kind] = array;
			CustomItem val3 = new CustomItem(PrefabName(kind), "SaddleLox");
			if ((Object)(object)val3.ItemPrefab == (Object)null)
			{
				Object.Destroy((Object)(object)val);
				BearRidingPlugin.Log.LogError((object)string.Format("Cloning {0} for {1} failed.", "SaddleLox", kind));
				return;
			}
			Reskin(val3.ItemPrefab, val);
			SharedData shared = val3.ItemDrop.m_itemData.m_shared;
			shared.m_name = text;
			shared.m_description = text + "_desc";
			shared.m_itemType = (ItemType)16;
			shared.m_maxStackSize = 1;
			shared.m_maxQuality = 5;
			shared.m_weight = Weight(kind);
			shared.m_useDurability = false;
			shared.m_canBeReparied = false;
			shared.m_teleportable = true;
			shared.m_value = 0;
			shared.m_scaleByQuality = 0f;
			shared.m_questItem = false;
			if ((Object)(object)array[0] != (Object)null)
			{
				shared.m_icons = (Sprite[])(object)new Sprite[1] { array[0] };
			}
			ItemManager.Instance.AddItem(val3);
			Prefabs[kind] = val3.ItemPrefab;
			ByToken[text] = kind;
		}

		public static GameObject Prefab(TackKind k)
		{
			if (!Prefabs.TryGetValue(k, out var value))
			{
				return null;
			}
			return value;
		}

		public static TackKind KindOf(ItemData item)
		{
			if (item?.m_shared == null)
			{
				return TackKind.None;
			}
			if (!ByToken.TryGetValue(item.m_shared.m_name, out var value))
			{
				return TackKind.None;
			}
			return value;
		}

		public static Sprite Icon(TackKind k, int quality)
		{
			if (!Icons.TryGetValue(k, out var value))
			{
				return null;
			}
			return value[TackRules.ClampQuality(quality) - 1];
		}

		private static void Reskin(GameObject prefab, GameObject visual)
		{
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//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_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			Transform transform = prefab.transform;
			for (int num = transform.childCount - 1; num >= 0; num--)
			{
				Object.DestroyImmediate((Object)(object)((Component)transform.GetChild(num)).gameObject);
			}
			Collider[] components = prefab.GetComponents<Collider>();
			for (int i = 0; i < components.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)components[i]);
			}
			MeshRenderer component = prefab.GetComponent<MeshRenderer>();
			if ((Object)(object)component != (Object)null)
			{
				Object.DestroyImmediate((Object)(object)component);
			}
			MeshFilter component2 = prefab.GetComponent<MeshFilter>();
			if ((Object)(object)component2 != (Object)null)
			{
				Object.DestroyImmediate((Object)(object)component2);
			}
			((Object)visual).name = "model";
			visual.transform.SetParent(transform, false);
			visual.transform.localPosition = Vector3.zero;
			visual.transform.localRotation = Quaternion.identity;
			Bounds val = LocalBounds(transform, visual);
			BoxCollider obj = prefab.AddComponent<BoxCollider>();
			obj.center = ((Bounds)(ref val)).center;
			obj.size = Vector3.Max(((Bounds)(ref val)).size, new Vector3(0.15f, 0.1f, 0.15f));
			SetLayer(visual, prefab.layer);
		}

		private static Bounds LocalBounds(Transform root, GameObject visual)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: 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_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			bool flag = false;
			Bounds result = default(Bounds);
			((Bounds)(ref result))..ctor(Vector3.zero, Vector3.zero);
			MeshFilter[] componentsInChildren = visual.GetComponentsInChildren<MeshFilter>(true);
			foreach (MeshFilter val in componentsInChildren)
			{
				if ((Object)(object)val.sharedMesh == (Object)null)
				{
					continue;
				}
				Bounds bounds = val.sharedMesh.bounds;
				Matrix4x4 val2 = root.worldToLocalMatrix * ((Component)val).transform.localToWorldMatrix;
				for (int j = 0; j < 8; j++)
				{
					Vector3 val3 = ((Bounds)(ref bounds)).center + Vector3.Scale(((Bounds)(ref bounds)).extents, new Vector3((float)(((j & 1) != 0) ? 1 : (-1)), (float)(((j & 2) != 0) ? 1 : (-1)), (float)(((j & 4) != 0) ? 1 : (-1))));
					Vector3 val4 = ((Matrix4x4)(ref val2)).MultiplyPoint3x4(val3);
					if (!flag)
					{
						((Bounds)(ref result))..ctor(val4, Vector3.zero);
						flag = true;
					}
					else
					{
						((Bounds)(ref result)).Encapsulate(val4);
					}
				}
			}
			if (!flag)
			{
				return new Bounds(Vector3.zero, new Vector3(0.4f, 0.3f, 0.4f));
			}
			return result;
		}

		private static void SetLayer(GameObject go, int layer)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			go.layer = layer;
			foreach (Transform item in go.transform)
			{
				SetLayer(((Component)item).gameObject, layer);
			}
		}

		internal static Sprite RenderIcon(GameObject visual, TackKind kind, int size = 128)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Expected O, but got Unknown
			GameObject val = null;
			try
			{
				val = Object.Instantiate<GameObject>(visual);
				val.transform.position = Vector3.zero;
				val.transform.rotation = Quaternion.identity;
				return RenderManager.Instance.Render(new RenderRequest(val)
				{
					Rotation = Quaternion.Euler(22f, 140f, 0f),
					Width = size,
					Height = size,
					ParticleSimulationTime = -1f,
					UseCache = false
				});
			}
			catch (Exception ex)
			{
				BearRidingPlugin.Log.LogWarning((object)$"Icon for {kind} failed: {ex.Message}");
				return null;
			}
			finally
			{
				if ((Object)(object)val != (Object)null)
				{
					Object.DestroyImmediate((Object)(object)val);
				}
			}
		}

		internal static string Describe(TackKind k, int q, bool crafting)
		{
			TackStats tackStats = TackRules.For(k, q, Cfg.Current);
			StringBuilder stringBuilder = new StringBuilder();
			if (tackStats.Rideable)
			{
				stringBuilder.Append('\n').Append(Lang.T("br_tt_ride"));
				stringBuilder.Append('\n').Append(Lang.T("br_tt_stamina", Mathf.RoundToInt(tackStats.MountStamina)));
			}
			if (tackStats.Armor > 0f)
			{
				stringBuilder.Append('\n').Append(Lang.T("br_tt_armor", Mathf.RoundToInt(tackStats.Armor)));
			}
			if (tackStats.HealthBonus > 0f)
			{
				stringBuilder.Append('\n').Append(Lang.T("br_tt_health", Mathf.RoundToInt(tackStats.HealthBonus * 100f)));
			}
			if (tackStats.SpeedModifier != 0f)
			{
				stringBuilder.Append('\n').Append(Lang.T("br_tt_speed", Mathf.RoundToInt(tackStats.SpeedModifier * 100f)));
			}
			if (tackStats.FireResistant)
			{
				stringBuilder.Append('\n').Append(Lang.T("br_tt_fire"));
			}
			if (tackStats.BagSlots > 0)
			{
				stringBuilder.Append('\n').Append(Lang.T("br_tt_bags", tackStats.BagSlots));
			}
			if (TackRules.IsCombo(k))
			{
				stringBuilder.Append("\n\n").Append(Lang.T("br_tt_bind", Lang.L("$" + Lang.Token(TackRules.BardingPart(k)))));
			}
			stringBuilder.Append("\n\n").Append(Lang.T("br_tt_use"));
			if (q < 5)
			{
				string text = Recipes.StationName(q + 1);
				if (!string.IsNullOrEmpty(text))
				{
					stringBuilder.Append('\n').Append(Lang.T("br_tt_next", Lang.L(text)));
				}
			}
			return stringBuilder.ToString();
		}
	}
	public static class Lang
	{
		private static readonly (TackKind kind, string token, string en, string de, string descEn, string descDe)[] Pieces = new(TackKind, string, string, string, string, string)[6]
		{
			(TackKind.Saddle, "br_saddle", "Bear Saddle", "Bärensattel", "A broad riding saddle cut to a bear's back, with a wide girth and long stirrups. Put it on a tame bear and ride it.", "Ein breiter Reitsattel, auf den Rücken eines Bären zugeschnitten, mit breitem Bauchgurt und langen Steigbügeln. Leg ihn einem zahmen Bären auf und reite ihn."),
			(TackKind.LightBarding, "br_barding_light", "Light Bear Barding", "Leichter Bärenharnisch", "A padded coat with metal studs over back, flanks and chest. More armour and health, and the bear stays as fast as ever.", "Ein gepolsterter Rock mit Metallnieten über Rücken, Flanken und Brust. Mehr Rüstung und Leben, und der Bär bleibt so schnell wie zuvor."),
			(TackKind.HeavyBarding, "br_barding_heavy", "Heavy Bear Barding", "Schwerer Bärenharnisch", "Overlapping plates over neck, hump and back, and a plate for the brow. Much more armour and health, but the bear is slower.", "Überlappende Platten über Nacken, Buckel und Rücken und ein Stirnschild. Viel mehr Rüstung und Leben, aber der Bär wird langsamer."),
			(TackKind.Saddlebags, "br_bags", "Bear Saddlebags", "Bären-Satteltaschen", "Two big saddlebags on a strap across the rump. A bear that wears them carries your load.", "Zwei große Satteltaschen an einem Gurt über der Kruppe. Ein Bär, der sie trägt, schleppt deine Last."),
			(TackKind.LightWarHarness, "br_harness_light", "Light Bear War Harness", "Leichtes Bären-Kriegsgeschirr", "Saddle, light barding and saddlebags bound into one harness: ride, fight and carry at once.", "Sattel, leichter Harnisch und Satteltaschen zu einem Geschirr verbunden: reiten, kämpfen und tragen zugleich."),
			(TackKind.HeavyWarHarness, "br_harness_heavy", "Heavy Bear War Harness", "Schweres Bären-Kriegsgeschirr", "Saddle, heavy barding and saddlebags bound into one harness: ride, fight and carry at once, armoured like a fortress.", "Sattel, schwerer Harnisch und Satteltaschen zu einem Geschirr verbunden: reiten, kämpfen und tragen zugleich, gepanzert wie eine Festung.")
		};

		private static readonly (string key, string en, string de)[] Texts = new(string, string, string)[40]
		{
			("br_wears", "Wears: {0}", "Trägt: {0}"),
			("br_quality", "quality {0}", "Stufe {0}"),
			("br_takeoff", "Take off {0}", "{0} abnehmen"),
			("br_open_bags", "Open the saddlebags", "Satteltaschen öffnen"),
			("br_bags_hover", "Saddlebags ({0}/{1})", "Satteltaschen ({0}/{1})"),
			("br_ride", "Ride", "Reiten"),
			("br_msg_on", "{0} now wears the {1}.", "{0} trägt jetzt: {1}."),
			("br_msg_already", "{0} already wears the {1}. Take it off first.", "{0} trägt schon: {1}. Erst abnehmen."),
			("br_msg_wild", "Only a tame bear lets you put tack on it.", "Nur ein zahmer Bär lässt sich etwas anlegen."),
			("br_msg_notbear", "The {0} only fits a bear.", "{0}: passt nur einem Bären."),
			("br_msg_cub", "The cub is too small for that. Wait until it is grown.", "Das Junge ist noch zu klein dafür. Warte, bis es ausgewachsen ist."),
			("br_msg_off", "You take the {0} off.", "Abgenommen: {0}."),
			("br_msg_bags_full", "Empty the saddlebags first.", "Leere zuerst die Satteltaschen."),
			("br_msg_bags_open", "Someone has the saddlebags open.", "Jemand hat die Satteltaschen offen."),
			("br_msg_ridden", "Someone is riding this bear.", "Jemand reitet diesen Bären."),
			("br_msg_tired", "{0} is out of breath.", "{0} ist außer Atem."),
			("br_msg_sleeping", "{0} is sleeping off its wounds.", "{0} schläft seine Wunden aus."),
			("br_hint", "Claws [<color=yellow><b>$KEY_Attack</b></color>]  Slam [<color=yellow><b>$KEY_SecondaryAttack</b></color>]  Leap [<color=yellow><b>$KEY_Jump</b></color>]  Dismount [<color=yellow><b>$KEY_Use</b></color>]", "Prankenhieb [<color=yellow><b>$KEY_Attack</b></color>]  Schmettern [<color=yellow><b>$KEY_SecondaryAttack</b></color>]  Satz [<color=yellow><b>$KEY_Jump</b></color>]  Absteigen [<color=yellow><b>$KEY_Use</b></color>]"),
			("br_tt_ride", "Lets you ride the bear", "Macht den Bären reitbar"),
			("br_tt_stamina", "Mount stamina: <color=orange>{0}</color>", "Ausdauer des Reittiers: <color=orange>{0}</color>"),
			("br_tt_armor", "Bear armour: <color=orange>{0}</color>", "Rüstung des Bären: <color=orange>{0}</color>"),
			("br_tt_health", "Bear health: <color=orange>+{0} %</color>", "Leben des Bären: <color=orange>+{0} %</color>"),
			("br_tt_speed", "Bear speed: <color=orange>{0} %</color>", "Tempo des Bären: <color=orange>{0} %</color>"),
			("br_tt_fire", "Resistant to fire", "Widerstandsfähig gegen Feuer"),
			("br_tt_bags", "Saddlebags: <color=orange>{0}</color> slots", "Satteltaschen: <color=orange>{0}</color> Plätze"),
			("br_tt_use", "Use it on a tame bear to put it on. A bear wears one piece of tack at a time.", "Auf einen zahmen Bären anwenden, um es anzulegen. Ein Bär trägt immer nur ein Stück Geschirr."),
			("br_tt_bind", "Bound from a saddle, a {0} and saddlebags of quality 4 or better. It takes the quality all three reach.", "Gebunden aus Sattel, {0} und Satteltaschen ab Stufe 4. Es erhält die Stufe, die alle drei erreichen."),
			("br_tt_next", "Next quality at: {0}", "Nächste Stufe an: {0}"),
			("br_cub", "Bear Cub", "Bärenjunges"),
			("br_bearborn", "Bearborn", "Bärenborn"),
			("br_born_line", "Bearborn · level {0} · {1}", "Bärenborn · Stufe {0} · {1}"),
			("br_born_xp", "{0}/{1} XP", "{0}/{1} EP"),
			("br_born_max", "fully grown", "ausgewachsen"),
			("br_born_sleep", "Sleeping off its wounds ({0} s)", "Schläft seine Wunden aus ({0} s)"),
			("br_pelt_0", "frost pelt", "Frostfell"),
			("br_pelt_1", "night pelt", "Nachtfell"),
			("br_pelt_2", "honey pelt", "Honigfell"),
			("br_msg_levelup", "{0} grows stronger: level {1}.", "{0} wird stärker: Stufe {1}."),
			("br_msg_hibernate", "{0} falls and sleeps off its wounds.", "{0} fällt und schläft seine Wunden aus."),
			("br_msg_wakes", "{0} wakes up.", "{0} erwacht.")
		};

		public static string Token(TackKind k)
		{
			(TackKind, string, string, string, string, string)[] pieces = Pieces;
			for (int i = 0; i < pieces.Length; i++)
			{
				(TackKind, string, string, string, string, string) tuple = pieces[i];
				if (tuple.Item1 == k)
				{
					return tuple.Item2;
				}
			}
			return "br_none";
		}

		public static string KindName(TackKind k)
		{
			(TackKind, string, string, string, string, string)[] pieces = Pieces;
			for (int i = 0; i < pieces.Length; i++)
			{
				(TackKind, string, string, string, string, string) tuple = pieces[i];
				if (tuple.Item1 == k)
				{
					return tuple.Item3.ToLowerInvariant();
				}
			}
			return k.ToString();
		}

		public static void Register()
		{
			CustomLocalization localization = LocalizationManager.Instance.GetLocalization();
			Dictionary<string, string> dictionary = new Dictionary<string, string>();
			Dictionary<string, string> dictionary2 = new Dictionary<string, string>();
			(string, string, string)[] texts = Texts;
			for (int i = 0; i < texts.Length; i++)
			{
				(string, string, string) tuple = texts[i];
				string item = tuple.Item1;
				string item2 = tuple.Item2;
				string item3 = tuple.Item3;
				dictionary[item] = item2;
				dictionary2[item] = item3;
			}
			(TackKind, string, string, string, string, string)[] pieces = Pieces;
			for (int i = 0; i < pieces.Length; i++)
			{
				(TackKind, string, string, string, string, string) tuple2 = pieces[i];
				dictionary[tuple2.Item2] = tuple2.Item3;
				dictionary2[tuple2.Item2] = tuple2.Item4;
				dictionary[tuple2.Item2 + "_desc"] = tuple2.Item5;
				dictionary2[tuple2.Item2 + "_desc"] = tuple2.Item6;
			}
			string text = "English";
			localization.AddTranslation(ref text, dictionary);
			text = "German";
			localization.AddTranslation(ref text, dictionary2);
		}

		public static string T(string token, params object[] args)
		{
			string text = ((Localization.instance != null) ? Localization.instance.Localize("$" + token) : token);
			if (args == null || args.Length == 0)
			{
				return text;
			}
			try
			{
				return string.Format(text, args);
			}
			catch (FormatException)
			{
				return text;
			}
		}

		public static string L(string token)
		{
			if (Localization.instance == null)
			{
				return token;
			}
			return Localization.instance.Localize(token);
		}

		public static string Name(TackKind k, int quality)
		{
			return L("$" + Token(k)) + " (" + T("br_quality", TackRules.ClampQuality(quality)) + ")";
		}
	}
	[BepInPlugin("zap.bearriding", "Bear Riding", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	public class BearRidingPlugin : BaseUnityPlugin
	{
		public const string PluginGuid = "zap.bearriding";

		public const string PluginName = "Bear Riding";

		public const string PluginVersion = "1.0.0";

		public const string BetterRidingGuid = "Ygg.BetterRiding";

		public const string WolfRidingGuid = "zap.wolfriding";

		private Harmony _harmony;

		public static BearRidingPlugin Instance { get; private set; }

		public static string PluginDir { get; private set; }

		public static ManualLogSource Log { get; private set; }

		public static string AssetPath(string fileName)
		{
			return Path.Combine(PluginDir ?? "", "Assets", fileName);
		}

		private void Awake()
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Expected O, but got Unknown
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			PluginDir = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
			Cfg.Bind(((BaseUnityPlugin)this).Config);
			Lang.Register();
			Taming.Init();
			Items.Init();
			Recipes.Init();
			_harmony = new Harmony("zap.bearriding");
			_harmony.PatchAll(typeof(BearRidingPlugin).Assembly);
			Patches.PatchSoftDependencies(_harmony);
			SelfTest.TryStart(((Component)this).gameObject);
		}

		private void OnDestroy()
		{
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}
	}
	public static class Recipes
	{
		public sealed class FixedRequirement : Requirement
		{
			public int Fixed;

			public TackKind Part;
		}

		private sealed class Info
		{
			public TackKind Kind;

			public int Makes;

			public bool Bind
			{
				get
				{
					if (TackRules.IsCombo(Kind))
					{
						return Makes == 4;
					}
					return false;
				}
			}
		}

		[HarmonyPatch(typeof(ObjectDB), "Awake")]
		private static class AddToObjectDB
		{
			[HarmonyPriority(0)]
			private static void Postfix()
			{
				Apply();
			}
		}

		[HarmonyPatch(typeof(Requirement), "GetAmount")]
		private static class FixedAmount
		{
			private static bool Prefix(Requirement __instance, ref int __result)
			{
				if (!(__instance is FixedRequirement fixedRequirement))
				{
					return true;
				}
				__result = fixedRequirement.Fixed;
				return false;
			}
		}

		[HarmonyPatch(typeof(Recipe), "GetRequiredStationLevel")]
		private static class StationLevel
		{
			private static bool Prefix(Recipe __instance, ref int __result)
			{
				if (!IsOurs(__instance, out var _))
				{
					return true;
				}
				__result = Mathf.Max(1, __instance.m_minStationLevel);
				return false;
			}
		}

		[HarmonyPatch(typeof(InventoryGui), "AddRecipeToList")]
		private static class OnlyTheNextQuality
		{
			private static bool Prefix(Recipe recipe, ItemData item)
			{
				if (item == null || !IsOurs(recipe, out var info))
				{
					return true;
				}
				if (!info.Bind)
				{
					return info.Makes == item.m_quality + 1;
				}
				return false;
			}
		}

		[HarmonyPatch(typeof(Player), "HaveRequirementItems")]
		private static class BindNeedsGoodParts
		{
			private static void Postfix(Player __instance, Recipe piece, bool discover, ref bool __result)
			{
				if (!(!__result || discover) && IsOurs(piece, out var info) && info.Bind)
				{
					__result = BindQuality(((Humanoid)__instance).GetInventory(), info.Kind) > 0;
				}
			}
		}

		[HarmonyPatch(typeof(InventoryGui), "DoCrafting")]
		private static class BindStart
		{
			private static void Prefix(InventoryGui __instance, Player player)
			{
				_binding = 0;
				if (__instance.m_craftUpgradeItem == null && IsOurs(__instance.m_craftRecipe, out var info) && info.Bind)
				{
					__instance.m_multiCrafting = false;
					_binding = Math.Max(BindQuality(((Humanoid)player).GetInventory(), info.Kind), 4);
				}
			}

			private static void Finalizer()
			{
				_binding = 0;
			}
		}

		[HarmonyPatch(typeof(Inventory), "AddItem", new Type[]
		{
			typeof(string),
			typeof(int),
			typeof(int),
			typeof(int),
			typeof(long),
			typeof(string),
			typeof(Vector2i),
			typeof(bool),
			typeof(bool),
			typeof(bool)
		})]
		private static class BindQualityOut
		{
			private static void Prefix(string name, ref int quality)
			{
				if (_binding > 0 && (name == Items.PrefabName(TackKind.LightWarHarness) || name == Items.PrefabName(TackKind.HeavyWarHarness)))
				{
					quality = _binding;
				}
			}
		}

		[HarmonyPatch(typeof(Player), "ConsumeResources")]
		private static class BindTakesParts
		{
			private static bool Prefix(Player __instance, Requirement[] requirements)
			{
				if (_binding <= 0 || requirements == null || !requirements.Any((Requirement r) => r is FixedRequirement fixedRequirement2 && fixedRequirement2.Part != TackKind.None))
				{
					return true;
				}
				Inventory inventory = ((Humanoid)__instance).GetInventory();
				foreach (Requirement val in requirements)
				{
					if ((Object)(object)val.m_resItem == (Object)null)
					{
						continue;
					}
					if (val is FixedRequirement { Part: not TackKind.None })
					{
						string name = val.m_resItem.m_itemData.m_shared.m_name;
						List<ItemData> list = (from i in inventory.GetAllItems()
							where i.m_shared.m_name == name
							select i).ToList();
						int num2 = TackRules.PickPart(list.Select((ItemData i) => i.m_quality).ToList(), _binding);
						if (num2 >= 0)
						{
							inventory.RemoveItem(list[num2]);
						}
					}
					else
					{
						inventory.RemoveItem(val.m_resItem.m_itemData.m_shared.m_name, val.GetAmount(1), -1, true);
					}
				}
				return false;
			}
		}

		private static readonly Dictionary<Recipe, Info> Ours = new Dictionary<Recipe, Info>();

		private static int _binding;

		private static readonly Dictionary<(TackKind, int), Recipe> Pool = new Dictionary<(TackKind, int), Recipe>();

		private static readonly string[] StationNames = new string[5];

		public static void Init()
		{
			foreach (ConfigEntry<string>[] value in Cfg.Recipes.Values)
			{
				foreach (ConfigEntry<string> val in value)
				{
					if (val != null)
					{
						val.SettingChanged += delegate
						{
							Apply();
						};
					}
				}
			}
			ConfigEntry<string>[] current = Cfg.Stations;
			for (int i = 0; i < current.Length; i++)
			{
				current[i].SettingChanged += delegate
				{
					Apply();
				};
			}
			SynchronizationManager.OnConfigurationSynchronized += delegate
			{
				Apply();
			};
		}

		public static void Apply()
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			ObjectDB instance = ObjectDB.instance;
			if ((Object)(object)instance == (Object)null || instance.m_items == null || instance.m_items.Count == 0)
			{
				return;
			}
			Scene activeScene = SceneManager.GetActiveScene();
			if (((Scene)(ref activeScene)).name != "main")
			{
				return;
			}
			try
			{
				for (int i = 1; i <= 5; i++)
				{
					int level;
					CraftingStation val = StationFor(i, out level);
					StationNames[i - 1] = (((Object)(object)val != (Object)null) ? val.m_name : "");
				}
				TackKind[] kinds = Items.Kinds;
				foreach (TackKind tackKind in kinds)
				{
					if (!Cfg.Recipes.TryGetValue(tackKind, out var value))
					{
						continue;
					}
					for (int j = 1; j <= 5; j++)
					{
						if (value[j - 1] != null)
						{
							Recipe val2 = Fill(instance, tackKind, j, value[j - 1]);
							if ((Object)(object)val2 != (Object)null && !instance.m_recipes.Contains(val2))
							{
								instance.m_recipes.Add(val2);
							}
						}
					}
				}
			}
			catch (Exception ex)
			{
				BearRidingPlugin.Log.LogError((object)("Could not set up the tack recipes: " + ex));
			}
		}

		private static Recipe Fill(ObjectDB db, TackKind kind, int makes, ConfigEntry<string> costEntry)
		{
			GameObject val = Items.Prefab(kind);
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			Info info = new Info
			{
				Kind = kind,
				Makes = makes
			};
			List<Requirement> list = new List<Requirement>();
			if (info.Bind)
			{
				TackKind[] array = TackRules.Parts(kind);
				foreach (TackKind tackKind in array)
				{
					GameObject val2 = Items.Prefab(tackKind);
					if ((Object)(object)val2 != (Object)null)
					{
						list.Add((Requirement)(object)new FixedRequirement
						{
							m_resItem = val2.GetComponent<ItemDrop>(),
							m_amount = 1,
							Fixed = 1,
							Part = tackKind,
							m_recover = false
						});
					}
				}
			}
			List<string> bad;
			List<Requirement> collection = Costs(db, costEntry.Value, out bad);
			if (bad.Count > 0)
			{
				BearRidingPlugin.Log.LogWarning((object)string.Format("Recipe {0}: unknown entries {1}; using the default \"{2}\".", ((ConfigEntryBase)costEntry).Definition.Key, string.Join(", ", bad), ((ConfigEntryBase)costEntry).DefaultValue));
				collection = Costs(db, (string)((ConfigEntryBase)costEntry).DefaultValue, out var _);
			}
			list.AddRange(collection);
			if (!Pool.TryGetValue((kind, makes), out var value) || (Object)(object)value == (Object)null)
			{
				value = ScriptableObject.CreateInstance<Recipe>();
				((Object)value).name = $"Recipe_BearRiding_{kind}_Q{makes}";
				((Object)value).hideFlags = (HideFlags)32;
				Pool[(kind, makes)] = value;
			}
			int level;
			CraftingStation craftingStation = StationFor(makes, out level);
			value.m_item = val.GetComponent<ItemDrop>();
			value.m_amount = 1;
			value.m_enabled = true;
			value.m_craftingStation = craftingStation;
			value.m_repairStation = null;
			value.m_minStationLevel = level;
			value.m_resources = list.ToArray();
			value.m_noCraftOnlyUpgrade = makes > 1 && !info.Bind;
			value.m_listSortWeight = (int)(100 + kind);
			Ours[value] = info;
			return value;
		}

		private static List<Requirement> Costs(ObjectDB db, string cost, out List<string> bad)
		{
			bad = new List<string>();
			List<Requirement> list = new List<Requirement>();
			foreach (KeyValuePair<string, int> item in RecipeText.Parse(cost, bad))
			{
				GameObject itemPrefab = db.GetItemPrefab(item.Key);
				if ((Object)(object)itemPrefab == (Object)null)
				{
					bad.Add(item.Key);
					continue;
				}
				list.Add((Requirement)(object)new FixedRequirement
				{
					m_resItem = itemPrefab.GetComponent<ItemDrop>(),
					m_amount = item.Value,
					Fixed = item.Value,
					m_amountPerLevel = 0
				});
			}
			return list;
		}

		private static CraftingStation StationFor(int quality, out int level)
		{
			ConfigEntry<string> val = Cfg.Stations[quality - 1];
			KeyValuePair<string, int> keyValuePair = RecipeText.Station(val.Value);
			level = keyValuePair.Value;
			CraftingStation val2 = Station(keyValuePair.Key);
			if ((Object)(object)val2 != (Object)null || string.IsNullOrEmpty(keyValuePair.Key))
			{
				return val2;
			}
			KeyValuePair<string, int> keyValuePair2 = RecipeText.Station((string)((ConfigEntryBase)val).DefaultValue);
			BearRidingPlugin.Log.LogWarning((object)$"No crafting station '{keyValuePair.Key}' for quality {quality}; using {keyValuePair2.Key}:{keyValuePair2.Value}.");
			level = keyValuePair2.Value;
			return Station(keyValuePair2.Key);
		}

		private static CraftingStation Station(string prefab)
		{
			if (string.IsNullOrEmpty(prefab))
			{
				return null;
			}
			GameObject val = null;
			try
			{
				val = PrefabManager.Instance.GetPrefab(prefab);
			}
			catch (Exception)
			{
			}
			if (!((Object)(object)val != (Object)null))
			{
				return null;
			}
			return val.GetComponent<CraftingStation>();
		}

		public static string StationName(int quality)
		{
			if (quality < 1 || quality > 5)
			{
				return "";
			}
			return StationNames[quality - 1] ?? "";
		}

		private static bool IsOurs(Recipe r, out Info info)
		{
			info = null;
			if ((Object)(object)r != (Object)null)
			{
				return Ours.TryGetValue(r, out info);
			}
			return false;
		}

		private static List<int> Qualities(Inventory inv, TackKind part)
		{
			List<int> list = new List<int>();
			GameObject val = Items.Prefab(part);
			if ((Object)(object)val == (Object)null || inv == null)
			{
				return list;
			}
			string name = val.GetComponent<ItemDrop>().m_itemData.m_shared.m_name;
			foreach (ItemData allItem in inv.GetAllItems())
			{
				if (allItem.m_shared.m_name == name)
				{
					list.Add(allItem.m_quality);
				}
			}
			return list;
		}

		internal static int BindQuality(Inventory inv, TackKind combo)
		{
			TackKind[] array = TackRules.Parts(combo);
			return TackRules.ComboQuality(Qualities(inv, array[0]), Qualities(inv, array[1]), Qualities(inv, array[2]));
		}
	}
}
namespace BearRiding.Visual
{
	internal static class BearShape
	{
		public const float SeatBack = -0.88f;

		public const float SeatFront = -0.06f;

		public const float SeatZ = -0.45f;

		public const float BagZ = -1.42f;

		public const string SeatBone = "Spine_02";

		public const string BagBone = "Hip";

		public const string ChestBone = "Chest";

		public const string NeckBone = "Neck";

		public const string HeadBone = "Head";

		public const float Axis = 0.62f;

		public const float S = 2f;

		public const float Belly = 1f;
	}
	internal sealed class RestBody
	{
		private static readonly Dictionary<Mesh, RestBody> Cache = new Dictionary<Mesh, RestBody>();

		public readonly Mesh Mesh;

		public readonly Matrix4x4 MeshToRoot;

		public readonly Matrix4x4 RootToMesh;

		public readonly Vector3[] MeshVerts;

		public readonly Vector3[] MeshNormals;

		public readonly Vector3[] Verts;

		public readonly Vector3[] Normals;

		public readonly Vector2[] Uvs;

		public readonly int[] Tris;

		public readonly BoneWeight[] Weights;

		public readonly Matrix4x4[] BindPoses;

		public readonly string[] BoneNames;

		private readonly float[] _top;

		private const float TopStep = 0.025f;

		private const float TopMin = -2.6f;

		private const float TopMax = 2.8f;

		private RestBody(SkinnedMeshRenderer smr, Transform root, bool rebuild)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: 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_015e: Unknown result type (might be due to invalid IL or missing references)
			//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_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			Mesh = smr.sharedMesh;
			MeshToRoot = root.worldToLocalMatrix * ((Component)smr).transform.localToWorldMatrix;
			RootToMesh = ((Matrix4x4)(ref MeshToRoot)).inverse;
			BindPoses = Mesh.bindposes;
			BoneNames = new string[smr.bones.Length];
			for (int i = 0; i < BoneNames.Length; i++)
			{
				BoneNames[i] = (((Object)(object)smr.bones[i] != (Object)null) ? ((Object)smr.bones[i]).name : "");
			}
			if (rebuild)
			{
				Rebuild(smr, out MeshVerts, out MeshNormals, out Uvs, out Tris, out Weights);
			}
			else
			{
				MeshVerts = Mesh.vertices;
				MeshNormals = Mesh.normals;
				Uvs = Mesh.uv;
				Tris = Mesh.triangles;
				Weights = Mesh.boneWeights;
			}
			Verts = (Vector3[])(object)new Vector3[MeshVerts.Length];
			Normals = (Vector3[])(object)new Vector3[MeshVerts.Length];
			Vector3 normal;
			for (int j = 0; j < Verts.Length; j++)
			{
				Verts[j] = ((Matrix4x4)(ref MeshToRoot)).MultiplyPoint3x4(MeshVerts[j]);
				Vector3[] normals = Normals;
				int num = j;
				normal = ((Matrix4x4)(ref MeshToRoot)).MultiplyVector((MeshNormals.Length > j) ? MeshNormals[j] : Vector3.up);
				normals[num] = ((Vector3)(ref normal)).normalized;
			}
			_top = new float[216];
			for (int k = 0; k < _top.Length; k++)
			{
				float num2 = -2.6f + (float)k * 0.025f;
				_top[k] = (Cast(new Vector3(0f, 6f, num2), Vector3.down, out var hit, out normal, 8f) ? hit.y : float.NaN);
			}
		}

		private static void Rebuild(SkinnedMeshRenderer smr, out Vector3[] verts, out Vector3[] normals, out Vector2[] uvs, out int[] tris, out BoneWeight[] weights)
		{
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Expected O, but got Unknown
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Expected O, but got Unknown
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0566: Unknown result type (might be due to invalid IL or missing references)
			//IL_0579: Unknown result type (might be due to invalid IL or missing references)
			//IL_058c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: 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_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: 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_012d: 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_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: 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_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0224: Unknown result type (might be due to invalid IL or missing references)
			//IL_022b: Expected O, but got Unknown
			//IL_0231: Unknown result type (might be due to invalid IL or missing references)
			//IL_0238: Unknown result type (might be due to invalid IL or missing references)
			//IL_0269: Unknown result type (might be due to invalid IL or missing references)
			//IL_026e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0272: Unknown result type (might be due to invalid IL or missing references)
			//IL_0274: Unknown result type (might be due to invalid IL or missing references)
			//IL_0276: Unknown result type (might be due to invalid IL or missing references)
			//IL_042d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0447: Unknown result type (might be due to invalid IL or missing references)
			//IL_0449: Unknown result type (might be due to invalid IL or missing references)
			//IL_051e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0520: Unknown result type (might be due to invalid IL or missing references)
			//IL_029d: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0341: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0301: Unknown result type (might be due to invalid IL or missing references)
			//IL_0365: Unknown result type (might be due to invalid IL or missing references)
			//IL_0378: Unknown result type (might be due to invalid IL or missing references)
			Transform[] bones = smr.bones;
			Matrix4x4[] bindposes = smr.sharedMesh.bindposes;
			List<(Transform, Vector3, Quaternion, Vector3)> list = new List<(Transform, Vector3, Quaternion, Vector3)>();
			Transform[] array = bones;
			foreach (Transform val in array)
			{
				if ((Object)(object)val != (Object)null)
				{
					list.Add((val, val.localPosition, val.localRotation, val.localScale));
				}
			}
			Mesh val2 = new Mesh();
			Mesh val3 = new Mesh();
			try
			{
				Matrix4x4 localToWorldMatrix = ((Component)smr).transform.localToWorldMatrix;
				List<int> list2 = new List<int>();
				for (int j = 0; j < bones.Length; j++)
				{
					if ((Object)(object)bones[j] != (Object)null)
					{
						list2.Add(j);
					}
				}
				list2.Sort((int a, int b) => Depth(bones[a]).CompareTo(Depth(bones[b])));
				foreach (int item in list2)
				{
					Matrix4x4 val4 = localToWorldMatrix * ((Matrix4x4)(ref bindposes[item])).inverse;
					bones[item].position = Vector4.op_Implicit(((Matrix4x4)(ref val4)).GetColumn(3));
					bones[item].rotation = Quaternion.LookRotation(Vector4.op_Implicit(((Matrix4x4)(ref val4)).GetColumn(2)), Vector4.op_Implicit(((Matrix4x4)(ref val4)).GetColumn(1)));
				}
				smr.BakeMesh(val2, true);
				verts = val2.vertices;
				normals = val2.normals;
				uvs = val2.uv;
				tris = val2.triangles;
				List<(int, float)>[] array2 = new List<(int, float)>[verts.Length];
				for (int num = 0; num < array2.Length; num++)
				{
					array2[num] = new List<(int, float)>(4);
				}
				Matrix4x4 worldToLocalMatrix = ((Component)smr).transform.worldToLocalMatrix;
				Vector3 val5 = default(Vector3);
				((Vector3)(ref val5))..ctor(0.5f, 0f, 0f);
				Vector3 val6 = ((Matrix4x4)(ref worldToLocalMatrix)).MultiplyVector(val5);
				float sqrMagnitude = ((Vector3)(ref val6)).sqrMagnitude;
				for (int num2 = 0; num2 < bones.Length; num2++)
				{
					Transform val7 = bones[num2];
					if ((Object)(object)val7 == (Object)null)
					{
						continue;
					}
					List<(Transform, Vector3, Quaternion)> list3 = new List<(Transform, Vector3, Quaternion)>();
					foreach (Transform item2 in val7)
					{
						Transform val8 = item2;
						list3.Add((val8, val8.position, val8.rotation));
					}
					Vector3 position = val7.position;
					val7.position = position + val5;
					foreach (var item3 in list3)
					{
						item3.Item1.position = item3.Item2;
						item3.Item1.rotation = item3.Item3;
					}
					smr.BakeMesh(val3, true);
					Vector3[] vertices = val3.vertices;
					for (int num3 = 0; num3 < verts.Length && num3 < vertices.Length; num3++)
					{
						float num4 = Vector3.Dot(vertices[num3] - verts[num3], val6) / sqrMagnitude;
						if (num4 > 0.01f)
						{
							array2[num3].Add((num2, num4));
						}
					}
					val7.position = position;
					foreach (var item4 in list3)
					{
						item4.Item1.position = item4.Item2;
						item4.Item1.rotation = item4.Item3;
					}
				}
				weights = (BoneWeight[])(object)new BoneWeight[verts.Length];
				for (int num5 = 0; num5 < verts.Length; num5++)
				{
					List<(int, float)> list4 = array2[num5];
					list4.Sort(((int bone, float w) a, (int bone, float w) b) => b.w.CompareTo(a.w));
					int num6 = Math.Min(4, list4.Count);
					float num7 = 0f;
					for (int num8 = 0; num8 < num6; num8++)
					{
						num7 += list4[num8].Item2;
					}
					BoneWeight val9 = default(BoneWeight);
					((BoneWeight)(ref val9)).boneIndex0 = 0;
					((BoneWeight)(ref val9)).weight0 = 1f;
					BoneWeight val10 = val9;
					if (num7 > 0f)
					{
						((BoneWeight)(ref val10)).weight0 = 0f;
						for (int num9 = 0; num9 < num6; num9++)
						{
							float num10 = list4[num9].Item2 / num7;
							switch (num9)
							{
							case 0:
								((BoneWeight)(ref val10)).boneIndex0 = list4[num9].Item1;
								((BoneWeight)(ref val10)).weight0 = num10;
								break;
							case 1:
								((BoneWeight)(ref val10)).boneIndex1 = list4[num9].Item1;
								((BoneWeight)(ref val10)).weight1 = num10;
								break;
							case 2:
								((BoneWeight)(ref val10)).boneIndex2 = list4[num9].Item1;
								((BoneWeight)(ref val10)).weight2 = num10;
								break;
							default:
								((BoneWeight)(ref val10)).boneIndex3 = list4[num9].Item1;
								((BoneWeight)(ref val10)).weight3 = num10;
								break;
							}
						}
					}
					weights[num5] = val10;
				}
			}
			finally
			{
				foreach (var item5 in list)
				{
					if (!((Object)(object)item5.Item1 == (Object)null))
					{
						item5.Item1.localPosition = item5.Item2;
						item5.Item1.localRotation = item5.Item3;
						item5.Item1.localScale = item5.Item4;
					}
				}
				Object.Destroy((Object)(object)val2);
				Object.Destroy((Object)(object)val3);
			}
		}

		private static int Depth(Transform t)
		{
			int num = 0;
			Transform val = t;
			while ((Object)(object)val != (Object)null)
			{
				num++;
				val = val.parent;
			}
			return num;
		}

		public static RestBody For(SkinnedMeshRenderer smr, Transform root)
		{
			if ((Object)(object)smr == (Object)null || (Object)(object)smr.sharedMesh == (Object)null)
			{
				return null;
			}
			if (Cache.TryGetValue(smr.sharedMesh, out var value))
			{
				return value;
			}
			try
			{
				value = new RestBody(smr, root, !smr.sharedMesh.isReadable);
			}
			catch (Exception ex)
			{
				BearRidingPlugin.Log.LogWarning((object)("Could not read the body mesh: " + ex));
				value = null;
			}
			Cache[smr.sharedMesh] = value;
			return value;
		}

		public static RestBody OfPrefab(string prefabName, string renderer = null)
		{
			GameObject val = null;
			try
			{
				val = PrefabManager.Instance.GetPrefab(prefabName);
			}
			catch (Exception)
			{
			}
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			SkinnedMeshRenderer smr = null;
			if (renderer == null)
			{
				smr = BodyRenderer(val.transform);
			}
			else
			{
				SkinnedMeshRenderer[] componentsInChildren = val.GetComponentsInChildren<SkinnedMeshRenderer>(true);
				foreach (SkinnedMeshRenderer val2 in componentsInChildren)
				{
					if (((Object)val2).name == renderer)
					{
						smr = val2;
					}
				}
			}
			return For(smr, val.transform);
		}

		public static SkinnedMeshRenderer BodyRenderer(Transform root)
		{
			SkinnedMeshRenderer val = null;
			SkinnedMeshRenderer[] componentsInChildren = ((Component)root).GetComponentsInChildren<SkinnedMeshRenderer>(true);
			foreach (SkinnedMeshRenderer val2 in componentsInChildren)
			{
				if (!((Object)(object)val2.sharedMesh == (Object)null) && !((Object)val2).name.StartsWith("BearRiding", StringComparison.Ordinal) && ((Object)(object)val == (Object)null || val2.sharedMesh.vertexCount > val.sharedMesh.vertexCount))
				{
					val = val2;
				}
			}
			return val;
		}

		public int BoneIndex(string name)
		{
			return Array.IndexOf(BoneNames, name);
		}

		public Matrix4x4 BoneInRoot(int i)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			return MeshToRoot * ((Matrix4x4)(ref BindPoses[i])).inverse;
		}

		public Vector3 BonePosition(string name)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//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)
			int num = BoneIndex(name);
			if (num >= 0)
			{
				Matrix4x4 val = BoneInRoot(num);
				return ((Matrix4x4)(ref val)).MultiplyPoint3x4(Vector3.zero);
			}
			return Vector3.zero;
		}

		public float TopAt(float z)
		{
			float num = (z - -2.6f) / 0.025f;
			int num2 = Mathf.Clamp(Mathf.FloorToInt(num), 0, _top.Length - 1);
			int k = Mathf.Clamp(num2 + 1, 0, _top.Length - 1);
			float num3 = Near(num2);
			float num4 = Near(k);
			return Mathf.Lerp(num3, num4, Mathf.Clamp01(num - (float)num2));
		}

		private float Near(int k)
		{
			for (int i = 0; i < _top.Length; i++)
			{
				if (k - i >= 0 && !float.IsNaN(_top[k - i]))
				{
					return _top[k - i];
				}
				if (k + i < _top.Length && !float.IsNaN(_top[k + i]))
				{
					return _top[k + i];
				}
			}
			return 1f;
		}

		public int DominantBone(int v)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			if (Weights == null || v >= Weights.Length)
			{
				return -1;
			}
			BoneWeight val = Weights[v];
			int result = ((BoneWeight)(ref val)).boneIndex0;
			float num = ((BoneWeight)(ref val)).weight0;
			if (((BoneWeight)(ref val)).weight1 > num)
			{
				result = ((BoneWeight)(ref val)).boneIndex1;
				num = ((BoneWeight)(ref val)).weight1;
			}
			if (((BoneWeight)(ref val)).weight2 > num)
			{
				result = ((BoneWeight)(ref val)).boneIndex2;
				num = ((BoneWeight)(ref val)).weight2;
			}
			if (((BoneWeight)(ref val)).weight3 > num)
			{
				result = ((BoneWeight)(ref val)).boneIndex3;
			}
			return result;
		}

		public string DominantBoneName(int v)
		{
			int num = DominantBone(v);
			if (num < 0 || num >= BoneNames.Length)
			{
				return "";
			}
			return BoneNames[num];
		}

		public bool Cast(Vector3 from, Vector3 dir, out Vector3 hit, out Vector3 normal, float maxDist = 3f)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: 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_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: 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_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: 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_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: 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_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: 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_00e2: 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_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: 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_012d: 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_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = (hit = (normal = Vector3.zero));
			float num = maxDist;
			bool flag = false;
			for (int i = 0; i + 2 < Tris.Length; i += 3)
			{
				Vector3 val2 = Verts[Tris[i]];
				Vector3 val3 = Verts[Tris[i + 1]];
				Vector3 val4 = Verts[Tris[i + 2]];
				Vector3 val5 = val3 - val2;
				Vector3 val6 = val4 - val2;
				Vector3 val7 = Vector3.Cross(dir, val6);
				float num2 = Vector3.Dot(val5, val7);
				if (Mathf.Abs(num2) < 1E-09f)
				{
					continue;
				}
				float num3 = 1f / num2;
				Vector3 val8 = from - val2;
				float num4 = Vector3.Dot(val8, val7) * num3;
				if (num4 < 0f || num4 > 1f)
				{
					continue;
				}
				Vector3 val9 = Vector3.Cross(val8, val5);
				float num5 = Vector3.Dot(dir, val9) * num3;
				if (num5 < 0f || num4 + num5 > 1f)
				{
					continue;
				}
				float num6 = Vector3.Dot(val6, val9) * num3;
				if (!(num6 <= 0f) && !(num6 >= num))
				{
					num = num6;
					flag = true;
					val = Vector3.Cross(val5, val6);
					Vector3 val10 = ((Vector3)(ref val)).normalized;
					if (Vector3.Dot(val10, dir) > 0f)
					{
						val10 = -val10;
					}
					normal = val10;
				}
			}
			if (flag)
			{
				hit = from + dir * num;
			}
			return flag;
		}
	}
	public sealed class BodyRig
	{
		public readonly Transform Root;

		public readonly SkinnedMeshRenderer Body;

		internal readonly RestBody Rest;

		private readonly Dictionary<string, Transform> _bones = new Dictionary<string, Transform>();

		private readonly Dictionary<string, Transform> _frames = new Dictionary<string, Transform>();

		public bool Valid
		{
			get
			{
				if ((Object)(object)Body != (Object)null)
				{
					return Rest != null;
				}
				return false;
			}
		}

		public BodyRig(Transform root)
		{
			Root = root;
			Body = RestBody.BodyRenderer(root);
			if ((Object)(object)Body == (Object)null)
			{
				return;
			}
			Rest = RestBody.OfPrefab(Utils.GetPrefabName(((Component)root).gameObject)) ?? RestBody.For(Body, root);
			Transform[] bones = Body.bones;
			foreach (Transform val in bones)
			{
				if ((Object)(object)val != (Object)null && !_bones.ContainsKey(((Object)val).name))
				{
					_bones[((Object)val).name] = val;
				}
			}
		}

		public Transform Bone(string name)
		{
			if (!_bones.TryGetValue(name, out var value))
			{
				return null;
			}
			return value;
		}

		public Transform Frame(string bone, string name)
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: 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)
			string key = bone + "/" + name;
			if (_frames.TryGetValue(key, out var value) && (Object)(object)value != (Object)null)
			{
				return value;
			}
			Transform val = Bone(bone);
			int num = ((Rest != null) ? Rest.BoneIndex(bone) : (-1));
			value = new GameObject(name).transform;
			if ((Object)(object)val == (Object)null || num < 0)
			{
				value.SetParent(Root, false);
			}
			else
			{
				value.SetParent(val, false);
				Matrix4x4 m = Rest.BindPoses[num] * Rest.RootToMesh;
				SetLocal(value, m);
			}
			_frames[key] = value;
			return value;
		}

		internal static void SetLocal(Transform t, Matrix4x4 m)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//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_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: 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_006b: 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_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = Vector4.op_Implicit(((Matrix4x4)(ref m)).GetColumn(0));
			Vector3 val2 = Vector4.op_Implicit(((Matrix4x4)(ref m)).GetColumn(1));
			Vector3 val3 = Vector4.op_Implicit(((Matrix4x4)(ref m)).GetColumn(2));
			float num = ((Vector3)(ref val)).magnitude;
			float magnitude = ((Vector3)(ref val2)).magnitude;
			float magnitude2 = ((Vector3)(ref val3)).magnitude;
			if (Vector3.Dot(Vector3.Cross(val, val2), val3) < 0f)
			{
				num = 0f - num;
				val = -val;
			}
			t.localPosition = Vector4.op_Implicit(((Matrix4x4)(ref m)).GetColumn(3));
			t.localRotation = Quaternion.LookRotation(val3 / magnitude2, val2 / magnitude);
			t.localScale = new Vector3(num, magnitude, magnitude2);
		}
	}
	internal static class FurCut
	{
		public const string FurRenderer = "Plane";

		private static readonly Dictionary<(Mesh, TackKind), Mesh> Cache = new Dictionary<(Mesh, TackKind), Mesh>();

		public static Mesh For(Mesh full, Transform root, TackKind kind)
		{
			if ((Object)(object)full == (Object)null)
			{
				return null;
			}
			if (Cache.TryGetValue((full, kind), out var value))
			{
				return value;
			}
			value = null;
			try
			{
				RestBody restBody = RestBody.OfPrefab(Utils.GetPrefabName(((Component)root).gameObject), "Plane");
				RestBody restBody2 = RestBody.OfPrefab(Utils.GetPrefabName(((Component)root).gameObject));
				if (restBody != null && restBody2 != null)
				{
					value = Make(restBody, restBody2, kind, ((Object)full).name);
				}
			}
			catch (Exception ex)
			{
				BearRidingPlugin.Log.LogWarning((object)("Could not trim the fur: " + ex.Message));
			}
			Cache[(full, kind)] = value;
			return value;
		}

		internal static bool Covered(RestBody body, TackKind kind, Vector3 c, string bone)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			if (TackModel.IsHead(bone))
			{
				return false;
			}
			if (TackRules.BardingOf(kind) != Barding.None && c.z > -1.95f && c.z < 1.2f && c.y > 1.3f)
			{
				return true;
			}
			if (TackRules.IsRideable(kind) && c.z > -1.2f && c.z < 0.19999999f && c.y > body.TopAt(c.z) - 0.85f)
			{
				return true;
			}
			if (TackRules.HasBags(kind) && Mathf.Abs(c.z - -1.42f) < 0.5f && c.y > 1.2f)
			{
				return true;
			}
			return false;
		}

		private static Mesh Make(RestBody fur, RestBody body, TackKind kind, string name)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: 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_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: Unknown result type (might be due to invalid IL or missing references)
			//IL_023e: Unknown result type (might be due to invalid IL or missing references)
			//IL_025e: Expected O, but got Unknown
			int num = fur.Verts.Length;
			int[] parent = new int[num];
			for (int i = 0; i < num; i++)
			{
				parent[i] = i;
			}
			Dictionary<Vector3Int, int> dictionary = new Dictionary<Vector3Int, int>();
			Vector3Int key = default(Vector3Int);
			for (int j = 0; j < num; j++)
			{
				Vector3 val = fur.Verts[j];
				((Vector3Int)(ref key))..ctor(Mathf.RoundToInt(val.x * 1000f), Mathf.RoundToInt(val.y * 1000f), Mathf.RoundToInt(val.z * 1000f));
				if (dictionary.TryGetValue(key, out var value))
				{
					Union(j, value);
				}
				else
				{
					dictionary[key] = j;
				}
			}
			int[] tris = fur.Tris;
			for (int k = 0; k + 2 < tris.Length; k += 3)
			{
				Union(tris[k], tris[k + 1]);
				Union(tris[k], tris[k + 2]);
			}
			Dictionary<int, Vector3> dictionary2 = new Dictionary<int, Vector3>();
			Dictionary<int, int> dictionary3 = new Dictionary<int, int>();
			for (int l = 0; l < num; l++)
			{
				int key2 = Find(l);
				dictionary2[key2] = (dictionary2.TryGetValue(key2, out var value2) ? value2 : Vector3.zero) + fur.Verts[l];
				dictionary3[key2] = (dictionary3.TryGetValue(key2, out var value3) ? value3 : 0) + 1;
			}
			HashSet<int> hashSet = new HashSet<int>();
			foreach (KeyValuePair<int, Vector3> item in dictionary2)
			{
				Vector3 c = item.Value / (float)dictionary3[item.Key];
				if (Covered(body, kind, c, fur.DominantBoneName(item.Key)))
				{
					hashSet.Add(item.Key);
				}
			}
			List<int> list = new List<int>(tris.Length);
			for (int m = 0; m + 2 < tris.Length; m += 3)
			{
				if (!hashSet.Contains(Find(tris[m])))
				{
					list.Add(tris[m]);
					list.Add(tris[m + 1]);
					list.Add(tris[m + 2]);
				}
			}
			Mesh val2 = new Mesh
			{
				name = name + "_BearRiding_" + kind
			};
			val2.SetVertices(fur.MeshVerts);
			val2.SetNormals(fur.MeshNormals);
			if (fur.Uvs != null && fur.Uvs.Length == num)
			{
				val2.SetUVs(0, fur.Uvs);
			}
			val2.SetTriangles(list, 0, true);
			val2.boneWeights = fur.Weights;
			val2.bindposes = fur.BindPoses;
			val2.RecalculateBounds();
			return val2;
			int Find(int x)
			{
				while (parent[x] != x)
				{
					x = (parent[x] = parent[parent[x]]);
				}
				return x;
			}
			void Union(int a, int b)
			{
				a = Find(a);
				b = Find(b);
				if (a != b)
				{
					parent[a] = b;
				}
			}
		}
	}
	internal sealed class TierMats
	{
		public Material Leather;

		public Material Strap;

		public Material Metal;

		public Material Cloth;

		public Material Pelt;

		public Material Plate;
	}
	internal static class Mats
	{
		private static readonly TierMats[] Tiers = new TierMats[5];

		private static readonly Dictionary<string, Texture2D> Textures = new Dictionary<string, Texture2D>();

		private static readonly int MetallicId = Shader.PropertyToID("_Metallic");

		private static readonly int GlossId = Shader.PropertyToID("_Glossiness");

		private static readonly int BumpId = Shader.PropertyToID("_BumpMap");

		private static readonly (string tex, Color c, float met, float gloss)[,] Spec = new(string, Color, float, float)[5, 6]
		{
			{
				("leather", new Color(0.45f, 0.3f, 0.19f), 0f, 0.26f),
				("leather", new Color(0.27f, 0.17f, 0.1f), 0f, 0.28f),
				("metal", new Color(0.74f, 0.5f, 0.27f), 0.8f, 0.5f),
				("quilt", new Color(0.27f, 0.36f, 0.2f), 0f, 0.08f),
				("fur", new Color(0.46f, 0.33f, 0.22f), 0f, 0.05f),
				("metal", new Color(0.7f, 0.46f, 0.24f), 0.8f, 0.5f)
			},
			{
				("leather", new Color(0.62f, 0.42f, 0.27f), 0f, 0.28f),
				("leather", new Color(0.36f, 0.23f, 0.14f), 0f, 0.3f),
				("metal", new Color(0.55f, 0.55f, 0.56f), 0.75f, 0.45f),
				("quilt", new Color(0.55f, 0.16f, 0.12f), 0f, 0.08f),
				("fur", new Color(0.86f, 0.86f, 0.88f), 0f, 0.05f),
				("metal", new Color(0.58f, 0.58f, 0.6f), 0.8f, 0.5f)
			},
			{
				("leather", new Color(0.28f, 0.23f, 0.2f), 0f, 0.35f),
				("leather", new Color(0.19f, 0.15f, 0.13f), 0f, 0.35f),
				("metal", new Color(0.26f, 0.28f, 0.31f), 0.85f, 0.55f),
				("quilt", new Color(0.8f, 0.74f, 0.6f), 0f, 0.06f),
				("fur", new Color(0.5f, 0.36f, 0.22f), 0f, 0.05f),
				("metal", new Color(0.24f, 0.26f, 0.29f), 0.85f, 0.55f)
			},
			{
				("scales", new Color(0.42f, 0.48f, 0.5f), 0.1f, 0.4f),
				("leather", new Color(0.2f, 0.22f, 0.25f), 0f, 0.35f),
				("metal", new Color(0.3f, 0.46f, 0.55f), 0.5f, 0.7f),
				("quilt", new Color(0.22f, 0.33f, 0.55f), 0f, 0.08f),
				("fur", new Color(0.24f, 0.26f, 0.3f), 0f, 0.05f),
				("chitin", new Color(0.16f, 0.2f, 0.28f), 0.25f, 0.82f)
			},
			{
				("scales", new Color(0.58f, 0.26f, 0.15f), 0.05f, 0.35f),
				("leather", new Color(0.24f, 0.13f, 0.09f), 0f, 0.3f),
				("metal", new Color(0.78f, 0.5f, 0.24f), 0.8f, 0.5f),
				("quilt", new Color(0.16f, 0.14f, 0.14f), 0f, 0.06f),
				("fur", new Color(0.62f, 0.3f, 0.14f), 0f, 0.05f),
				("metal", new Color(0.6f, 0.36f, 0.18f), 0.75f, 0.42f)
			}
		};

		private static readonly string[] Roles = new string[6] { "Leather", "Strap", "Metal", "Cloth", "Pelt", "Plate" };

		public static TierMats For(int quality)
		{
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			int num = Mathf.Clamp(quality, 1, Tiers.Length) - 1;
			if (Tiers[num] != null)
			{
				return Tiers[num];
			}
			Material[] array = (Material[])(object)new Material[Roles.Length];
			for (int i = 0; i < Roles.Length; i++)
			{
				(string, Color, float, float) tuple = Spec[num, i];
				array[i] = Make($"BearRiding_{Roles[i]}{num + 1}", tuple.Item1, tuple.Item2, tuple.Item3, tuple.Item4);
			}
			Tiers[num] = new TierMats
			{
				Leather = array[0],
				Strap = array[1],
				Metal = array[2],
				Cloth = array[3],
				Pelt = array[4],
				Plate = array[5]
			};
			return Tiers[num];
		}

		private static Material Make(string name, string tex, Color c, float metallic, float gloss)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			Material val = new Material(Shader.Find("Standard") ?? Shader.Find("Legacy Shaders/Diffuse"))
			{
				name = name,
				hideFlags = (HideFlags)32,
				color = c
			};
			if (val.HasProperty(MetallicId))
			{
				val.SetFloat(MetallicId, metallic);
			}
			if (val.HasProperty(GlossId))
			{
				val.SetFloat(GlossId, gloss);
			}
			Texture2D val2 = Load(tex + "_d.png", linear: false);
			if ((Object)(object)val2 != (Object)null)
			{
				val.mainTexture = (Texture)(object)val2;
			}
			Texture2D val3 = Load(tex + "_n.png", linear: true);
			if ((Object)(object)val3 != (Object)null && val.HasProperty(BumpId))
			{
				val.SetTexture(BumpId, (Texture)(object)val3);
				val.EnableKeyword("_NORMALMAP");
			}
			return val;
		}

		private static Texture2D Load(string file, bool linear)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Expected O, but got Unknown
			if (Textures.TryGetValue(file, out var value))
			{
				return value;
			}
			value = null;
			string path = BearRidingPlugin.AssetPath(file);
			try
			{
				if (File.Exists(path))
				{
					Texture2D val = new Texture2D(2, 2, (TextureFormat)4, true, linear)
					{
						name = "BearRiding_" + Path.GetFileNameWithoutExtension(file),
						wrapMode = (TextureWrapMode)0,
						filterMode = (FilterMode)2,
						anisoLevel = 4
					};
					if (AssetUtils.LoadImage(val, File.ReadAllBytes(path)))
					{
						value = val;
					}
				}
			}
			catch (Exception ex)
			{
				BearRidingPlugin.Log.LogWarning((object)("Could not load " + file + ": " + ex.Message));
			}
			Textures[file] = value;
			return value;
		}
	}
	internal sealed class MeshBuilder
	{
		public readonly List<Vector3> Vertices = new List<Vector3>(256);

		public readonly List<Vector3> Normals = new List<Vector3>(256);

		public readonly List<Vector2> UVs = new List<Vector2>(256);

		public readonly List<int> Triangles = new List<int>(512);

		private readonly Stack<Matrix4x4> _stack = new Stack<Matrix4x4>();

		private Matrix4x4 _base = Matrix4x4.identity;

		private Matrix4x4 _local = Matrix4x4.identity;

		private Matrix4x4 _m = Matrix4x4.identity;

		private Matrix4x4 _n = Matrix4x4.identity;

		private bool _flip;

		public bool IsEmpty => Triangles.Count == 0;

		public void SetBase(Matrix4x4 m)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			if (!(m == _base))
			{
				_base = m;
				Recalc();
			}
		}

		public void Push(Matrix4x4 m)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			_stack.Push(_local);
			_local *= m;
			Recalc();
		}

		public void Push(Vector3 pos, Quaternion rot)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			Push(Matrix4x4.TRS(pos, rot, Vector3.one));
		}

		public void Pop()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			_local = ((_stack.Count > 0) ? _stack.Pop() : Matrix4x4.identity);
			Recalc();
		}

		private void Recalc()
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			_m = _base * _local;
			Matrix4x4 inverse = ((Matrix4x4)(ref _m)).inverse;
			_n = ((Matrix4x4)(ref inverse)).transpose;
			_flip = ((Matrix4x4)(ref _m)).determinant < 0f;
		}

		public int Add(Vector3 p, Vector3 n, Vector2 uv)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: 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_0053: Unknown result type (might be due to invalid IL or missing references)
			Vertices.Add(((Matrix4x4)(ref _m)).MultiplyPoint3x4(p));
			Vector3 val = ((Matrix4x4)(ref _n)).MultiplyVector(n);
			float magnitude = ((Vector3)(ref val)).magnitude;
			Normals.Add((magnitude > 1E-08f) ? (val / magnitude) : Vector3.up);
			UVs.Add(uv);
			return Vertices.Count - 1;
		}

		public void Tri(int a, int b, int c)
		{
			Triangles.Add(a);
			if (_flip)
			{
				Triangles.Add(c);
				Triangles.Add(b);
			}
			else
			{
				Triangles.Add(b);
				Triangles.Add(c);
			}
		}

		public void Quad(int a, int b, int c, int d)
		{
			Tri(a, b, c);
			Tri(a, c, d);
		}

		public Mesh ToMesh(string name)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			Mesh val = new Mesh
			{
				name = name
			};
			if (Vertices.Count > 65000)
			{
				val.indexFormat = (IndexFormat)1;
			}
			val.SetVertices(Vertices);
			val.SetNormals(Normals);
			val.SetUVs(0, UVs);
			val.SetTriangles(Triangles, 0, true);
			val.RecalculateTangents();
			return val;
		}

		public void Clear()
		{
			Vertices.Clear();
			Normals.Clear();
			UVs.Clear();
			Triangles.Clear();
		}
	}
	internal sealed class PartSet
	{
		private readonly List<Material> _mats = new List<Material>();

		private readonly List<MeshBuilder> _builders = new List<MeshBuilder>();

		private readonly Stack<Matrix4x4> _stack = new Stack<Matrix4x4>();

		private Matrix4x4 _current = Matrix4x4.identity;

		public MeshBuilder this[Material mat]
		{
			get
			{
				//IL_0059: Unknown result type (might be due to invalid IL or missing references)
				MeshBuilder meshBuilder = null;
				for (int i = 0; i < _mats.Count; i++)
				{
					if (_mats[i] == mat)
					{
						meshBuilder = _builders[i];
						break;
					}
				}
				if (meshBuilder == null)
				{
					meshBuilder = new MeshBuilder();
					_mats.Add(mat);
					_builders.Add(meshBuilder);
				}
				meshBuilder.SetBase(_current);
				return meshBuilder;
			}
		}

		public void Push(Matrix4x4 m)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			_stack.Push(_current);
			_current *= m;
		}

		public void Push(Vector3 pos, Quaternion rot)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			Push(Matrix4x4.TRS(pos, rot, Vector3.one));
		}

		public void Push(Vector3 pos, Quaternion rot, Vector3 scale)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			Push(Matrix4x4.TRS(pos, rot, scale));
		}

		public void Pop()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			_current = ((_stack.Count > 0) ? _stack.Pop() : Matrix4x4.identity);
		}

		public List<(Mesh mesh, Material mat)