Decompiled source of RideableTames v1.0.0

RideableTames.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("RideableTames")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("RideableTames")]
[assembly: AssemblyTitle("RideableTames")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace RideableTames
{
	public class MountMarker : MonoBehaviour
	{
		public int Kind;
	}
	internal sealed class MountKind
	{
		public int Index;

		public MountShape Shape;

		public string Trophy;

		public ConfigEntry<bool> Enabled;

		public ConfigEntry<float> WalkSpeed;

		public ConfigEntry<float> RunSpeed;

		public ConfigEntry<float> Stamina;

		public ConfigEntry<Vector3> SaddleOffset;

		public ConfigEntry<Vector3> RiderOffset;

		public ConfigEntry<string> RiderPose;
	}
	internal static class Mounts
	{
		public const string SaddleObjectName = "q8rt_saddle";

		private const string ModelName = "model";

		private const string AttachName = "attach";

		private const float RunStaminaDrain = 2.5f;

		private const float SwimStaminaDrain = 5f;

		private const float StaminaRegen = 1.5f;

		private const float StaminaRegenHungry = 0.5f;

		private static readonly string[] Poses = new string[3] { "attach_asksvin", "attach_moose", "attach_lox" };

		public static readonly List<MountKind> Kinds = new List<MountKind>();

		public static bool AnyEnabled
		{
			get
			{
				foreach (MountKind kind in Kinds)
				{
					if (kind.Enabled.Value)
					{
						return true;
					}
				}
				return false;
			}
		}

		public static void Bind(RideableTamesPlugin plugin)
		{
			Add(plugin, MountShapes.Boar, "TrophyBoar", 4f, 8.5f, 100f, "Tamed boars can wear the saddle and be ridden.");
			Add(plugin, MountShapes.Wolf, "TrophyWolf", 4.5f, 9.5f, 150f, "Tamed wolves can wear the saddle and be ridden.");
			Add(plugin, MountShapes.Deer, "TrophyDeer", 5f, 10f, 150f, "Tamed deer can wear the saddle and be ridden. In the base game deer cannot be tamed: that takes a taming mod such as LetMeTameYou.");
		}

		private static void Add(RideableTamesPlugin plugin, MountShape shape, string trophy, float walk, float run, float stamina, string enabledText)
		{
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			string prefab = shape.Prefab;
			MountKind kind = new MountKind
			{
				Index = Kinds.Count,
				Shape = shape,
				Trophy = trophy
			};
			kind.Enabled = plugin.Rule(prefab, "Enabled", value: true, enabledText + " If false, the saddle cannot be put on and a saddled animal cannot be mounted; the saddle can still be taken off.");
			kind.WalkSpeed = plugin.Rule(prefab, "WalkSpeed", walk, "Speed with a rider at a walk (W), metres per second. On its own the animal ambles at 1.5; a player jogs at 4.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 15f));
			kind.RunSpeed = plugin.Rule(prefab, "RunSpeed", run, "Speed with a rider at a gallop (Shift), metres per second, before the riding skill bonus of up to +25%. A player runs at 7.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(2f, 25f));
			kind.Stamina = plugin.Rule(prefab, "Stamina", stamina, "The animal's own stamina with a saddle on. A gallop costs 2.5 a second and swimming 5 (half that at riding skill 100); it comes back at 1.5 to 3 a second, a third of that when the animal is hungry.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(10f, 1000f));
			kind.SaddleOffset = plugin.Look<Vector3>(prefab, "SaddleOffset", Vector3.zero, "Moves the saddle together with the rider, metres: X to the animal's right, Y up, Z forward. For fitting by eye; applied on the fly when this file is saved.");
			kind.RiderOffset = plugin.Look<Vector3>(prefab, "RiderOffset", Vector3.zero, "Moves only the rider, metres: X to the right, Y up, Z forward. Applied on the fly.");
			kind.RiderPose = plugin.Look(prefab, "RiderPose", Poses[0], "How the rider sits: one of the game's own riding poses, taken from the asksvin, the moose or the lox. Applies the next time someone mounts.", (AcceptableValueBase)(object)new AcceptableValueList<string>(Poses));
			kind.Enabled.SettingChanged += delegate
			{
				SaddleItem.ApplyRecipe();
			};
			kind.SaddleOffset.SettingChanged += delegate
			{
				ApplyLook(kind);
			};
			kind.RiderOffset.SettingChanged += delegate
			{
				ApplyLook(kind);
			};
			kind.RiderPose.SettingChanged += delegate
			{
				ApplyLook(kind);
			};
			Kinds.Add(kind);
		}

		public static MountKind KindOf(Sadle sadle)
		{
			if ((Object)(object)sadle == (Object)null)
			{
				return null;
			}
			MountMarker component = ((Component)sadle).GetComponent<MountMarker>();
			if (!((Object)(object)component != (Object)null) || component.Kind < 0 || component.Kind >= Kinds.Count)
			{
				return null;
			}
			return Kinds[component.Kind];
		}

		public static MountKind KindOf(Character character)
		{
			Tameable component = ((Component)character).GetComponent<Tameable>();
			if (!((Object)(object)component != (Object)null))
			{
				return null;
			}
			return KindOf(component.m_saddle);
		}

		private static MountKind KindOfPrefab(GameObject go)
		{
			string text = PrefabName(go);
			foreach (MountKind kind in Kinds)
			{
				if (kind.Shape.Prefab == text)
				{
					return kind;
				}
			}
			return null;
		}

		private static string PrefabName(GameObject go)
		{
			string name = ((Object)go).name;
			int num = name.IndexOf('(');
			return ((num >= 0) ? name.Substring(0, num) : name).Trim();
		}

		private static Sadle FindSaddle(GameObject go)
		{
			Sadle[] componentsInChildren = go.GetComponentsInChildren<Sadle>(true);
			foreach (Sadle val in componentsInChildren)
			{
				if (((Object)((Component)val).gameObject).name == "q8rt_saddle")
				{
					return val;
				}
			}
			return null;
		}

		public static void SetupPrefabs(ZNetScene scene)
		{
			GameObject prefab = scene.GetPrefab("Lox");
			Tameable val = (((Object)(object)prefab != (Object)null) ? prefab.GetComponent<Tameable>() : null);
			Sadle lox = (((Object)(object)val != (Object)null) ? val.m_saddle : null);
			List<string> list = new List<string>();
			foreach (MountKind kind in Kinds)
			{
				GameObject prefab2 = scene.GetPrefab(kind.Shape.Prefab);
				if ((Object)(object)prefab2 == (Object)null)
				{
					RideableTamesPlugin.Log.LogWarning((object)("Prefab " + kind.Shape.Prefab + " not found, it cannot be ridden."));
					continue;
				}
				if ((Object)(object)FindSaddle(prefab2) == (Object)null)
				{
					try
					{
						AddSaddle(prefab2, kind, lox);
					}
					catch (Exception ex)
					{
						RideableTamesPlugin.Log.LogError((object)("Could not put a saddle mount on " + kind.Shape.Prefab + ": " + ex));
						continue;
					}
				}
				list.Add(kind.Shape.Prefab + (kind.Enabled.Value ? "" : " (off)"));
			}
			RideableTamesPlugin.Log.LogInfo((object)("Saddle mounts ready: " + string.Join(", ", list.ToArray()) + (SaddleLook.Headless ? " (no graphics)" : "") + (((Object)(object)SaddleItem.Drop == (Object)null) ? "; the saddle item is missing!" : "")));
		}

		private static void AddSaddle(GameObject prefab, MountKind kind, Sadle lox)
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Expected O, but got Unknown
			//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_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Expected O, but got Unknown
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_021e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0230: Unknown result type (might be due to invalid IL or missing references)
			MountShape shape = kind.Shape;
			Transform val = FindDeep(prefab.transform, shape.Bone);
			if ((Object)(object)val == (Object)null)
			{
				RideableTamesPlugin.Log.LogWarning((object)(shape.Prefab + " has no bone " + shape.Bone + ", the saddle is fixed to the body."));
				val = prefab.transform;
			}
			GameObject val2 = new GameObject("q8rt_saddle");
			val2.SetActive(false);
			val2.layer = (((Object)(object)lox != (Object)null) ? ((Component)lox).gameObject.layer : LayerMask.NameToLayer("piece_nonsolid"));
			val2.transform.SetParent(prefab.transform, false);
			val2.transform.localPosition = shape.SaddleCenter;
			val2.transform.localRotation = Quaternion.identity;
			val2.transform.localScale = Vector3.one;
			val2.transform.SetParent(val, true);
			val2.AddComponent<MountMarker>().Kind = kind.Index;
			Sadle val3 = val2.AddComponent<Sadle>();
			if ((Object)(object)lox != (Object)null)
			{
				val3.m_drownEffects = lox.m_drownEffects;
			}
			val3.m_hoverText = "$item_q8rt_saddle";
			val3.m_maxUseRange = 6f;
			val3.m_maxStamina = kind.Stamina.Value;
			val3.m_runStaminaDrain = 2.5f;
			val3.m_swimStaminaDrain = 5f;
			val3.m_staminaRegen = 1.5f;
			val3.m_staminaRegenHungry = 0.5f;
			val3.m_detachOffset = new Vector3(shape.CapsuleRadius + 0.5f, 0.2f, 0f);
			val3.m_hoverOffset = 0f;
			SphereCollider obj = val2.AddComponent<SphereCollider>();
			((Collider)obj).isTrigger = true;
			obj.center = new Vector3(0f, 0.12f, 0f);
			obj.radius = shape.HoverRadius;
			GameObject val4 = new GameObject("attach");
			val4.transform.SetParent(val2.transform, false);
			val3.m_attachPoint = val4.transform;
			if (!SaddleLook.Headless)
			{
				GameObject val5 = new GameObject("model");
				SkinnedMeshRenderer componentInChildren = prefab.GetComponentInChildren<SkinnedMeshRenderer>(true);
				val5.layer = (((Object)(object)componentInChildren != (Object)null) ? ((Component)componentInChildren).gameObject.layer : prefab.layer);
				val5.transform.SetParent(val2.transform, false);
				val5.AddComponent<MeshFilter>().sharedMesh = SaddleLook.MountMesh(shape);
				MeshRenderer val6 = val5.AddComponent<MeshRenderer>();
				((Renderer)val6).sharedMaterial = SaddleLook.Material;
				AddToLods(prefab, (Renderer)(object)val6);
			}
			ApplyLookTo(val2.transform, kind);
		}

		private static void AddToLods(GameObject prefab, Renderer renderer)
		{
			LODGroup componentInChildren = prefab.GetComponentInChildren<LODGroup>(true);
			if (!((Object)(object)componentInChildren == (Object)null))
			{
				LOD[] lODs = componentInChildren.GetLODs();
				for (int i = 0; i < lODs.Length; i++)
				{
					Renderer[] array = (Renderer[])(((object)lODs[i].renderers) ?? ((object)new Renderer[0]));
					Renderer[] array2 = (Renderer[])(object)new Renderer[array.Length + 1];
					array.CopyTo(array2, 0);
					array2[array.Length] = renderer;
					lODs[i].renderers = array2;
				}
				componentInChildren.SetLODs(lODs);
			}
		}

		public static void WireInstance(Tameable tameable)
		{
			if ((Object)(object)tameable.m_saddle != (Object)null || (Object)(object)SaddleItem.Drop == (Object)null)
			{
				return;
			}
			MountKind mountKind = KindOfPrefab(((Component)tameable).gameObject);
			if (mountKind == null)
			{
				return;
			}
			Sadle val = FindSaddle(((Component)tameable).gameObject);
			if (!((Object)(object)val == (Object)null))
			{
				tameable.m_saddle = val;
				tameable.m_saddleItem = SaddleItem.Drop;
				tameable.m_dropSaddleOnDeath = true;
				if ((Object)(object)val.m_mountIcon == (Object)null)
				{
					val.m_mountIcon = TrophyIcon(mountKind);
				}
			}
		}

		private static Sprite TrophyIcon(MountKind kind)
		{
			GameObject val = (((Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetItemPrefab(kind.Trophy) : null);
			ItemDrop val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<ItemDrop>() : null);
			if (!((Object)(object)val2 != (Object)null))
			{
				return null;
			}
			return val2.m_itemData.GetIcon();
		}

		public static string Pose(MountKind kind)
		{
			if (Array.IndexOf(Poses, kind.RiderPose.Value) < 0)
			{
				return Poses[0];
			}
			return kind.RiderPose.Value;
		}

		private static void ApplyLook(MountKind kind)
		{
			if ((Object)(object)ZNetScene.instance != (Object)null)
			{
				GameObject prefab = ZNetScene.instance.GetPrefab(kind.Shape.Prefab);
				Sadle val = (((Object)(object)prefab != (Object)null) ? FindSaddle(prefab) : null);
				if ((Object)(object)val != (Object)null)
				{
					ApplyLookTo(((Component)val).transform, kind);
				}
			}
			foreach (Character allCharacter in Character.GetAllCharacters())
			{
				Tameable val2 = (((Object)(object)allCharacter != (Object)null) ? ((Component)allCharacter).GetComponent<Tameable>() : null);
				if ((Object)(object)val2 != (Object)null && KindOf(val2.m_saddle) == kind)
				{
					ApplyLookTo(((Component)val2.m_saddle).transform, kind);
				}
			}
		}

		private static void ApplyLookTo(Transform saddle, MountKind kind)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: 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_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_007f: Unknown result type (might be due to invalid IL or missing references)
			Vector3 value = kind.SaddleOffset.Value;
			Transform val = saddle.Find("model");
			if ((Object)(object)val != (Object)null)
			{
				val.localPosition = value;
			}
			Transform val2 = saddle.Find("attach");
			if ((Object)(object)val2 != (Object)null)
			{
				val2.localPosition = new Vector3(0f, SaddleShape.SeatHeight(kind.Shape.Fit) - 0.01f, 0f) + value + kind.RiderOffset.Value;
				val2.localRotation = Quaternion.identity;
			}
			Sadle component = ((Component)saddle).GetComponent<Sadle>();
			if ((Object)(object)component != (Object)null)
			{
				component.m_attachAnimation = Pose(kind);
			}
		}

		private static Transform FindDeep(Transform root, string name)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			if (((Object)root).name == name)
			{
				return root;
			}
			foreach (Transform item in root)
			{
				Transform val = FindDeep(item, name);
				if ((Object)(object)val != (Object)null)
				{
					return val;
				}
			}
			return null;
		}
	}
	internal sealed class MountShape
	{
		public string Prefab;

		public string Bone;

		public Vector3 SaddleCenter;

		public float CapsuleRadius;

		public float HoverRadius;

		public SaddleFit Fit;
	}
	internal static class MountShapes
	{
		public static readonly MountShape Boar = new MountShape
		{
			Prefab = "Boar",
			Bone = "Spine1",
			SaddleCenter = new Vector3(0f, 0.953f, 0f),
			CapsuleRadius = 0.5f,
			HoverRadius = 0.55f,
			Fit = new SaddleFit
			{
				BackA = 0.28f,
				BackB = 0.575f,
				Lift = 0.01f,
				BackLine = new float[13]
				{
					0.025f, 0.02f, 0.014f, 0.008f, 0.003f, 0f, 0f, 0.006f, 0.011f, 0.017f,
					0.021f, 0.025f, 0.029f
				},
				BlanketHalfLength = 0.24f,
				BlanketDrape = 0.2f,
				SeatHalfLength = 0.17f,
				SeatDrape = 0.1f,
				GirthZ = 0.1f,
				GirthA = 0.246f,
				GirthB = 0.346f,
				GirthCenterY = -0.313f
			}
		};

		public static readonly MountShape Wolf = new MountShape
		{
			Prefab = "Wolf",
			Bone = "Spine1",
			SaddleCenter = new Vector3(0f, 1.129f, -0.1f),
			CapsuleRadius = 0.65f,
			HoverRadius = 0.62f,
			Fit = new SaddleFit
			{
				BackA = 0.245f,
				BackB = 0.25f,
				Lift = 0.02f,
				BackLine = new float[13]
				{
					-0.023f, -0.019f, -0.016f, -0.012f, -0.009f, -0.005f, 0f, 0.005f, 0.009f, 0.015f,
					0.028f, 0.042f, 0.058f
				},
				BlanketHalfLength = 0.24f,
				BlanketDrape = 0.2f,
				SeatHalfLength = 0.17f,
				SeatDrape = 0.1f,
				GirthZ = 0.04f,
				GirthA = 0.23f,
				GirthB = 0.273f,
				GirthCenterY = -0.252f
			}
		};

		public static readonly MountShape Deer = new MountShape
		{
			Prefab = "Deer",
			Bone = "Spine1",
			SaddleCenter = new Vector3(0f, 1.338f, -0.08f),
			CapsuleRadius = 0.8f,
			HoverRadius = 0.72f,
			Fit = new SaddleFit
			{
				BackA = 0.29f,
				BackB = 0.585f,
				Lift = 0.01f,
				BackLine = new float[13]
				{
					0.024f, 0.02f, 0.016f, 0.011f, 0.007f, 0.003f, 0f, -0.002f, -0.005f, 0f,
					0.011f, 0.022f, 0.033f
				},
				BlanketHalfLength = 0.26f,
				BlanketDrape = 0.22f,
				SeatHalfLength = 0.18f,
				SeatDrape = 0.11f,
				GirthZ = 0.1f,
				GirthA = 0.274f,
				GirthB = 0.338f,
				GirthCenterY = -0.323f
			}
		};

		public static readonly MountShape[] All = new MountShape[3] { Boar, Wolf, Deer };
	}
	[HarmonyPatch(typeof(ZNetScene), "Awake")]
	internal static class ZNetSceneAwakePatch
	{
		private static void Postfix(ZNetScene __instance)
		{
			Mounts.SetupPrefabs(__instance);
		}
	}
	[HarmonyPatch(typeof(Tameable), "Awake")]
	internal static class TameableAwakePatch
	{
		private static void Prefix(Tameable __instance)
		{
			Mounts.WireInstance(__instance);
		}
	}
	[HarmonyPatch(typeof(Tameable), "UseItem")]
	internal static class TameableUseItemPatch
	{
		private static bool Prefix(Tameable __instance, Humanoid user, ItemData item, ref bool __result)
		{
			if (!SaddleItem.IsSaddle(item))
			{
				return true;
			}
			MountKind mountKind = Mounts.KindOf(__instance.m_saddle);
			if (mountKind == null || mountKind.Enabled.Value)
			{
				return true;
			}
			((Character)user).Message((MessageType)2, "$q8rt_msg_off", 0, (Sprite)null, false);
			__result = true;
			return false;
		}
	}
	[HarmonyPatch(typeof(Sadle), "Interact")]
	internal static class SadleInteractPatch
	{
		private static bool Prefix(Sadle __instance, Humanoid character, bool repeat, bool alt, ref bool __result)
		{
			if (repeat || alt)
			{
				return true;
			}
			MountKind mountKind = Mounts.KindOf(__instance);
			if (mountKind == null || mountKind.Enabled.Value)
			{
				return true;
			}
			((Character)character).Message((MessageType)2, "$q8rt_msg_off", 0, (Sprite)null, false);
			__result = false;
			return false;
		}
	}
	[HarmonyPatch(typeof(Sadle), "GetMaxStamina")]
	internal static class SadleMaxStaminaPatch
	{
		private static void Postfix(Sadle __instance, ref float __result)
		{
			MountKind mountKind = Mounts.KindOf(__instance);
			if (mountKind != null)
			{
				__result = Mathf.Max(1f, mountKind.Stamina.Value);
			}
		}
	}
	[HarmonyPatch(typeof(Character), "GetJogSpeedFactor")]
	internal static class CharacterJogSpeedPatch
	{
		private static void Postfix(Character __instance, ref float __result)
		{
			if (__instance.HaveRider())
			{
				MountKind mountKind = Mounts.KindOf(__instance);
				if (mountKind != null && __instance.m_speed > 0.01f)
				{
					__result *= mountKind.WalkSpeed.Value / __instance.m_speed;
				}
			}
		}
	}
	[HarmonyPatch(typeof(Character), "GetRunSpeedFactor")]
	internal static class CharacterRunSpeedPatch
	{
		private static void Postfix(Character __instance, ref float __result)
		{
			if (__instance.HaveRider())
			{
				MountKind mountKind = Mounts.KindOf(__instance);
				if (mountKind != null && __instance.m_runSpeed > 0.01f)
				{
					__result *= mountKind.RunSpeed.Value / __instance.m_runSpeed;
				}
			}
		}
	}
	[HarmonyPatch(/*Could not decode attribute arguments.*/)]
	internal static class LegacyItemPatch
	{
		private static void Postfix(int hash, ref GameObject prefab, ref bool __result)
		{
			if (!__result && hash == SaddleItem.LegacyHash && (Object)(object)SaddleItem.Prefab != (Object)null)
			{
				prefab = SaddleItem.Prefab;
				__result = true;
			}
		}
	}
	[HarmonyPatch(typeof(ZNetScene), "GetPrefab", new Type[] { typeof(int) })]
	internal static class LegacyPrefabPatch
	{
		private static void Postfix(int hash, ref GameObject __result)
		{
			if ((Object)(object)__result == (Object)null && hash == SaddleItem.LegacyHash && (Object)(object)SaddleItem.Prefab != (Object)null)
			{
				__result = SaddleItem.Prefab;
			}
		}
	}
	[BepInPlugin("qua8ion.valheim.rideabletames", "RideableTames", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInIncompatibility("xneliox.rideableboars")]
	[BepInIncompatibility("valheim.boarriding")]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	public class RideableTamesPlugin : BaseUnityPlugin
	{
		public const string PluginGuid = "qua8ion.valheim.rideabletames";

		public const string PluginName = "RideableTames";

		public const string PluginVersion = "1.0.0";

		internal static ManualLogSource Log;

		internal static ConfigEntry<string> Recipe;

		internal static ConfigEntry<string> Station;

		internal static ConfigEntry<int> StationLevel;

		private FileSystemWatcher configWatcher;

		private volatile bool configChanged;

		private void Awake()
		{
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			Recipe = Rule("Saddle", "Recipe", "LeatherScraps:5,DeerHide:2,BronzeNails:4", "What the saddle is made of: Item:amount pairs separated by commas (prefab names). One saddle fits a boar, a wolf and a deer alike.");
			Station = Rule("Saddle", "Station", "Workbench", "Where the saddle is made: Workbench, Forge, Stonecutter, ArtisanTable, BlackForge, GaldrTable, or a station prefab name.");
			StationLevel = Rule("Saddle", "StationLevel", 2, "Station level needed to make the saddle.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 10));
			Mounts.Bind(this);
			AddLocalization();
			Recipe.SettingChanged += delegate
			{
				SaddleItem.ApplyRecipe();
			};
			Station.SettingChanged += delegate
			{
				SaddleItem.ApplyRecipe();
			};
			StationLevel.SettingChanged += delegate
			{
				SaddleItem.ApplyRecipe();
			};
			SynchronizationManager.OnConfigurationSynchronized += delegate
			{
				SaddleItem.ApplyRecipe();
			};
			PrefabManager.OnVanillaPrefabsAvailable += SaddleItem.Register;
			new Harmony("qua8ion.valheim.rideabletames").PatchAll(Assembly.GetExecutingAssembly());
			WatchConfigFile();
		}

		internal ConfigEntry<T> Rule<T>(string section, string key, T value, string description, AcceptableValueBase range = null)
		{
			//IL_0015: 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_0022: Expected O, but got Unknown
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			return ((BaseUnityPlugin)this).Config.Bind<T>(section, key, value, new ConfigDescription(description, range, new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true
			} }));
		}

		internal ConfigEntry<T> Look<T>(string section, string key, T value, string description, AcceptableValueBase range = null)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			return ((BaseUnityPlugin)this).Config.Bind<T>(section, key, value, new ConfigDescription(description, range, Array.Empty<object>()));
		}

		private void WatchConfigFile()
		{
			try
			{
				configWatcher = new FileSystemWatcher(Path.GetDirectoryName(((BaseUnityPlugin)this).Config.ConfigFilePath), Path.GetFileName(((BaseUnityPlugin)this).Config.ConfigFilePath));
				configWatcher.NotifyFilter = NotifyFilters.Size | NotifyFilters.LastWrite | NotifyFilters.CreationTime;
				configWatcher.Changed += delegate
				{
					configChanged = true;
				};
				configWatcher.Created += delegate
				{
					configChanged = true;
				};
				configWatcher.EnableRaisingEvents = true;
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)("Config file will not be reloaded on the fly: " + ex.Message));
			}
		}

		private void Update()
		{
			if (!configChanged)
			{
				return;
			}
			configChanged = false;
			try
			{
				((BaseUnityPlugin)this).Config.Reload();
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)("Could not reload the config file: " + ex.Message));
			}
		}

		private void OnDestroy()
		{
			if (configWatcher != null)
			{
				configWatcher.Dispose();
			}
		}

		private static void AddLocalization()
		{
			CustomLocalization localization = LocalizationManager.Instance.GetLocalization();
			string text = "English";
			localization.AddTranslation(ref text, new Dictionary<string, string>
			{
				{ "item_q8rt_saddle", "Saddle" },
				{ "item_q8rt_saddle_desc", "A light leather saddle on a woollen blanket. Fits a tamed boar, wolf or deer: look at the animal and use the saddle from your hotbar." },
				{ "q8rt_msg_off", "Riding this animal is turned off" }
			});
			text = "Russian";
			localization.AddTranslation(ref text, new Dictionary<string, string>
			{
				{ "item_q8rt_saddle", "Седло" },
				{ "item_q8rt_saddle_desc", "Лёгкое кожаное седло на шерстяной попоне. Подходит ручному кабану, волку и оленю: посмотрите на зверя и используйте седло с панели быстрого доступа." },
				{ "q8rt_msg_off", "Ездить на этом звере нельзя" }
			});
		}
	}
	internal static class SaddleItem
	{
		public const string PrefabName = "Q8_TameSaddle";

		public const string NameToken = "$item_q8rt_saddle";

		public const string DescriptionToken = "$item_q8rt_saddle_desc";

		private const string BasePrefabName = "SaddleLox";

		public static readonly int LegacyHash = StringExtensionMethods.GetStableHashCode("BoarSaddle");

		public static GameObject Prefab;

		public static ItemDrop Drop;

		public static bool IsSaddle(ItemData item)
		{
			if (item != null && item.m_shared != null)
			{
				return item.m_shared.m_name == "$item_q8rt_saddle";
			}
			return false;
		}

		public static void Register()
		{
			//IL_00dd: 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_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Expected O, but got Unknown
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Expected O, but got Unknown
			PrefabManager.OnVanillaPrefabsAvailable -= Register;
			GameObject val = PrefabManager.Instance.CreateClonedPrefab("Q8_TameSaddle", "SaddleLox");
			ItemDrop val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<ItemDrop>() : null);
			if ((Object)(object)val2 == (Object)null)
			{
				RideableTamesPlugin.Log.LogError((object)"Base prefab SaddleLox not found, the saddle is not added.");
				return;
			}
			bool headless = SaddleLook.Headless;
			if (!headless)
			{
				try
				{
					BuildVisuals(val);
				}
				catch (Exception ex)
				{
					RideableTamesPlugin.Log.LogWarning((object)("Could not build the saddle model: " + ex.Message));
				}
			}
			val2.m_autoDestroy = false;
			SharedData shared = val2.m_itemData.m_shared;
			shared.m_name = "$item_q8rt_saddle";
			shared.m_description = "$item_q8rt_saddle_desc";
			shared.m_weight = 8f;
			shared.m_teleportable = true;
			shared.m_value = 0;
			val2.m_itemData.m_dropPrefab = val;
			ItemConfig val3 = new ItemConfig
			{
				Name = "$item_q8rt_saddle",
				Description = "$item_q8rt_saddle_desc"
			};
			if (!headless)
			{
				val3.CraftingStation = RideableTamesPlugin.Station.Value;
				val3.MinStationLevel = RideableTamesPlugin.StationLevel.Value;
				val3.Amount = 1;
				val3.Enabled = Mounts.AnyEnabled;
				val3.Icons = (Sprite[])(object)new Sprite[1] { SaddleLook.Icon };
				val3.Requirements = ParseRecipe(RideableTamesPlugin.Recipe.Value).ToArray();
			}
			if (!ItemManager.Instance.AddItem(new CustomItem(val, false, val3)))
			{
				RideableTamesPlugin.Log.LogError((object)"Jotunn rejected the saddle item.");
				return;
			}
			Prefab = val;
			Drop = val2;
		}

		private static void BuildVisuals(GameObject prefab)
		{
			//IL_0050: 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_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Expected O, but got Unknown
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			for (int num = prefab.transform.childCount - 1; num >= 0; num--)
			{
				Object.DestroyImmediate((Object)(object)((Component)prefab.transform.GetChild(num)).gameObject);
			}
			LODGroup component = prefab.GetComponent<LODGroup>();
			if ((Object)(object)component != (Object)null)
			{
				Object.DestroyImmediate((Object)(object)component);
			}
			Mesh itemMesh = SaddleLook.ItemMesh;
			Bounds bounds = itemMesh.bounds;
			GameObject val = new GameObject("model");
			val.layer = prefab.layer;
			val.transform.SetParent(prefab.transform, false);
			val.transform.localPosition = new Vector3(0f, 0f - ((Bounds)(ref bounds)).min.y, 0f);
			val.AddComponent<MeshFilter>().sharedMesh = itemMesh;
			((Renderer)val.AddComponent<MeshRenderer>()).sharedMaterial = SaddleLook.Material;
			if ((Object)(object)prefab.GetComponentInChildren<Collider>(true) == (Object)null)
			{
				BoxCollider obj = prefab.AddComponent<BoxCollider>();
				obj.center = ((Bounds)(ref bounds)).center + val.transform.localPosition;
				obj.size = ((Bounds)(ref bounds)).size;
			}
		}

		internal static List<RequirementConfig> ParseRecipe(string text)
		{
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: 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
			List<RequirementConfig> list = new List<RequirementConfig>();
			string[] array = (text ?? "").Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries);
			foreach (string text2 in array)
			{
				string[] array2 = text2.Split(new char[1] { ':' });
				if (array2.Length != 2 || array2[0].Trim().Length == 0 || !int.TryParse(array2[1].Trim(), out var result) || result < 1)
				{
					RideableTamesPlugin.Log.LogWarning((object)("Recipe entry '" + text2 + "' is ignored, expected Item:amount."));
				}
				else
				{
					list.Add(new RequirementConfig(array2[0].Trim(), result, 0, true));
				}
			}
			if (list.Count == 0)
			{
				list.Add(new RequirementConfig("LeatherScraps", 5, 0, true));
			}
			return list;
		}

		internal static void ApplyRecipe()
		{
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: 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_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Expected O, but got Unknown
			if ((Object)(object)ObjectDB.instance == (Object)null)
			{
				return;
			}
			Recipe val = ObjectDB.instance.m_recipes.Find((Recipe r) => (Object)(object)r != (Object)null && (Object)(object)r.m_item != (Object)null && ((Object)((Component)r.m_item).gameObject).name == "Q8_TameSaddle");
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			val.m_enabled = Mounts.AnyEnabled;
			val.m_minStationLevel = Mathf.Max(1, RideableTamesPlugin.StationLevel.Value);
			string internalName = CraftingStations.GetInternalName(RideableTamesPlugin.Station.Value);
			if (string.IsNullOrEmpty(internalName))
			{
				val.m_craftingStation = null;
			}
			else if ((Object)(object)ZNetScene.instance != (Object)null)
			{
				GameObject prefab = ZNetScene.instance.GetPrefab(internalName);
				CraftingStation val2 = (((Object)(object)prefab != (Object)null) ? prefab.GetComponent<CraftingStation>() : null);
				if ((Object)(object)val2 != (Object)null)
				{
					val.m_craftingStation = val2;
				}
				else
				{
					RideableTamesPlugin.Log.LogWarning((object)("Crafting station '" + RideableTamesPlugin.Station.Value + "' does not exist, the station is left as it was."));
				}
			}
			List<Requirement> list = new List<Requirement>();
			foreach (RequirementConfig item in ParseRecipe(RideableTamesPlugin.Recipe.Value))
			{
				GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(item.Item);
				ItemDrop val3 = (((Object)(object)itemPrefab != (Object)null) ? itemPrefab.GetComponent<ItemDrop>() : null);
				if ((Object)(object)val3 == (Object)null)
				{
					RideableTamesPlugin.Log.LogWarning((object)("Recipe item '" + item.Item + "' does not exist and is ignored."));
					continue;
				}
				list.Add(new Requirement
				{
					m_resItem = val3,
					m_amount = item.Amount,
					m_amountPerLevel = 0,
					m_recover = true
				});
			}
			if (list.Count > 0)
			{
				val.m_resources = list.ToArray();
			}
		}
	}
	internal static class SaddleLook
	{
		private static Material material;

		private static Sprite icon;

		private static Mesh itemMesh;

		private static readonly Dictionary<MountShape, Mesh> mountMeshes = new Dictionary<MountShape, Mesh>();

		public static bool Headless => (int)SystemInfo.graphicsDeviceType == 4;

		public static Material Material
		{
			get
			{
				if ((Object)(object)material == (Object)null)
				{
					material = CreateMaterial();
				}
				return material;
			}
		}

		public static Sprite Icon
		{
			get
			{
				//IL_0031: 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)
				if ((Object)(object)icon == (Object)null)
				{
					Texture2D val = LoadTexture("icon.png");
					icon = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f);
					((Object)icon).name = "q8rt_saddle_icon";
				}
				return icon;
			}
		}

		public static Mesh ItemMesh
		{
			get
			{
				if ((Object)(object)itemMesh == (Object)null)
				{
					itemMesh = ToMesh(SaddleShape.Build(MountShapes.Boar.Fit, withGirth: false), "q8rt_saddle_item");
				}
				return itemMesh;
			}
		}

		public static Mesh MountMesh(MountShape shape)
		{
			if (!mountMeshes.TryGetValue(shape, out var value) || (Object)(object)value == (Object)null)
			{
				value = ToMesh(SaddleShape.Build(shape.Fit, withGirth: true), "q8rt_saddle_" + shape.Prefab);
				mountMeshes[shape] = value;
			}
			return value;
		}

		private static Mesh ToMesh(MeshData data, 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_000c: 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_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: 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_004d: Expected O, but got Unknown
			Mesh val = new Mesh
			{
				name = name
			};
			val.SetVertices(data.Vertices);
			val.SetNormals(data.Normals);
			val.SetUVs(0, data.Uv);
			val.SetTriangles(data.Triangles, 0);
			val.RecalculateBounds();
			((Object)val).hideFlags = (HideFlags)32;
			return val;
		}

		private static Material CreateMaterial()
		{
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Expected O, but got Unknown
			//IL_0084: 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_0047: Expected O, but got Unknown
			GameObject prefab = PrefabManager.Instance.GetPrefab("SaddleLox");
			MeshRenderer val = (((Object)(object)prefab != (Object)null) ? prefab.GetComponentInChildren<MeshRenderer>(true) : null);
			Material val2;
			if ((Object)(object)val != (Object)null && (Object)(object)((Renderer)val).sharedMaterial != (Object)null)
			{
				val2 = new Material(((Renderer)val).sharedMaterial);
			}
			else
			{
				RideableTamesPlugin.Log.LogWarning((object)"The lox saddle material was not found, the saddle uses a plain one.");
				val2 = new Material(Shader.Find("Standard"));
			}
			((Object)val2).name = "q8rt_saddle";
			val2.mainTexture = (Texture)(object)LoadTexture("saddle.png");
			val2.color = Color.white;
			string[] array = new string[3] { "_BumpMap", "_MetallicGlossMap", "_EmissionMap" };
			foreach (string text in array)
			{
				if (val2.HasProperty(text))
				{
					val2.SetTexture(text, (Texture)null);
				}
			}
			array = new string[3] { "_NORMALMAP", "_METALLICGLOSSMAP", "_EMISSION" };
			foreach (string text2 in array)
			{
				val2.DisableKeyword(text2);
			}
			if (val2.HasProperty("_Metallic"))
			{
				val2.SetFloat("_Metallic", 0f);
			}
			if (val2.HasProperty("_Glossiness"))
			{
				val2.SetFloat("_Glossiness", 0.15f);
			}
			((Object)val2).hideFlags = (HideFlags)32;
			return val2;
		}

		private static Texture2D LoadTexture(string resourceName)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Expected O, but got Unknown
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Expected O, but got Unknown
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: 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_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_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, true);
			try
			{
				using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName);
				if (stream == null)
				{
					throw new FileNotFoundException("embedded resource is missing");
				}
				byte[] array = new byte[stream.Length];
				int num;
				for (int i = 0; i < array.Length; i += num)
				{
					num = stream.Read(array, i, array.Length - i);
					if (num <= 0)
					{
						break;
					}
				}
				Type type = Type.GetType("UnityEngine.ImageConversion, UnityEngine.ImageConversionModule");
				MethodInfo methodInfo = ((type != null) ? type.GetMethod("LoadImage", new Type[2]
				{
					typeof(Texture2D),
					typeof(byte[])
				}) : null);
				if (methodInfo == null || !(bool)methodInfo.Invoke(null, new object[2] { val, array }))
				{
					throw new InvalidDataException("the image could not be decoded");
				}
			}
			catch (Exception ex)
			{
				RideableTamesPlugin.Log.LogWarning((object)("Could not load " + resourceName + ": " + ex.Message));
				val = new Texture2D(2, 2, (TextureFormat)4, false);
				Color32 val2 = default(Color32);
				((Color32)(ref val2))..ctor((byte)110, (byte)70, (byte)38, byte.MaxValue);
				val.SetPixels32((Color32[])(object)new Color32[4] { val2, val2, val2, val2 });
				val.Apply();
			}
			((Object)val).name = "q8rt_" + Path.GetFileNameWithoutExtension(resourceName);
			((Texture)val).wrapMode = (TextureWrapMode)1;
			((Texture)val).filterMode = (FilterMode)2;
			((Texture)val).anisoLevel = 4;
			((Object)val).hideFlags = (HideFlags)32;
			return val;
		}
	}
	internal sealed class SaddleFit
	{
		public float BackA;

		public float BackB;

		public float Lift;

		public float[] BackLine;

		public float BlanketHalfLength;

		public float BlanketDrape;

		public float SeatHalfLength;

		public float SeatDrape;

		public float GirthZ;

		public float GirthA;

		public float GirthB;

		public float GirthCenterY;

		public float BackLineAt(float z)
		{
			float num = (z + 0.3f) / 0.05f;
			int num2 = BackLine.Length - 1;
			if (num <= 0f)
			{
				return BackLine[0];
			}
			if (num >= (float)num2)
			{
				return BackLine[num2];
			}
			int num3 = (int)num;
			return Mathf.Lerp(BackLine[num3], BackLine[num3 + 1], num - (float)num3);
		}
	}
	internal sealed class MeshData
	{
		public readonly List<Vector3> Vertices = new List<Vector3>();

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

		public readonly List<Vector2> Uv = new List<Vector2>();

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

		public void AddGrid(int nu, int nv, Func<int, int, Vector3> position, Func<int, int, Vector2> uv, Vector3 outward)
		{
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: 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_00ab: 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_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)
			//IL_00ba: 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_00c5: 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)
			//IL_0037: 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_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			int count = Vertices.Count;
			for (int i = 0; i <= nv; i++)
			{
				for (int j = 0; j <= nu; j++)
				{
					Vertices.Add(position(j, i));
					Uv.Add(uv(j, i));
					Normals.Add(Vector3.zero);
				}
			}
			int num = nu / 2;
			int num2 = nv / 2;
			Vector3 val = Vertices[count + num2 * (nu + 1) + num];
			Vector3 val2 = Vertices[count + (num2 + 1) * (nu + 1) + num];
			Vector3 val3 = Vertices[count + num2 * (nu + 1) + num + 1];
			bool flip = Vector3.Dot(Vector3.Cross(val2 - val, val3 - val), outward) < 0f;
			for (int k = 0; k < nv; k++)
			{
				for (int l = 0; l < nu; l++)
				{
					int num3 = count + k * (nu + 1) + l;
					int num4 = num3 + 1;
					int num5 = num3 + nu + 1;
					int c = num5 + 1;
					AddTriangle(num3, num5, num4, flip);
					AddTriangle(num4, num5, c, flip);
				}
			}
			for (int m = count; m < Vertices.Count; m++)
			{
				List<Vector3> normals = Normals;
				int index = m;
				Vector3 val4 = Normals[m];
				normals[index] = ((Vector3)(ref val4)).normalized;
			}
		}

		private void AddTriangle(int a, int b, int c, bool flip)
		{
			//IL_0035: 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_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: 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_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: 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_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			if (flip)
			{
				int num = b;
				b = c;
				c = num;
			}
			Triangles.Add(a);
			Triangles.Add(b);
			Triangles.Add(c);
			Vector3 val = Vector3.Cross(Vertices[b] - Vertices[a], Vertices[c] - Vertices[a]);
			List<Vector3> normals = Normals;
			int index = a;
			normals[index] += val;
			normals = Normals;
			index = b;
			normals[index] += val;
			normals = Normals;
			index = c;
			normals[index] += val;
		}
	}
	internal static class SaddleShape
	{
		private const float Gap = 0.008f;

		private const float BlanketThickness = 0.012f;

		private const float SeatGap = 0.002f;

		private const float SeatThickness = 0.028f;

		private const float CantleRise = 0.075f;

		private const float PommelRise = 0.05f;

		private const float GirthWidth = 0.045f;

		private const float GirthThickness = 0.008f;

		private const float GirthGap = 0.006f;

		private static readonly Rect Cloth = new Rect(0.5f, 0.5f, 0.5f, 0.5f);

		private static readonly Rect Leather = new Rect(0f, 0.5f, 0.5f, 0.5f);

		private static readonly Rect Strap = new Rect(0f, 0.375f, 1f, 0.125f);

		private static readonly Rect Dark = new Rect(0f, 0.25f, 1f, 0.125f);

		public static float SeatHeight(SaddleFit fit)
		{
			return fit.Lift + 0.008f + 0.012f + 0.002f + 0.028f;
		}

		public static MeshData Build(SaddleFit fit, bool withGirth)
		{
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: 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_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			MeshData meshData = new MeshData();
			float num = PhiForDepth(fit, fit.BlanketDrape);
			float maxPhi = PhiForDepth(fit, fit.SeatDrape);
			Shell(meshData, fit, 14, 10, num, fit.BlanketHalfLength, (float u, float w) => 0.008f, (float u, float w) => 0.02f, Cloth, Cloth, Cloth);
			float seatBase = 0.022f;
			Shell(meshData, fit, 10, 12, maxPhi, fit.SeatHalfLength, (float u, float w) => seatBase, (float u, float w) => seatBase + 0.028f + SeatBump(u, w), Leather, Dark, Leather);
			if (withGirth)
			{
				Girth(meshData, fit, num);
			}
			return meshData;
		}

		private static Vector3 Surface(SaddleFit fit, float phi, float z, float h)
		{
			//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_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: 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_0060: 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_0067: Unknown result type (might be due to invalid IL or missing references)
			float num = Mathf.Sin(phi);
			float num2 = Mathf.Cos(phi);
			Vector3 val = new Vector3(fit.BackB * num, fit.BackA * num2, 0f);
			Vector3 normalized = ((Vector3)(ref val)).normalized;
			float num3 = fit.Lift - fit.BackB + fit.BackB * num2 + fit.BackLineAt(z);
			return new Vector3(fit.BackA * num, num3, z) + normalized * h;
		}

		private static float PhiForDepth(SaddleFit fit, float depth)
		{
			return Mathf.Acos(Mathf.Clamp((fit.BackB - fit.Lift - depth) / fit.BackB, -1f, 1f));
		}

		private static float SeatBump(float u, float w)
		{
			float num = Mathf.Clamp01((0f - u - 0.35f) / 0.65f);
			float num2 = Mathf.Clamp01((u - 0.5f) / 0.5f);
			float num3 = Mathf.Cos(w * (float)Math.PI * 0.5f);
			num3 *= num3;
			return (0.075f * num * num + 0.05f * num2 * num2) * num3;
		}

		private static void Shell(MeshData mesh, SaddleFit fit, int nPhi, int nZ, float maxPhi, float halfLength, Func<float, float, float> inner, Func<float, float, float> outer, Rect top, Rect bottom, Rect edge)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: 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_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: 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_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: 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_0246: Unknown result type (might be due to invalid IL or missing references)
			Func<int, float> w = (int i) => (float)i / (float)nPhi * 2f - 1f;
			Func<int, float> u = (int j) => (float)j / (float)nZ * 2f - 1f;
			Func<float, float, float, Vector3> at = (float num4, float num3, float h) => Surface(fit, num3 * maxPhi, num4 * halfLength, h);
			mesh.AddGrid(nPhi, nZ, (int i, int j) => at(u(j), w(i), outer(u(j), w(i))), (int i, int j) => Map(top, (float)i / (float)nPhi, (float)j / (float)nZ), Vector3.up);
			mesh.AddGrid(nPhi, nZ, (int i, int j) => at(u(j), w(i), inner(u(j), w(i))), (int i, int j) => Map(bottom, (float)i / (float)nPhi, (float)j / (float)nZ), Vector3.down);
			int[] array = new int[2] { -1, 1 };
			Vector3 outward = default(Vector3);
			foreach (int side in array)
			{
				float uu = side;
				mesh.AddGrid(nPhi, 1, (int i, int k) => at(uu, w(i), (k == 0) ? inner(uu, w(i)) : outer(uu, w(i))), (int i, int k) => Map(edge, (float)i / (float)nPhi, (side > 0) ? (0.99f - (float)k * 0.02f) : (0.01f + (float)k * 0.02f)), new Vector3(0f, 0f, (float)side));
				float ww = side;
				float num2 = ww * maxPhi;
				((Vector3)(ref outward))..ctor((float)side * fit.BackA * Mathf.Cos(num2), (0f - fit.BackB) * Mathf.Sin(Mathf.Abs(num2)), 0f);
				mesh.AddGrid(1, nZ, (int k, int j) => at(u(j), ww, (k == 0) ? inner(u(j), ww) : outer(u(j), ww)), (int k, int j) => Map(edge, (side > 0) ? (0.99f - (float)k * 0.02f) : (0.01f + (float)k * 0.02f), (float)j / (float)nZ), outward);
			}
		}

		private static void Girth(MeshData mesh, SaddleFit fit, float blanketPhi)
		{
			//IL_0052: 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_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			float a = fit.GirthA + 0.006f;
			float b = fit.GirthB + 0.006f;
			float num = Surface(fit, blanketPhi, fit.GirthZ, 0.008f).y + 0.02f;
			float start = Mathf.Acos(Mathf.Clamp((num - fit.GirthCenterY) / b, -1f, 1f));
			float end = (float)Math.PI * 2f - start;
			Func<int, float> psi = (int i) => Mathf.Lerp(start, end, (float)i / 36f);
			Func<float, float, float, Vector3> at = delegate(float angle, float num6, float h)
			{
				//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_002b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: 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_0053: 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_005a: Unknown result type (might be due to invalid IL or missing references)
				float num4 = Mathf.Sin(angle);
				float num5 = Mathf.Cos(angle);
				Vector3 val = new Vector3(b * num4, a * num5, 0f);
				Vector3 normalized = ((Vector3)(ref val)).normalized;
				return new Vector3(a * num4, fit.GirthCenterY + b * num5, num6) + normalized * h;
			};
			float z0 = fit.GirthZ - 0.0225f;
			float z1 = fit.GirthZ + 0.0225f;
			mesh.AddGrid(36, 1, (int i, int k) => at(psi(i), (k == 0) ? z0 : z1, 0.008f), (int i, int k) => Map(Strap, (float)i / 36f, k), Vector3.down);
			mesh.AddGrid(36, 1, (int i, int k) => at(psi(i), (k == 0) ? z0 : z1, 0f), (int i, int k) => Map(Dark, (float)i / 36f, k), Vector3.up);
			int[] array = new int[2] { -1, 1 };
			foreach (int num3 in array)
			{
				float z2 = ((num3 > 0) ? z1 : z0);
				mesh.AddGrid(36, 1, (int i, int k) => at(psi(i), z2, (float)k * 0.008f), (int i, int k) => Map(Dark, (float)i / 36f, 0.5f), new Vector3(0f, 0f, (float)num3));
			}
		}

		private static Vector2 Map(Rect area, float u, float v)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			return new Vector2(((Rect)(ref area)).xMin + 0.0009765625f + Mathf.Clamp01(u) * (((Rect)(ref area)).width - 0.001953125f), ((Rect)(ref area)).yMin + 0.0009765625f + Mathf.Clamp01(v) * (((Rect)(ref area)).height - 0.001953125f));
		}
	}
}