Decompiled source of Pig Riding v1.0.0

plugins/PigRiding.dll

Decompiled 2 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
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 BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using PigRiding.Core;
using PigRiding.Dev;
using PigRiding.Gameplay;
using PigRiding.Visual;
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 PigRiding
{
	public static class Cfg
	{
		public static ConfigEntry<string> Boars;

		public static ConfigEntry<bool> MountFightsOnItsOwn;

		public static ConfigEntry<bool> BoarsFollow;

		public static ConfigEntry<float> RideMinSize;

		public static ConfigEntry<bool> TameBoarsGrow;

		public static ConfigEntry<float> XpScale;

		public static ConfigEntry<float> PlainMaxSize;

		public static ConfigEntry<float> BornMaxSize;

		public static ConfigEntry<float> BoarbornChance;

		public static ConfigEntry<float> BoarbornInheritChance;

		public static ConfigEntry<float> HibernationSeconds;

		public static ConfigEntry<bool> Hibernation;

		public static ConfigEntry<float> GoreStamina;

		public static ConfigEntry<float> ChargeStamina;

		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>[7];

		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[7] { "DeerHide:4,LeatherScraps:6,Wood:4,Resin:2", "TrollHide:3,Bronze:2,LeatherScraps:4", "Iron:4,DeerHide:4,LeatherScraps:6", "WolfPelt:3,Silver:4,LeatherScraps:6", "LoxPelt:3,LinenThread:10,BlackMetal:4", "ScaleHide:3,Carapace:6,JuteBlue:3", "AskHide:4,FlametalNew:4,MorgenSinew:2" },
			[TackKind.LightBarding] = new string[7] { "DeerHide:6,LeatherScraps:8,Resin:4", "TrollHide:4,Bronze:2,LeatherScraps:4", "Iron:4,TrollHide:3,LeatherScraps:6", "WolfPelt:4,Silver:4,DeerHide:4", "LinenThread:15,LoxPelt:3,BlackMetal:4", "JuteBlue:4,ScaleHide:3,Carapace:8", "AskHide:6,LinenThread:10,FlametalNew:4" },
			[TackKind.HeavyBarding] = new string[7] { "Wood:10,LeatherScraps:10,DeerHide:4,Flint:6", "Bronze:10,TrollHide:3,LeatherScraps:6", "Iron:16,LeatherScraps:8,Chain:2", "Silver:14,WolfPelt:3,LeatherScraps:8", "BlackMetal:14,LoxPelt:3,LinenThread:10", "Carapace:18,ScaleHide:4,Eitr:4", "FlametalNew:16,AskHide:4,CharredBone:6" },
			[TackKind.Saddlebags] = new string[7] { "DeerHide:4,LeatherScraps:6,Wood:2", "TrollHide:4,Bronze:1,LeatherScraps:4", "Iron:2,TrollHide:3,LeatherScraps:6", "WolfPelt:3,Silver:2,LeatherScraps:6", "LoxPelt:3,LinenThread:15,BlackMetal:2", "JuteBlue:6,ScaleHide:3,YggdrasilWood:4", "AskHide:6,LinenThread:15,FlametalNew:2" }
		};

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

		private const string DefaultHarnessQ6 = "Carapace:8,ScaleHide:4,JuteBlue:4";

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

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

		public static readonly string[] Biomes = new string[7] { "Meadows", "Black Forest", "Swamp", "Mountains", "Plains", "Mistlands", "Ashlands" };

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

		public static GrowTuning Grow { get; private set; } = new GrowTuning();

		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_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Expected O, but got Unknown
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Expected O, but got Unknown
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Expected O, but got Unknown
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Expected O, but got Unknown
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Expected O, but got Unknown
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Expected O, but got Unknown
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Expected O, but got Unknown
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Expected O, but got Unknown
			//IL_021c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0226: Expected O, but got Unknown
			//IL_0247: Unknown result type (might be due to invalid IL or missing references)
			//IL_0251: Expected O, but got Unknown
			//IL_0284: Unknown result type (might be due to invalid IL or missing references)
			//IL_028e: Expected O, but got Unknown
			//IL_02c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cb: Expected O, but got Unknown
			//IL_02fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0308: Expected O, but got Unknown
			//IL_033b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0345: Expected O, but got Unknown
			//IL_0378: Unknown result type (might be due to invalid IL or missing references)
			//IL_0382: Expected O, but got Unknown
			//IL_03b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bf: Expected O, but got Unknown
			//IL_03f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fc: Expected O, but got Unknown
			//IL_042f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0439: Expected O, but got Unknown
			//IL_046c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0476: Expected O, but got Unknown
			//IL_0509: Unknown result type (might be due to invalid IL or missing references)
			//IL_0513: Expected O, but got Unknown
			//IL_0647: Unknown result type (might be due to invalid IL or missing references)
			//IL_0651: Expected O, but got Unknown
			//IL_0672: Unknown result type (might be due to invalid IL or missing references)
			//IL_067c: Expected O, but got Unknown
			//IL_069d: Unknown result type (might be due to invalid IL or missing references)
			//IL_06a7: Expected O, but got Unknown
			//IL_05d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_05de: Expected O, but got Unknown
			ConfigurationManagerAttributes val = new ConfigurationManagerAttributes
			{
				IsAdminOnly = true
			};
			Boars = c.Bind<string>("1 - General", "Boars", "Boar", new ConfigDescription("Prefab names of the creatures that can wear boar tack and grow up, comma separated, '*' as wildcard. Takes effect for creatures that load after the change.", (AcceptableValueBase)null, new object[1] { val }));
			RideMinSize = c.Bind<float>("1 - General", "RideMinSize", 1.2f, new ConfigDescription("How big a boar must be to carry a rider, as a share of a plain boar's size (1.2 = a two-star boar). At the default a Boarborn is big enough from birth; a plain boar grows into it. 0 lets every tame boar be ridden.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 3f), new object[1] { val }));
			BoarsFollow = c.Bind<bool>("1 - General", "BoarsFollow", true, new ConfigDescription("Tame boars follow you or stay when you tell them, like wolves (vanilla boars cannot be commanded). Needed for them to gain experience beside you.", (AcceptableValueBase)null, new object[1] { val }));
			MountFightsOnItsOwn = c.Bind<bool>("1 - General", "MountFightsOnItsOwn", false, new ConfigDescription("A ridden boar that stands still may run after enemies by itself. Off: while you sit in the saddle, the boar only does what you tell it.", (AcceptableValueBase)null, new object[1] { val }));
			TameBoarsGrow = c.Bind<bool>("2 - Growing", "TameBoarsGrow", true, new ConfigDescription("Every tame boar gains experience beside you, rises to level 10 and grows. Off: only Boarborn do.", (AcceptableValueBase)null, new object[1] { val }));
			XpScale = c.Bind<float>("2 - Growing", "XpScale", 1f, new ConfigDescription("Multiplies all experience (2 for every 25 m walked together, 15 for a killing blow).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 20f), new object[1] { val }));
			PlainMaxSize = c.Bind<float>("2 - Growing", "PlainMaxSize", 1.5f, new ConfigDescription("Size of a plain tame boar at level 10 (1 = as born). Stars add their own size on top.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 3f), new object[1] { val }));
			BornMaxSize = c.Bind<float>("2 - Growing", "BoarbornMaxSize", 2f, new ConfigDescription("Size of a Boarborn at level 10. It is born at 1.25. Stars add their own size on top.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1.25f, 4f), new object[1] { val }));
			BoarbornChance = c.Bind<float>("3 - Boarborn", "BoarbornChance", 0.05f, new ConfigDescription("Chance that a wild boar is a Boarborn (0.05 = 1 in 20). Rolled once per boar, when it is first seen.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), new object[1] { val }));
			BoarbornInheritChance = c.Bind<float>("3 - Boarborn", "BoarbornInheritChance", 0.25f, new ConfigDescription("Chance that a piglet of a Boarborn mother grows into a Boarborn. Piglets of plain boars never do.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), new object[1] { val }));
			Hibernation = c.Bind<bool>("3 - Boarborn", "FallenBoarbornSleep", true, new ConfigDescription("A tame Boarborn that falls sleeps off its wounds instead of dying (a player's blow still kills it).", (AcceptableValueBase)null, new object[1] { val }));
			HibernationSeconds = c.Bind<float>("3 - Boarborn", "SleepSeconds", 180f, new ConfigDescription("How long a fallen Boarborn sleeps before it wakes with 30 % health.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(10f, 3600f), new object[1] { val }));
			RunStaminaDrain = c.Bind<float>("4 - Riding", "RunStaminaDrain", 1f, new ConfigDescription("Mount stamina a running boar uses per second (halved at full riding skill, like the lox).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 20f), new object[1] { val }));
			GoreStamina = c.Bind<float>("4 - Riding", "GoreStamina", 10f, new ConfigDescription("Mount stamina for a tusk gore (attack button).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), new object[1] { val }));
			ChargeStamina = c.Bind<float>("4 - Riding", "ChargeStamina", 25f, new ConfigDescription("Mount stamina for a charge (secondary attack button): a burst of speed and a gore that hits 75 % harder and throws the target back.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), new object[1] { val }));
			LeapStamina = c.Bind<float>("4 - 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>("4 - Riding", "LeapUp", 6.5f, new ConfigDescription("Upward push of a leap in m/s (6.5 clears about 1 m; the boar's own jump is 10).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 20f), new object[1] { val }));
			LeapForward = c.Bind<float>("4 - Riding", "LeapForward", 5f, new ConfigDescription("Forward push of a leap in m/s, on top of the boar's own jump.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 20f), new object[1] { val }));
			ArmorScale = c.Bind<float>("5 - 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>("5 - 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 < 7; i++)
			{
				Stations[i] = c.Bind<string>("6 - 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 == 4) ? " War harnesses are bound here." : ""), (AcceptableValueBase)null, new object[1] { val }));
			}
			foreach (KeyValuePair<TackKind, string[]> defaultRecipe in DefaultRecipes)
			{
				ConfigEntry<string>[] array = new ConfigEntry<string>[7];
				for (int j = 0; j < 7; j++)
				{
					array[j] = c.Bind<string>("7 - 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} ({Biomes[j]}): 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>("7 - Recipes", "WarHarnessQ5", "LinenThread:10,LoxPelt:2,BlackMetal:4", new ConfigDescription($"Cost to bind a war harness, on top of a saddle, a barding and saddlebags of quality {5} or better (the harness takes the quality all three reach).", (AcceptableValueBase)null, new object[1] { val }));
			ConfigEntry<string> val3 = c.Bind<string>("7 - Recipes", "WarHarnessQ6", "Carapace:8,ScaleHide:4,JuteBlue:4", new ConfigDescription("Cost to upgrade a war harness to quality 6 (Mistlands).", (AcceptableValueBase)null, new object[1] { val }));
			ConfigEntry<string> val4 = c.Bind<string>("7 - Recipes", "WarHarnessQ7", "FlametalNew:8,AskHide:6,MorgenSinew:2", new ConfigDescription("Cost to upgrade a war harness to quality 7 (Ashlands).", (AcceptableValueBase)null, new object[1] { val }));
			Recipes[TackKind.LightWarHarness] = new ConfigEntry<string>[7] { null, null, null, null, val2, val3, val4 };
			Recipes[TackKind.HeavyWarHarness] = Recipes[TackKind.LightWarHarness];
			c.SettingChanged += delegate
			{
				Retune();
			};
			Retune();
			ShowHints = c.Bind<bool>("9 - Client", "ShowRidingHints", true, "Show the boar's riding keys (gore, charge, leap, dismount) as a message when you mount.");
		}

		private static void Retune()
		{
			Current = new Tuning
			{
				ArmorScale = (ArmorScale?.Value ?? 1f),
				HealthScale = (HealthScale?.Value ?? 1f)
			};
			Grow = new GrowTuning
			{
				XpScale = (XpScale?.Value ?? 1f),
				PlainMaxSize = (PlainMaxSize?.Value ?? 1.5f),
				BornMaxSize = (BornMaxSize?.Value ?? 2f)
			};
		}
	}
	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, 5) : qualityLevel);
						__result = __result + "\n" + Describe(tackKind, q, crafting);
					}
				}
				catch (Exception ex)
				{
					PigRidingPlugin.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 readonly string[] BiomeTokens = new string[7] { "$biome_meadows", "$biome_blackforest", "$biome_swamp", "$biome_mountain", "$biome_plains", "$biome_mistlands", "$biome_ashlands" };

		private static float Weight(TackKind k)
		{
			return k switch
			{
				TackKind.Saddle => 8f, 
				TackKind.LightBarding => 10f, 
				TackKind.HeavyBarding => 25f, 
				TackKind.Saddlebags => 5f, 
				TackKind.LightWarHarness => 22f, 
				_ => 36f, 
			};
		}

		public static string PrefabName(TackKind k)
		{
			return "PigRiding_" + 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)
			{
				PigRidingPlugin.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[7];
			bool num = GUIManager.IsHeadless();
			GameObject val = (GameObject)((!num) ? ((object)TackModel.BuildItem(kind, 1)) : ((object)new GameObject("PigRiding_Item_" + kind)));
			if (!num)
			{
				for (int i = 1; i <= 7; 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);
				PigRidingPlugin.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 = 7;
			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)
			{
				PigRidingPlugin.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("pr_tt_ride"));
				stringBuilder.Append('\n').Append(Lang.T("pr_tt_stamina", Mathf.RoundToInt(tackStats.MountStamina)));
			}
			if (tackStats.Armor > 0f)
			{
				stringBuilder.Append('\n').Append(Lang.T("pr_tt_armor", Mathf.RoundToInt(tackStats.Armor)));
			}
			if (tackStats.HealthBonus > 0f)
			{
				stringBuilder.Append('\n').Append(Lang.T("pr_tt_health", Mathf.RoundToInt(tackStats.HealthBonus * 100f)));
			}
			if (tackStats.SpeedModifier != 0f)
			{
				stringBuilder.Append('\n').Append(Lang.T("pr_tt_speed", Mathf.RoundToInt(tackStats.SpeedModifier * 100f)));
			}
			if (tackStats.FireResistant)
			{
				stringBuilder.Append('\n').Append(Lang.T("pr_tt_fire"));
			}
			if (tackStats.BagSlots > 0)
			{
				stringBuilder.Append('\n').Append(Lang.T("pr_tt_bags", tackStats.BagSlots));
			}
			if (TackRules.IsCombo(k))
			{
				stringBuilder.Append("\n\n").Append(Lang.T("pr_tt_bind", Lang.L("$" + Lang.Token(TackRules.BardingPart(k))), 5));
			}
			stringBuilder.Append("\n\n").Append(Lang.T("pr_tt_use"));
			if (tackStats.Rideable && Cfg.RideMinSize.Value > 0f)
			{
				stringBuilder.Append(' ').Append(Lang.T("pr_tt_size"));
			}
			if (q < 7)
			{
				string text = Recipes.StationName(q + 1);
				if (!string.IsNullOrEmpty(text))
				{
					stringBuilder.Append('\n').Append(Lang.T("pr_tt_next", Lang.L(text), Lang.L(BiomeTokens[q])));
				}
			}
			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, "pr_saddle", "Boar Saddle", "Ebersattel", "A riding saddle cut to a boar's broad back, with a girth strap and short stirrups. Put it on a tame boar that is big enough to carry you.", "Ein Reitsattel für den breiten Rücken eines Ebers, mit Bauchgurt und kurzen Steigbügeln. Leg ihn einem zahmen Eber auf, der groß genug ist, dich zu tragen."),
			(TackKind.LightBarding, "pr_barding_light", "Light Boar Barding", "Leichter Eberharnisch", "A padded coat with studs over back, flanks and chest. More armour and health, and the boar stays as fast as ever.", "Ein gepolsterter Rock mit Nieten über Rücken, Flanken und Brust. Mehr Rüstung und Leben, und der Eber bleibt so schnell wie zuvor."),
			(TackKind.HeavyBarding, "pr_barding_heavy", "Heavy Boar Barding", "Schwerer Eberharnisch", "Overlapping plates over neck, back and flanks, and a plate for the brow. Much more armour and health, but the boar is slower.", "Überlappende Platten über Nacken, Rücken und Flanken und ein Stirnschild. Viel mehr Rüstung und Leben, aber der Eber wird langsamer."),
			(TackKind.Saddlebags, "pr_bags", "Boar Saddlebags", "Eber-Satteltaschen", "Two saddlebags on a strap across the back. A boar that wears them carries your load.", "Zwei Satteltaschen an einem Gurt über dem Rücken. Ein Eber, der sie trägt, schleppt deine Last."),
			(TackKind.LightWarHarness, "pr_harness_light", "Light Boar War Harness", "Leichtes Eber-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, "pr_harness_heavy", "Heavy Boar War Harness", "Schweres Eber-Kriegsgeschirr", "Saddle, heavy barding and saddlebags bound into one harness: ride, fight and carry at once, armoured like Hildisvíni, Freyja's battle boar.", "Sattel, schwerer Harnisch und Satteltaschen zu einem Geschirr verbunden: reiten, kämpfen und tragen zugleich, gepanzert wie Hildisvíni, Freyjas Kampfeber.")
		};

		private static readonly (string key, string en, string de)[] Texts = new(string, string, string)[42]
		{
			("pr_wears", "Wears: {0}", "Trägt: {0}"),
			("pr_quality", "quality {0}", "Stufe {0}"),
			("pr_takeoff", "Take off {0}", "{0} abnehmen"),
			("pr_open_bags", "Open the saddlebags", "Satteltaschen öffnen"),
			("pr_bags_hover", "Saddlebags ({0}/{1})", "Satteltaschen ({0}/{1})"),
			("pr_ride", "Ride", "Reiten"),
			("pr_too_small_line", "Too small to carry you yet", "Noch zu klein, um dich zu tragen"),
			("pr_msg_on", "{0} now wears the {1}.", "{0} trägt jetzt: {1}."),
			("pr_msg_already", "{0} already wears the {1}. Take it off first.", "{0} trägt schon: {1}. Nimm es zuerst ab."),
			("pr_msg_wild", "Only a tame boar lets you put tack on it.", "Nur ein zahmer Eber lässt sich etwas anlegen."),
			("pr_msg_notboar", "The {0} only fits a boar.", "{0}: passt nur einem Eber."),
			("pr_msg_small", "{0} is too small to carry you. It grows big enough at level {1}.", "{0} ist zu klein, um dich zu tragen. Ab Level {1} ist er groß genug."),
			("pr_msg_small_never", "{0} is too small to carry you. Only a Boarborn or a boar with two stars is big enough.", "{0} ist zu klein, um dich zu tragen. Nur ein Boarborn oder ein Eber mit zwei Sternen ist groß genug."),
			("pr_msg_off", "You take the {0} off.", "Abgenommen: {0}."),
			("pr_msg_bags_full", "Empty the saddlebags first.", "Leere zuerst die Satteltaschen."),
			("pr_msg_bags_open", "Someone has the saddlebags open.", "Jemand hat die Satteltaschen offen."),
			("pr_msg_ridden", "Someone is riding this boar.", "Jemand reitet diesen Eber."),
			("pr_msg_tired", "{0} is out of breath.", "{0} ist außer Atem."),
			("pr_hint", "Gore [<color=yellow><b>$KEY_Attack</b></color>]  Charge [<color=yellow><b>$KEY_SecondaryAttack</b></color>]  Leap [<color=yellow><b>$KEY_Jump</b></color>]  Dismount [<color=yellow><b>$KEY_Use</b></color>]", "Hauer [<color=yellow><b>$KEY_Attack</b></color>]  Ansturm [<color=yellow><b>$KEY_SecondaryAttack</b></color>]  Satz [<color=yellow><b>$KEY_Jump</b></color>]  Absteigen [<color=yellow><b>$KEY_Use</b></color>]"),
			("pr_tt_ride", "Lets you ride the boar", "Macht den Eber reitbar"),
			("pr_tt_stamina", "Mount stamina: <color=orange>{0}</color>", "Ausdauer des Reittiers: <color=orange>{0}</color>"),
			("pr_tt_armor", "Boar armour: <color=orange>{0}</color>", "Rüstung des Ebers: <color=orange>{0}</color>"),
			("pr_tt_health", "Boar health: <color=orange>+{0} %</color>", "Leben des Ebers: <color=orange>+{0} %</color>"),
			("pr_tt_speed", "Boar speed: <color=orange>{0} %</color>", "Tempo des Ebers: <color=orange>{0} %</color>"),
			("pr_tt_fire", "Resistant to fire", "Widerstandsfähig gegen Feuer"),
			("pr_tt_bags", "Saddlebags: <color=orange>{0}</color> slots", "Satteltaschen: <color=orange>{0}</color> Plätze"),
			("pr_tt_use", "Use it on a tame boar to put it on. A boar wears one piece of tack at a time.", "Auf einen zahmen Eber anwenden, um es anzulegen. Ein Eber trägt immer nur ein Stück Geschirr."),
			("pr_tt_size", "Only a boar big enough to carry you can be ridden: a Boarborn, a boar with two stars, or a boar that has grown.", "Reiten lässt sich nur ein Eber, der groß genug ist: ein Boarborn, ein Eber mit zwei Sternen oder einer, der gewachsen ist."),
			("pr_tt_bind", "Bound from a saddle, a {0} and saddlebags of quality {1} or better. It takes the quality all three reach.", "Gebunden aus Sattel, Harnisch ({0}) und Satteltaschen, alle ab Stufe {1}. Es erhält die Stufe, die alle drei erreichen."),
			("pr_tt_next", "Next quality at: {0} ({1})", "Nächste Stufe an: {0} ({1})"),
			("pr_boarborn", "Boarborn", "Boarborn"),
			("pr_coat_0", "golden bristles", "goldene Borsten"),
			("pr_coat_1", "ash-grey bristles", "aschgraue Borsten"),
			("pr_coat_2", "night-black bristles", "nachtschwarze Borsten"),
			("pr_level_line", "Level {0} · {1}", "Level {0} · {1}"),
			("pr_level_xp", "{0}/{1} XP", "{0}/{1} EP"),
			("pr_level_max", "fully grown", "ausgewachsen"),
			("pr_born_sleep", "Sleeps off its wounds ({0} s)", "Schläft seine Wunden aus ({0} s)"),
			("pr_msg_levelup", "{0} has grown: level {1}.", "{0} ist gewachsen: Level {1}."),
			("pr_msg_canride", "{0} is big enough to carry you now.", "{0} ist jetzt groß genug, dich zu tragen."),
			("pr_msg_hibernate", "{0} falls and sleeps off its wounds.", "{0} geht zu Boden und schläft seine Wunden aus."),
			("pr_msg_wakes", "{0} wakes up.", "{0} wacht auf.")
		};

		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 "pr_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("pr_quality", TackRules.ClampQuality(quality)) + ")";
		}
	}
	[BepInPlugin("zap.pigriding", "Pig Riding", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[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 PigRidingPlugin : BaseUnityPlugin
	{
		public const string PluginGuid = "zap.pigriding";

		public const string PluginName = "Pig Riding";

		public const string PluginVersion = "1.0.0";

		public const string BetterRidingGuid = "Ygg.BetterRiding";

		public const string WolfRidingGuid = "zap.wolfriding";

		public const string BearRidingGuid = "zap.bearriding";

		public const string StarbornGuid = "zap.starbornbreeding";

		private Harmony _harmony;

		public static PigRidingPlugin 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_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: 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();
			Items.Init();
			Recipes.Init();
			_harmony = new Harmony("zap.pigriding");
			_harmony.PatchAll(typeof(PigRidingPlugin).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 == 5;
					}
					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), 5);
				}
			}

			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[7];

		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 <= 7; 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 <= 7; 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)
			{
				PigRidingPlugin.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)
			{
				PigRidingPlugin.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_PigRiding_{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);
			PigRidingPlugin.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 > 7)
			{
				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 PigRiding.Visual
{
	internal static class BoarShape
	{
		public const string RideAnimation = "attach_asksvin";

		public const string SeatBone = "Spine1";

		public const string BagBone = "Spine";

		public const string NeckBone = "Neck";

		public const string HeadBone = "Head";

		public const float SeatBack = -0.24f;

		public const float SeatFront = 0.16f;

		public const float BagZ = -0.33f;

		public const float Belly = 0.31f;

		public const float Axis = 0.3f;

		public const float HalfWidth = 0.22f;

		public const float CoatBack = -0.52f;

		public const float CoatFront = 0.47f;

		public const float CoatLow = 0.5f;

		public const float NeckEnd = 0.62f;

		public const float GirthZ = 0.08f;

		public const float StirrupZ = -0.04f;

		public const float StirrupBottom = 0.4f;

		public const float BrowFrom = 0.73f;

		public const float BrowTo = 0.86f;

		public const float PlatesFront = 0.4f;

		public const float PlatesBack = -0.52f;

		public const float PlateStep = 0.095f;

		public static readonly float[] NeckPlates = new float[2] { 0.5f, 0.575f };

		public static readonly Vector3 SeatRest = new Vector3(0f, 0.975f, -0.04f);

		public static readonly Bounds SeatBox = new Bounds(new Vector3(0f, 1f, -0.04f), new Vector3(0.52f, 0.24f, 0.48f));

		public static readonly Bounds NeckBox = new Bounds(new Vector3(0f, 0.8f, 0.5f), new Vector3(0.46f, 0.46f, 0.3f));

		public static readonly Bounds PackBox = new Bounds(new Vector3(0f, 0.99f, -0.3f), new Vector3(0.4f, 0.18f, 0.4f));

		public static Bounds BagBox(int side)
		{
			//IL_0012: 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)
			return new Bounds(new Vector3((float)side * 0.31f, 0.74f, -0.33f), new Vector3(0.18f, 0.34f, 0.34f));
		}
	}
	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 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 = -1.7f;

		private const float TopMax = 1.5f;

		private const float EdgeSlack = 0.0001f;

		private RestBody(SkinnedMeshRenderer smr, Transform root)
		{
			//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_0124: 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_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: 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_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: 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;
			MeshVerts = Mesh.vertices;
			MeshNormals = Mesh.normals;
			Tris = Mesh.triangles;
			Weights = Mesh.boneWeights;
			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 : "");
			}
			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[129];
			for (int k = 0; k < _top.Length; k++)
			{
				float num2 = -1.7f + (float)k * 0.025f;
				_top[k] = (Cast(new Vector3(0f, 4f, num2), Vector3.down, out var hit, out normal, 6f) ? hit.y : float.NaN);
			}
		}

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

		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("PigRiding", 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 - -1.7f) / 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 = 2f)
		{
			//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 < -0.0001f || num4 > 1.0001f)
				{
					continue;
				}
				Vector3 val9 = Vector3.Cross(val8, val5);
				float num5 = Vector3.Dot(dir, val9) * num3;
				if (num5 < -0.0001f || num4 + num5 > 1.0001f)
				{
					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.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 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[7];

		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)[7, 6]
		{
			{
				("leather", new Color(0.66f, 0.47f, 0.3f), 0f, 0.22f),
				("leather", new Color(0.4f, 0.27f, 0.16f), 0f, 0.25f),
				("metal", new Color(0.36f, 0.36f, 0.35f), 0.15f, 0.55f),
				("quilt", new Color(0.72f, 0.64f, 0.5f), 0f, 0.06f),
				("fur", new Color(0.58f, 0.42f, 0.27f), 0f, 0.05f),
				("wood", new Color(0.44f, 0.33f, 0.22f), 0f, 0.15f)
			},
			{
				("leather", new Color(0.4f, 0.46f, 0.54f), 0f, 0.3f),
				("leather", new Color(0.22f, 0.21f, 0.21f), 0f, 0.3f),
				("metal", new Color(0.76f, 0.5f, 0.26f), 0.85f, 0.5f),
				("quilt", new Color(0.34f, 0.4f, 0.26f), 0f, 0.06f),
				("fur", new Color(0.34f, 0.37f, 0.42f), 0f, 0.05f),
				("metal", new Color(0.72f, 0.47f, 0.24f), 0.85f, 0.5f)
			},
			{
				("leather", new Color(0.33f, 0.22f, 0.14f), 0f, 0.3f),
				("leather", new Color(0.19f, 0.13f, 0.09f), 0f, 0.3f),
				("metal", new Color(0.52f, 0.52f, 0.54f), 0.75f, 0.42f),
				("quilt", new Color(0.5f, 0.15f, 0.11f), 0f, 0.08f),
				("fur", new Color(0.46f, 0.33f, 0.22f), 0f, 0.05f),
				("metal", new Color(0.55f, 0.55f, 0.57f), 0.8f, 0.45f)
			},
			{
				("leather", new Color(0.52f, 0.5f, 0.48f), 0f, 0.28f),
				("leather", new Color(0.26f, 0.25f, 0.25f), 0f, 0.3f),
				("metal", new Color(0.86f, 0.88f, 0.92f), 0.9f, 0.68f),
				("quilt", new Color(0.36f, 0.46f, 0.62f), 0f, 0.06f),
				("fur", new Color(0.88f, 0.88f, 0.9f), 0f, 0.05f),
				("metal", new Color(0.82f, 0.84f, 0.88f), 0.9f, 0.65f)
			},
			{
				("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.92f, 0.62f, 0.3f), 0.9f, 0.62f),
				("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.85f, 0.55f, 0.26f), 0.9f, 0.6f)
			}
		};

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

		public static TierMats For(int quality)
		{
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			int num = Mathf.Clamp(quality, 1, 7) - 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($"PigRiding_{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 = PigRidingPlugin.AssetPath(file);
			try
			{
				if (File.Exists(path))
				{
					Texture2D val = new Texture2D(2, 2, (TextureFormat)4, true, linear)
					{
						name = "PigRiding_" + Path.GetFileNameWithoutExtension(file),
						wrapMode = (TextureWrapMode)0,
						filterMode = (FilterMode)2,
						anisoLevel = 4
					};
					if (AssetUtils.LoadImage(val, File.ReadAllBytes(path)))
					{
						value = val;
					}
				}
			}
			catch (Exception ex)
			{
				PigRidingPlugin.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)> Bake(string name)
		{
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			List<(Mesh, Material)> list = new List<(Mesh, Material)>();
			for (int i = 0; i < _builders.Count; i++)
			{
				if (!_builders[i].IsEmpty)
				{
					list.Add((_builders[i].ToMesh(name + "_" + (((Object)(object)_mats[i] != (Object)null) ? ((Object)_mats[i]).name : "Mat")), _mats[i]));
				}
			}
			_mats.Clear();
			_builders.Clear();
			_stack.Clear();
			_current = Matrix4x4.identity;
			return list;
		}

		public void Emit(Transform parent, string name)
		{
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: 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_0062: Expected O, but got Unknown
			for (int i = 0; i < _builders.Count; i++)
			{
				MeshBuilder meshBuilder = _builders[i];
				Material val = _mats[i];
				if (!meshBuilder.IsEmpty)
				{
					string text = (((Object)(object)val != (Object)null) ? ((Object)val).name.Replace("PigRiding_", "") : "Mat");
					GameObject val2 = new GameObject(name + "_" + text);
					val2.transform.SetParent(parent, false);
					val2.AddComponent<MeshFilter>().sharedMesh = meshBuilder.ToMesh(((Object)val2).name);
					MeshRenderer obj = val2.AddComponent<MeshRenderer>();
					((Renderer)obj).sharedMaterial = val;
					((Renderer)obj).shadowCastingMode = (ShadowCastingMode)1;
					((Renderer)obj).receiveShadows = true;
				}
			}
			_mats.Clear();
			_builders.Clear();
			_stack.Clear();
			_current = Matrix4x4.identity;
		}
	}
	internal static class MeshKit
	{
		private const float Tau = (float)Math.PI * 2f;

		public static Quaternion AlongX => Quaternion.Euler(0f, 0f, -90f);

		public static Quaternion AlongZ => Quaternion.Euler(90f, 0f, 0f);

		public static void ProfileNormals(IList<Vector2> p, Vector2[] result)
		{
			//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_001a: 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_0028: 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_0068: 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_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: 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_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: 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)
			//IL_0058: 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_00d0: 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_0089: 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_0091: 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_00a2: 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_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			int count = p.Count;
			for (int i = 0; i < count; i++)
			{
				Vector2 val = Vector2.zero;
				Vector2 val4;
				if (i > 0)
				{
					Vector2 val2 = p[i] - p[i - 1];
					if (((Vector2)(ref val2)).sqrMagnitude > 1E-12f)
					{
						Vector2 val3 = val;
						val4 = new Vector2(val2.y, 0f - val2.x);
						val = val3 + ((Vector2)(ref val4)).normalized;
					}
				}
				if (i < count - 1)
				{
					Vector2 val5 = p[i + 1] - p[i];
					if (((Vector2)(ref val5)).sqrMagnitude > 1E-12f)
					{
						Vector2 val6 = val;
						val4 = new Vector2(val5.y, 0f - val5.x);
						val = val6 + ((Vector2)(ref val4)).normalized;
					}
				}
				result[i] = (Vector2)((((Vector2)(ref val)).sqrMagnitude > 1E-12f) ? ((Vector2)(ref val)).normalized : new Vector2(1f, 0f));
			}
		}

		public static void Lathe(MeshBuilder mb, IList<Vector2> prof, int seg, float uTiles = 1f, float vPerMeter = 1f, IList<Vector2> normals = null, bool swapUV = false)
		{
			//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_005d: 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_017f: 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_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: 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_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: 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_01ba: Unknown result type (might be due to invalid IL or missing references)
			int count = prof.Count;
			if (count < 2 || seg < 3)
			{
				return;
			}
			Vector2[] array = (Vector2[])(object)new Vector2[count];
			if (normals != null)
			{
				for (int i = 0; i < count; i++)
				{
					array[i] = normals[i];
				}
			}
			else
			{
				ProfileNormals(prof, array);
			}
			float[] array2 = new float[count];
			for (int j = 1; j < count; j++)
			{
				array2[j] = array2[j - 1] + Vector2.Distance(prof[j], prof[j - 1]);
			}
			int num = seg + 1;
			int num2 = -1;
			Vector2 val = default(Vector2);
			for (int k = 0; k < count; k++)
			{
				for (int l = 0; l <= seg; l++)
				{
					float num3 = (float)l * ((float)Math.PI * 2f / (float)seg);
					float num4 = Mathf.Cos(num3);
					float num5 = Mathf.Sin(num3);
					((Vector2)(ref val))..ctor((float)l / (float)seg * uTiles, array2[k] * vPerMeter);
					if (swapUV)
					{
						((Vector2)(ref val))..ctor(val.y, val.x);
					}
					int num6 = mb.Add(new Vector3(prof[k].x * num4, prof[k].y, prof[k].x * num5), new Vector3(array[k].x * num4, array[k].y, array[k].x * num5), val);
					if (num2 < 0)
					{
						num2 = num6;
					}
				}
			}
			for (int m = 0; m < count - 1; m++)
			{
				Vector2 val2 = prof[m + 1] - prof[m];
				if (!(((Vector2)(ref val2)).sqrMagnitude < 1E-12f) && (!(prof[m].x <= 0f) || !(prof[m + 1].x <= 0f)))
				{
					for (int n = 0; n < seg; n++)
					{
						int num7 = num2 + m * num + n;
						int d = num7 + 1;
						int num8 = num7 + num;
						int c = num8 + 1;
						mb.Quad(num7, num8, c, d);
					}
				}
			}
		}

		public static void LatheX(MeshBuilder mb, Vector3 origin, IList<Vector2> prof, int seg, float uTiles = 1f, float vPerMeter = 1f, bool swapUV = false)
		{
			//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)
			mb.Push(origin, AlongX);
			Lathe(mb, prof, seg, uTiles, vPerMeter, null, swapUV);
			mb.Pop();
		}

		public static void LatheZ(MeshBuilder mb, Vector3 origin, IList<Vector2> prof, int seg, float uTiles = 1f, float vPerMeter = 1f, bool swapUV = false)
		{
			//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)
			mb.Push(origin, AlongZ);
			Lathe(mb, prof, seg, uTiles, vPerMeter, null, swapUV);
			mb.Pop();
		}

		public static float Tiles(float radius, float perMeter)
		{
			return Mathf.Max(1f, Mathf.Round((float)Math.PI * 2f * radius * perMeter));
		}

		public static void Arc(List<Vector2> list, Vector2 center, float radius, float fromDeg, float toDeg, int steps)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: 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_0032: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i <= steps; i++)
			{
				float num = Mathf.Lerp(fromDeg, toDeg, (float)i / (float)steps) * ((float)Math.PI / 180f);
				list.Add(center + new Vector2(Mathf.Cos(num), Mathf.Sin(num)) * radius);
			}
		}

		public static void Cylinder(MeshBuilder mb, Vector3 a, Vector3 b, float ra, float rb, int seg, bool capA = true, bool capB = true, float uTiles = 1f, float vPerMeter = 1f, bool swapUV = false)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//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_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: 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_002f: 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_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: 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_0082: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = b - a;
			float magnitude = ((Vector3)(ref val)).magnitude;
			if (!(magnitude < 1E-06f))
			{
				List<Vector2> list = new List<Vector2>(6);
				if (capA)
				{
					list.Add(new Vector2(0f, 0f));
					list.Add(new Vector2(ra, 0f));
				}
				list.Add(new Vector2(ra, 0f));
				list.Add(new Vector2(rb, magnitude));
				if (capB)
				{
					list.Add(new Vector2(rb, magnitude));
					list.Add(new Vector2(0f, magnitude));
				}
				mb.Push(a, Quaternion.FromToRotation(Vector3.up, val / magnitude));
				Lathe(mb, list, seg, uTiles, vPerMeter, null, swapUV);
				mb.Pop();
			}
		}

		public static void Cylinder(MeshBuilder mb, Vector3 a, Vector3 b, float r, int seg, bool caps = true, float uTiles = 1f, float vPerMeter = 1f)
		{
			//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)
			Cylinder(mb, a, b, r, r, seg, caps, caps, uTiles, vPerMeter);
		}

		public static void Sphere(MeshBuilder mb, Vector3 c, float r, int seg = 12, int rings = 8)
		{
			//IL_0001: 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_000a: Unknown result type (might be due to invalid IL or missing references)
			Ellipsoid(mb, c, new Vector3(r, r, r), Quaternion.identity, seg, rings);
		}

		public static void Ellipsoid(MeshBuilder mb, Vector3 c, Vector3 radii, Quaternion rot, int seg = 12, int rings = 8)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			Vector2[] array = (Vector2[])(object)new Vector2[rings + 1];
			Vector2[] array2 = (Vector2[])(object)new Vector2[rings + 1];
			for (int i = 0; i <= rings; i++)
			{
				float num = (fl