Decompiled source of OctoPack addon Lantern v1.2.3

plugins/OctoPack_addon_Lantern/OctoPack_addon_Lantern.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using OctoPack;
using OctoPack_addon_Lantern;
using OctoPack_addon_LanternArm;
using TMPro;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("OctoPack_addon_Lantern")]
[assembly: AssemblyCompany("Octodad")]
[assembly: AssemblyProduct("OctoPack_addon_Lantern")]
[assembly: AssemblyFileVersion("1.2.3.0")]
[assembly: AssemblyMetadata("AI_Assisted_Creation", "Created and maintained with assistance from OpenAI Codex.")]
[assembly: AssemblyMetadata("AI_Model_Vendor", "OpenAI")]
[assembly: AssemblyVersion("1.2.3.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 OctoPack_addon_LanternArm
{
	internal sealed class ArmConfigMigration
	{
		private readonly ConfigFile target;

		private readonly ConfigFile legacy;

		private readonly HashSet<string> existing;

		private readonly HashSet<string> oldKeys;

		private readonly ConfigEntry<bool> completed;

		internal ArmConfigMigration(ConfigFile config, string legacyPath)
		{
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Expected O, but got Unknown
			target = config;
			existing = ReadKeys(config.ConfigFilePath);
			completed = target.Bind<bool>("Arm.Migration", "ImportedLegacyConfig", false, "Internal migration marker. Existing Arm.* settings always take precedence over the old standalone config.");
			if (!completed.Value && File.Exists(legacyPath))
			{
				oldKeys = ReadKeys(legacyPath);
				legacy = new ConfigFile(legacyPath, false);
				legacy.SaveOnConfigSet = false;
			}
		}

		internal ConfigEntry<T> Bind<T>(string section, string key, T fallback, string description)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			return Bind(section, key, fallback, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>()));
		}

		internal ConfigEntry<T> Bind<T>(string section, string key, T fallback, ConfigDescription description)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected O, but got Unknown
			string text = "Arm." + section;
			bool num = existing.Contains(Id(text, key)) || target.ContainsKey(new ConfigDefinition(text, key));
			ConfigEntry<T> val = target.Bind<T>(text, key, fallback, description);
			if (!num && legacy != null && oldKeys.Contains(Id(section, key)))
			{
				val.Value = legacy.Bind<T>(section, key, fallback, description).Value;
			}
			return val;
		}

		internal void Complete()
		{
			completed.Value = true;
			target.Save();
		}

		private static string Id(string section, string key)
		{
			return section + "\n" + key;
		}

		private static HashSet<string> ReadKeys(string path)
		{
			HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal);
			if (!File.Exists(path))
			{
				return hashSet;
			}
			string section = "";
			string[] array = File.ReadAllLines(path);
			for (int i = 0; i < array.Length; i++)
			{
				string text = array[i].Trim();
				if (text.Length == 0 || text.StartsWith("#") || text.StartsWith(";"))
				{
					continue;
				}
				if (text.StartsWith("[") && text.EndsWith("]"))
				{
					section = text.Substring(1, text.Length - 2).Trim();
					continue;
				}
				int num = text.IndexOf('=');
				if (num > 0)
				{
					hashSet.Add(Id(section, text.Substring(0, num).Trim()));
				}
			}
			return hashSet;
		}
	}
	internal static class ArmItems
	{
		private const string Marker = "OctoPack_addon_LanternArm.Item.v1";

		private const string Wanted = "OctoPack_addon_LanternArm.Equipped.v1";

		private const string Net = "OctoPack_addon_LanternArm.Equipped.v1";

		private static Recipe recipe;

		private static ObjectDB database;

		private static GameObject cache;

		private static float next;

		private static Sprite icon;

		private static Texture2D texture;

		private static void Toggle(Player player, ItemData item)
		{
			if (!Object.op_Implicit((Object)(object)player) || (Object)(object)player != (Object)(object)Player.m_localPlayer)
			{
				return;
			}
			if (Selected(item))
			{
				item.m_customData["OctoPack_addon_LanternArm.Equipped.v1"] = "0";
				item.m_equipped = false;
				Tick();
				return;
			}
			if (!InPack(player, item))
			{
				((Character)player).Message((MessageType)2, "Move the lantern arm into a backpack slot first.", 0, (Sprite)null, false);
				return;
			}
			foreach (ItemData allItem in ((Humanoid)player).GetInventory().GetAllItems())
			{
				if (Is(allItem))
				{
					allItem.m_customData["OctoPack_addon_LanternArm.Equipped.v1"] = "0";
				}
			}
			item.m_customData["OctoPack_addon_LanternArm.Equipped.v1"] = "1";
			Tick();
		}

		internal static bool Use(Humanoid __instance, ItemData item)
		{
			if (!Is(item))
			{
				return true;
			}
			Toggle((Player)(object)((__instance is Player) ? __instance : null), item);
			return false;
		}

		internal static bool Equip(Humanoid __instance, ItemData item, ref bool __result)
		{
			if (!Is(item))
			{
				return true;
			}
			Player val = (Player)(object)((__instance is Player) ? __instance : null);
			__result = false;
			if (!Object.op_Implicit((Object)(object)val))
			{
				return false;
			}
			if (Selected(item))
			{
				__result = InPack(val, item);
				return false;
			}
			if ((Object)(object)val != (Object)(object)Player.m_localPlayer || (bool)AccessTools.Field(typeof(Player), "m_isLoading").GetValue(val))
			{
				return false;
			}
			if (!InPack(val, item))
			{
				((Character)val).Message((MessageType)2, "Move the lantern arm into a backpack slot first.", 0, (Sprite)null, false);
				return false;
			}
			foreach (ItemData allItem in ((Humanoid)val).GetInventory().GetAllItems())
			{
				if (Is(allItem))
				{
					allItem.m_customData["OctoPack_addon_LanternArm.Equipped.v1"] = "0";
				}
			}
			item.m_customData["OctoPack_addon_LanternArm.Equipped.v1"] = "1";
			Tick();
			__result = true;
			return false;
		}

		internal static bool Unequip(Humanoid __instance, ItemData item)
		{
			if (!Is(item))
			{
				return true;
			}
			Player val = (Player)(object)((__instance is Player) ? __instance : null);
			if (!Object.op_Implicit((Object)(object)val) || (bool)AccessTools.Field(typeof(Player), "m_isLoading").GetValue(val))
			{
				item.m_equipped = false;
				return false;
			}
			item.m_customData["OctoPack_addon_LanternArm.Equipped.v1"] = "0";
			item.m_equipped = false;
			Tick();
			return false;
		}

		internal static void IsEquipped(Humanoid __instance, ItemData item, ref bool __result)
		{
			if (Is(item))
			{
				__result = Selected(item) && InPack((Player)(object)((__instance is Player) ? __instance : null), item);
			}
		}

		internal static bool Is(ItemData item)
		{
			return item?.m_customData.ContainsKey("OctoPack_addon_LanternArm.Item.v1") ?? false;
		}

		internal static bool Selected(ItemData item)
		{
			if (Is(item) && item.m_customData.TryGetValue("OctoPack_addon_LanternArm.Equipped.v1", out var value))
			{
				return value == "1";
			}
			return false;
		}

		private static bool InPack(Player player, ItemData item)
		{
			return BackpackBridge.InBackpack(player, item);
		}

		internal static bool EquippedFor(Player player)
		{
			if (!Object.op_Implicit((Object)(object)player))
			{
				return false;
			}
			if ((Object)(object)player == (Object)(object)Player.m_localPlayer)
			{
				if (!Object.op_Implicit((Object)(object)Plugin.Instance) || !Plugin.Instance.Enabled.Value || ((Character)player).IsDead())
				{
					return false;
				}
				foreach (ItemData allItem in ((Humanoid)player).GetInventory().GetAllItems())
				{
					if (Selected(allItem) && InPack(player, allItem))
					{
						return true;
					}
				}
				return false;
			}
			ZNetView component = ((Component)player).GetComponent<ZNetView>();
			if (Object.op_Implicit((Object)(object)component) && component.GetZDO() != null)
			{
				return component.GetZDO().GetBool("OctoPack_addon_LanternArm.Equipped.v1", false);
			}
			return false;
		}

		private static Sprite Icon()
		{
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: 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_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Expected O, but got Unknown
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)icon))
			{
				return icon;
			}
			using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("OctoPack_addon_LanternArm.Icon");
			byte[] array = new byte[65536];
			int i;
			int num;
			for (i = 0; i < array.Length; i += num)
			{
				if ((num = stream.Read(array, i, array.Length - i)) <= 0)
				{
					break;
				}
			}
			if (i != array.Length)
			{
				throw new InvalidDataException("Arm icon data");
			}
			byte[] array2 = new byte[array.Length];
			for (int j = 0; j < 128; j++)
			{
				Array.Copy(array, j * 512, array2, (127 - j) * 512, 512);
			}
			texture = new Texture2D(128, 128, (TextureFormat)4, false)
			{
				name = "OctoPack_LanternArmIcon",
				filterMode = (FilterMode)0,
				wrapMode = (TextureWrapMode)1
			};
			texture.LoadRawTextureData(array2);
			texture.Apply(false, true);
			icon = Sprite.Create(texture, new Rect(0f, 0f, 128f, 128f), new Vector2(0.5f, 0.5f), 128f);
			return icon;
		}

		private static void Mark(ItemData item)
		{
			item.m_customData["OctoPack_addon_LanternArm.Item.v1"] = "1";
			if (!item.m_customData.ContainsKey("OctoPack_addon_LanternArm.Equipped.v1"))
			{
				item.m_customData["OctoPack_addon_LanternArm.Equipped.v1"] = "0";
			}
			Decorate(item);
		}

		internal static void Decorate(ItemData item)
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Expected O, but got Unknown
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			if (Is(item) && !(item.m_shared.m_name == "OctoPack Lantern Arm"))
			{
				item.m_shared = (SharedData)typeof(object).GetMethod("MemberwiseClone", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(item.m_shared, null);
				item.m_shared.m_name = "OctoPack Lantern Arm";
				item.m_shared.m_description = "Equip from a backpack slot to mount the lantern on a forged arm. Unequip to return the lantern to the bedroll strap.\nMade from 1 core wood, 2 iron, and 2 deer hide.";
				item.m_shared.m_icons = (Sprite[])(object)new Sprite[1] { Icon() };
				item.m_shared.m_itemType = (ItemType)1;
				item.m_shared.m_questItem = false;
				item.m_shared.m_equipStatusEffect = null;
				item.m_shared.m_useDurability = false;
				item.m_shared.m_maxStackSize = 1;
				item.m_shared.m_maxQuality = 1;
				item.m_shared.m_weight = 2f;
			}
		}

		internal static void Loaded(Inventory __instance)
		{
			foreach (ItemData allItem in __instance.GetAllItems())
			{
				Decorate(allItem);
			}
		}

		internal static void Tick()
		{
			Player localPlayer = Player.m_localPlayer;
			if (Time.realtimeSinceStartup >= next)
			{
				next = Time.realtimeSinceStartup + 2f;
				EnsureRecipe();
				if (Object.op_Implicit((Object)(object)localPlayer) && Object.op_Implicit((Object)(object)recipe))
				{
					AccessTools.Method(typeof(Player), "UpdateKnownRecipesList", (Type[])null, (Type[])null).Invoke(localPlayer, null);
				}
			}
			if (!Object.op_Implicit((Object)(object)localPlayer))
			{
				return;
			}
			bool flag = false;
			foreach (ItemData allItem in ((Humanoid)localPlayer).GetInventory().GetAllItems())
			{
				if (Is(allItem))
				{
					Decorate(allItem);
					if (allItem.m_equipped = !flag && Selected(allItem) && InPack(localPlayer, allItem) && Plugin.Instance.Enabled.Value && !((Character)localPlayer).IsDead())
					{
						flag = true;
					}
				}
			}
			ZNetView component = ((Component)localPlayer).GetComponent<ZNetView>();
			ZDO val = (Object.op_Implicit((Object)(object)component) ? component.GetZDO() : null);
			if (Object.op_Implicit((Object)(object)component) && component.IsOwner() && val != null && val.GetBool("OctoPack_addon_LanternArm.Equipped.v1", false) != flag)
			{
				val.Set("OctoPack_addon_LanternArm.Equipped.v1", flag);
			}
		}

		internal static void BeforeDeath(Player __instance)
		{
			foreach (ItemData allItem in ((Humanoid)__instance).GetInventory().GetAllItems())
			{
				if (Is(allItem))
				{
					allItem.m_equipped = false;
				}
			}
		}

		private static Requirement Cost(GameObject go, int amount)
		{
			//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_0011: 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_0020: Expected O, but got Unknown
			return new Requirement
			{
				m_resItem = go.GetComponent<ItemDrop>(),
				m_amount = amount,
				m_amountPerLevel = 0
			};
		}

		private static void EnsureRecipe()
		{
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Expected O, but got Unknown
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			ObjectDB instance = ObjectDB.instance;
			if (Object.op_Implicit((Object)(object)instance) && (!((Object)(object)database == (Object)(object)instance) || !Object.op_Implicit((Object)(object)recipe) || !instance.m_recipes.Contains(recipe)))
			{
				GameObject itemPrefab = instance.GetItemPrefab("Wishbone");
				GameObject itemPrefab2 = instance.GetItemPrefab("RoundLog");
				GameObject itemPrefab3 = instance.GetItemPrefab("Iron");
				GameObject itemPrefab4 = instance.GetItemPrefab("DeerHide");
				GameObject val = (Object.op_Implicit((Object)(object)ZNetScene.instance) ? ZNetScene.instance.GetPrefab("forge") : null);
				CraftingStation val2 = (Object.op_Implicit((Object)(object)val) ? val.GetComponent<CraftingStation>() : null);
				if (Object.op_Implicit((Object)(object)itemPrefab) && Object.op_Implicit((Object)(object)itemPrefab2) && Object.op_Implicit((Object)(object)itemPrefab3) && Object.op_Implicit((Object)(object)itemPrefab4) && Object.op_Implicit((Object)(object)val2))
				{
					DisposeRecipe();
					database = instance;
					cache = new GameObject("OctoPack_LanternArmRecipe");
					cache.SetActive(false);
					Object.DontDestroyOnLoad((Object)(object)cache);
					GameObject val3 = new GameObject("Wishbone");
					val3.SetActive(false);
					val3.transform.SetParent(cache.transform, false);
					ItemDrop val4 = val3.AddComponent<ItemDrop>();
					val4.m_itemData = itemPrefab.GetComponent<ItemDrop>().m_itemData.Clone();
					val4.m_itemData.m_dropPrefab = itemPrefab;
					val4.m_itemData.m_customData = new Dictionary<string, string>();
					Mark(val4.m_itemData);
					recipe = ScriptableObject.CreateInstance<Recipe>();
					((Object)recipe).name = "Recipe_OctoPack_addon_LanternArm";
					recipe.m_item = val4;
					recipe.m_amount = 1;
					recipe.m_enabled = true;
					recipe.m_craftingStation = (recipe.m_repairStation = val2);
					recipe.m_minStationLevel = 1;
					recipe.m_resources = (Requirement[])(object)new Requirement[3]
					{
						Cost(itemPrefab2, 1),
						Cost(itemPrefab3, 2),
						Cost(itemPrefab4, 2)
					};
					instance.m_recipes.Add(recipe);
				}
			}
		}

		internal static void BeforeCraft(InventoryGui __instance, Player player, out HashSet<ItemData> __state)
		{
			__state = ((Object.op_Implicit((Object)(object)recipe) && AccessTools.Field(typeof(InventoryGui), "m_craftRecipe").GetValue(__instance) == recipe && Object.op_Implicit((Object)(object)player)) ? new HashSet<ItemData>(((Humanoid)player).GetInventory().GetAllItems()) : null);
		}

		internal static void AfterCraft(Player player, HashSet<ItemData> __state)
		{
			if (!Object.op_Implicit((Object)(object)player) || __state == null)
			{
				return;
			}
			foreach (ItemData allItem in ((Humanoid)player).GetInventory().GetAllItems())
			{
				if (!__state.Contains(allItem) && Object.op_Implicit((Object)(object)allItem.m_dropPrefab) && ((Object)allItem.m_dropPrefab).name == "Wishbone")
				{
					Mark(allItem);
				}
			}
		}

		private static void DisposeRecipe()
		{
			if (Object.op_Implicit((Object)(object)database) && Object.op_Implicit((Object)(object)recipe))
			{
				database.m_recipes.Remove(recipe);
			}
			if (Object.op_Implicit((Object)(object)recipe))
			{
				Object.Destroy((Object)(object)recipe);
			}
			if (Object.op_Implicit((Object)(object)cache))
			{
				Object.Destroy((Object)(object)cache);
			}
			recipe = null;
			cache = null;
			database = null;
		}

		internal static void Dispose()
		{
			Player localPlayer = Player.m_localPlayer;
			ZNetView val = (Object.op_Implicit((Object)(object)localPlayer) ? ((Component)localPlayer).GetComponent<ZNetView>() : null);
			if (Object.op_Implicit((Object)(object)val) && val.IsOwner() && val.GetZDO() != null)
			{
				val.GetZDO().Set("OctoPack_addon_LanternArm.Equipped.v1", false);
			}
			DisposeRecipe();
			if (Object.op_Implicit((Object)(object)icon))
			{
				Object.Destroy((Object)(object)icon);
			}
			if (Object.op_Implicit((Object)(object)texture))
			{
				Object.Destroy((Object)(object)texture);
			}
			icon = null;
			texture = null;
		}
	}
	internal struct Point : IEquatable<Point>
	{
		internal float X;

		internal float Y;

		internal float Z;

		internal float Length => (float)Math.Sqrt(X * X + Y * Y + Z * Z);

		internal Point Unit => this * (1f / Math.Max(1E-12f, Length));

		internal Point(float x, float y, float z)
		{
			X = x;
			Y = y;
			Z = z;
		}

		public bool Equals(Point other)
		{
			if (X.Equals(other.X) && Y.Equals(other.Y))
			{
				return Z.Equals(other.Z);
			}
			return false;
		}

		public override bool Equals(object value)
		{
			if (value is Point other)
			{
				return Equals(other);
			}
			return false;
		}

		public override int GetHashCode()
		{
			return (((X.GetHashCode() * 397) ^ Y.GetHashCode()) * 397) ^ Z.GetHashCode();
		}

		public static Point operator +(Point a, Point b)
		{
			return new Point(a.X + b.X, a.Y + b.Y, a.Z + b.Z);
		}

		public static Point operator -(Point a, Point b)
		{
			return new Point(a.X - b.X, a.Y - b.Y, a.Z - b.Z);
		}

		public static Point operator *(Point a, float k)
		{
			return new Point(a.X * k, a.Y * k, a.Z * k);
		}

		internal static Point Cross(Point a, Point b)
		{
			return new Point(a.Y * b.Z - a.Z * b.Y, a.Z * b.X - a.X * b.Z, a.X * b.Y - a.Y * b.X);
		}
	}
	internal sealed class Surface
	{
		internal readonly List<Point> Vertices = new List<Point>();

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

		internal bool Smooth;

		internal void Triangle(Point a, Point b, Point c)
		{
			int count = Vertices.Count;
			Vertices.Add(a);
			Vertices.Add(b);
			Vertices.Add(c);
			Triangles.Add(count);
			Triangles.Add(count + 1);
			Triangles.Add(count + 2);
		}

		internal Point[] Normals()
		{
			Dictionary<Point, Point> dictionary = new Dictionary<Point, Point>();
			for (int i = 0; i < Triangles.Count; i += 3)
			{
				Point point = Vertices[Triangles[i]];
				Point point2 = Vertices[Triangles[i + 1]];
				Point point3 = Vertices[Triangles[i + 2]];
				Point point4 = Point.Cross(point2 - point, point3 - point);
				Point[] array = new Point[3] { point, point2, point3 };
				foreach (Point key in array)
				{
					dictionary.TryGetValue(key, out var value);
					dictionary[key] = value + point4;
				}
			}
			Point[] array2 = new Point[Vertices.Count];
			for (int k = 0; k < array2.Length; k++)
			{
				array2[k] = dictionary[Vertices[k]].Unit;
			}
			return array2;
		}

		internal void Tube(Point a, Point b, float r, int sides = 12)
		{
			Sweep(new Point[2] { a, b }, r, sides);
		}

		internal void Sweep(Point[] path, float radius, int sides = 12)
		{
			Point[,] array = new Point[path.Length, sides];
			for (int i = 0; i < path.Length; i++)
			{
				Point unit = (path[Math.Min(path.Length - 1, i + 1)] - path[Math.Max(0, i - 1)]).Unit;
				Point unit2 = Point.Cross(b: (Math.Abs(unit.X) < 0.9f) ? new Point(1f, 0f, 0f) : new Point(0f, 0f, 1f), a: unit).Unit;
				Point unit3 = Point.Cross(unit, unit2).Unit;
				for (int j = 0; j < sides; j++)
				{
					double num = (double)(j * 2) * Math.PI / (double)sides;
					array[i, j] = path[i] + (unit2 * (float)Math.Cos(num) + unit3 * (float)Math.Sin(num)) * radius;
				}
			}
			for (int k = 1; k < path.Length; k++)
			{
				for (int l = 0; l < sides; l++)
				{
					int num2 = (l + 1) % sides;
					Triangle(array[k - 1, l], array[k, num2], array[k, l]);
					Triangle(array[k - 1, l], array[k - 1, num2], array[k, num2]);
				}
			}
			for (int m = 0; m < sides; m++)
			{
				int num3 = (m + 1) % sides;
				Triangle(path[0], array[0, num3], array[0, m]);
				Triangle(path[^1], array[path.Length - 1, m], array[path.Length - 1, num3]);
			}
		}

		internal void Bar(Point[] path, float[] widths, float[] depths, float irregular = 0f, float[] twists = null)
		{
			Point[] array = new Point[8]
			{
				new Point(-0.7f, -1f, 0f),
				new Point(0.7f, -1f, 0f),
				new Point(1f, -0.7f, 0f),
				new Point(1f, 0.7f, 0f),
				new Point(0.7f, 1f, 0f),
				new Point(-0.7f, 1f, 0f),
				new Point(-1f, 0.7f, 0f),
				new Point(-1f, -0.7f, 0f)
			};
			Point[,] array2 = new Point[path.Length, 8];
			for (int i = 0; i < path.Length; i++)
			{
				Point unit = (path[Math.Min(path.Length - 1, i + 1)] - path[Math.Max(0, i - 1)]).Unit;
				Point point = ((Math.Abs(unit.X) < 0.9f) ? new Point(1f, 0f, 0f) : new Point(0f, 0f, 1f));
				Point point2 = (point - unit * (unit.X * point.X + unit.Y * point.Y + unit.Z * point.Z)).Unit;
				Point point3 = Point.Cross(unit, point2).Unit;
				if (twists != null)
				{
					float num = (float)Math.Cos(twists[i]);
					float num2 = (float)Math.Sin(twists[i]);
					Point point4 = point2;
					point2 = point4 * num + point3 * num2;
					point3 = point3 * num - point4 * num2;
				}
				for (int j = 0; j < 8; j++)
				{
					float num3 = 1f + irregular * (float)Math.Sin((double)i * 1.91 + (double)j * 2.17);
					array2[i, j] = path[i] + point2 * (array[j].X * widths[i] * num3) + point3 * (array[j].Y * depths[i] * num3);
				}
			}
			for (int k = 1; k < path.Length; k++)
			{
				for (int l = 0; l < 8; l++)
				{
					int num4 = (l + 1) % 8;
					Triangle(array2[k - 1, l], array2[k, num4], array2[k, l]);
					Triangle(array2[k - 1, l], array2[k - 1, num4], array2[k, num4]);
				}
			}
			for (int m = 0; m < 8; m++)
			{
				int num5 = (m + 1) % 8;
				Triangle(path[0], array2[0, num5], array2[0, m]);
				Triangle(path[^1], array2[path.Length - 1, m], array2[path.Length - 1, num5]);
			}
		}

		internal static float Noise(int key)
		{
			uint num = (uint)(key * 747796405 + -1403630843);
			num = ((num >> (int)((num >> 28) + 4)) ^ num) * 277803737;
			num = (num >> 22) ^ num;
			return (float)(num & 0xFFFFFF) / 16777215f;
		}

		internal static Point[] Ring(Point center, float width, float depth, float cut = 0f)
		{
			float[] array = new float[8] { -0.7f, 0.7f, 1f, 1f, 0.7f, -0.7f, -1f, -1f };
			float[] array2 = new float[8] { 1f, 1f, 0.7f, -0.7f, -1f, -1f, -0.7f, 0.7f };
			Point[] array3 = new Point[8];
			for (int i = 0; i < 8; i++)
			{
				float num = cut * Noise((int)Math.Round(center.Y * 10000f) + i * 733);
				array3[i] = center + new Point(array[i] * width * (1f - num), 0f, array2[i] * depth * (1f - num));
			}
			return array3;
		}

		internal void Loft(Point[][] rings, bool caps = true, bool reverse = false)
		{
			for (int i = 1; i < rings.Length; i++)
			{
				for (int j = 0; j < 8; j++)
				{
					int num = (j + 1) % 8;
					Face(rings[i - 1][j], rings[i][num], rings[i][j], reverse);
					Face(rings[i - 1][j], rings[i - 1][num], rings[i][num], reverse);
				}
			}
			if (caps)
			{
				Point a = default(Point);
				Point a2 = default(Point);
				for (int k = 0; k < 8; k++)
				{
					a += rings[0][k] * 0.125f;
					a2 += rings[^1][k] * 0.125f;
				}
				for (int l = 0; l < 8; l++)
				{
					int num2 = (l + 1) % 8;
					Face(a, rings[0][num2], rings[0][l], reverse);
					Face(a2, rings[^1][l], rings[^1][num2], reverse);
				}
			}
		}

		internal void Face(Point a, Point b, Point c, bool reverse)
		{
			if (reverse)
			{
				Triangle(a, c, b);
			}
			else
			{
				Triangle(a, b, c);
			}
		}

		internal void Rim(Point[] outer, Point[] inner, bool reverse = false)
		{
			for (int i = 0; i < 8; i++)
			{
				int num = (i + 1) % 8;
				Face(outer[i], inner[num], outer[num], reverse);
				Face(outer[i], inner[i], inner[num], reverse);
			}
		}

		internal void Box(Point c, Point half)
		{
			Point[] array = new Point[8];
			for (int i = 0; i < 8; i++)
			{
				array[i] = c + new Point(((i & 1) == 0) ? (0f - half.X) : half.X, ((i & 2) == 0) ? (0f - half.Y) : half.Y, ((i & 4) == 0) ? (0f - half.Z) : half.Z);
			}
			int[] array2 = new int[24]
			{
				0, 4, 6, 2, 1, 3, 7, 5, 0, 1,
				5, 4, 2, 6, 7, 3, 0, 2, 3, 1,
				4, 5, 7, 6
			};
			for (int j = 0; j < array2.Length; j += 4)
			{
				Triangle(array[array2[j]], array[array2[j + 1]], array[array2[j + 2]]);
				Triangle(array[array2[j]], array[array2[j + 2]], array[array2[j + 3]]);
			}
		}
	}
	internal sealed class ArmGeometry
	{
		internal readonly Surface Wood = new Surface();

		internal readonly Surface BaseWood = new Surface();

		internal readonly Surface Iron = new Surface
		{
			Smooth = true
		};

		internal readonly Surface Leather = new Surface
		{
			Smooth = true
		};

		internal readonly Surface Thread = new Surface
		{
			Smooth = true
		};

		internal Point Hinge;

		internal Point Pivot;

		internal Surface Lining = new Surface();

		internal Surface Cuff = new Surface();

		internal float CapBottom;

		internal float CapTop;

		internal static ArmGeometry Build(float height, float reach, float side, float lift = 0.008f, Func<float, float, float> skin = null)
		{
			ArmGeometry armGeometry = new ArmGeometry();
			armGeometry.Pivot = new Point(side, 0.595f, 0.02f);
			Point point = Post(side, height);
			armGeometry.Lumber(armGeometry.BaseWood, side, 0.28f, 0.61f, height);
			armGeometry.Lumber(armGeometry.Wood, side, 0.588f, height, height);
			armGeometry.Sleeve(side, skin ?? new Func<float, float, float>(DefaultSkin));
			armGeometry.CapBottom = height - 0.052f;
			armGeometry.CapTop = height + 0.009f;
			armGeometry.Iron.Loft(new Point[3][]
			{
				Surface.Ring(Post(side, armGeometry.CapBottom), 0.029f, 0.026f),
				Surface.Ring(Post(side, height - 0.012f), 0.029f, 0.026f),
				Surface.Ring(Post(side, armGeometry.CapTop), 0.029f, 0.026f)
			});
			Point point2 = new Point(side - 0.04f, height, 0.02f + reach);
			List<Point> list = new List<Point>();
			List<float> list2 = new List<float>();
			List<float> list3 = new List<float>();
			List<float> list4 = new List<float>();
			for (int i = 0; i <= 12; i++)
			{
				float num = (float)i / 12f;
				list.Add(point + (point2 - point) * num + new Point(-0.0015f * (float)Math.Sin(num * 6f), 0.002f * (float)Math.Sin(num * 6f), 0f));
				list2.Add(0.014f * (1f - num) + 0.008f * num);
				list3.Add(0.009f * (1f - num) + 0.0065f * num);
				float num2 = Math.Max(0f, Math.Min(1f, (num - 0.15f) / 0.65f));
				list4.Add(MathF.PI * (num2 * num2 * (3f - 2f * num2)));
			}
			for (int j = 1; j <= 28; j++)
			{
				float num3 = (float)j / 28f;
				double num4 = (double)num3 * Math.PI * 1.65;
				list.Add(point2 + new Point(-0.002f * num3, (float)(Math.Cos(num4) - 1.0) * 0.03f, (float)Math.Sin(num4) * 0.03f));
				list2.Add(0.008f * (1f - num3) + 0.0021f * num3);
				list3.Add(0.0065f * (1f - num3) + 0.0018f * num3);
				list4.Add(MathF.PI);
			}
			armGeometry.Iron.Bar(list.ToArray(), list2.ToArray(), list3.ToArray(), 0.06f, list4.ToArray());
			Point point3 = Post(side, height - 0.22f) + new Point(0f, 0f, 0.023f);
			Point point4 = new Point(side - 0.006f, height - 0.055f, 0.02f + reach * 0.25f);
			Point point5 = point + (point2 - point) * 0.86f + new Point(0f, -0.007f, 0f);
			List<Point> points = new List<Point>();
			Curve(points, point3, point3 + new Point(0f, 0.07f, reach * 0.03f), point4 + new Point(0f, -0.11f, reach * 0.11f), point4, 16);
			Curve(points, point4, point4 + new Point(0f, -0.06f, reach * 0.23f), point5 + new Point(0f, -0.095f, (0f - reach) * 0.14f), point5, 24, skipFirst: true);
			armGeometry.Forging(points, 0.005f, 0.0065f, taper: false);
			List<Point> points2 = new List<Point>();
			Point point6 = new Point(side - 0.006f, height - 0.112f, 0.02f + reach * 0.1f);
			Curve(points2, point4, point4 + new Point(0f, 0.035f, (0f - reach) * 0.2f), point6 + new Point(0f, 0.07f, (0f - reach) * 0.12f), point6, 24);
			Curve(points2, point6, point6 + new Point(0f, -0.01f, reach * 0.06f), point6 + new Point(0f, 0.008f, reach * 0.08f), point6 + new Point(0f, 0.018f, reach * 0.065f), 10, skipFirst: true);
			armGeometry.Forging(points2, 0.0045f, 0.006f, taper: true);
			armGeometry.Iron.Loft(new Point[2][]
			{
				Surface.Ring(Post(side, height - 0.24f), 0.0275f, 0.024f),
				Surface.Ring(Post(side, height - 0.198f), 0.0275f, 0.024f)
			});
			float[] array = new float[3]
			{
				height - 0.226f,
				height - 0.208f,
				height - 0.025f
			};
			foreach (float y in array)
			{
				Point point7 = Post(side, y);
				armGeometry.Iron.Tube(point7 + new Point(-0.028f, 0f, 0f), point7 + new Point(-0.032f, 0f, 0f), 0.0055f, 8);
			}
			armGeometry.Hinge = point2 + new Point(0f, -0.06f + lift, 0f);
			return armGeometry;
		}

		internal static Point Post(float side, float y)
		{
			float num = (float)(Math.Sin((double)y * 7.3 + 0.4) + 0.4 * Math.Sin((double)y * 19.1 - 1.7));
			float num2 = (float)(Math.Sin(4.7435) + 0.4 * Math.Sin(9.6645));
			return new Point(side + 0.0022f * (num - num2), y, 0.02f + 0.0014f * (float)(Math.Sin((double)y * 11.7 + 0.2) - Math.Sin(7.161499999999999)));
		}

		private void Lumber(Surface surface, float side, float low, float high, float capHeight)
		{
			List<float> list = new List<float> { low };
			float num = low;
			int num2 = 0;
			while (num < high - 0.014f)
			{
				num += 0.016f + 0.021f * Surface.Noise(59 + num2++ * 117);
				if (num < high - 0.01f)
				{
					list.Add(num);
				}
			}
			list.Add(high);
			Point[][] array = new Point[list.Count][];
			float num3;
			int num4;
			float num5;
			float cut;
			float num6;
			for (int i = 0; i < list.Count; cut = num5, num6 = ((num4 != 0) ? 0f : (Surface.Noise((int)(num3 * 1700f) + 83) - 0.5f)), array[i] = Surface.Ring(Post(side, num3), 0.022f + 0.0011f * (float)Math.Sin(num3 * 14f) + num6 * 0.0015f, 0.019f + 0.001f * (float)Math.Cos(num3 * 11f) - num6 * 0.001f, cut), i++)
			{
				num3 = list[i];
				if (!(num3 < 0.63f))
				{
					num4 = ((num3 > capHeight - 0.065f) ? 1 : 0);
					if (num4 == 0)
					{
						num5 = 0.16f;
						continue;
					}
				}
				else
				{
					num4 = 1;
				}
				num5 = 0.018f;
			}
			surface.Loft(array);
		}

		private static void Curve(List<Point> points, Point a, Point b, Point c, Point d, int steps, bool skipFirst = false)
		{
			for (int i = (skipFirst ? 1 : 0); i <= steps; i++)
			{
				float num = (float)i / (float)steps;
				float num2 = 1f - num;
				points.Add(a * (num2 * num2 * num2) + b * (3f * num2 * num2 * num) + c * (3f * num2 * num * num) + d * (num * num * num));
			}
		}

		private void Forging(List<Point> points, float width, float depth, bool taper)
		{
			float[] array = new float[points.Count];
			float[] array2 = new float[points.Count];
			for (int i = 0; i < points.Count; i++)
			{
				float num = (float)i / (float)(points.Count - 1);
				float num2 = (taper ? (1f - 0.7f * num) : 1f);
				array[i] = width * num2;
				array2[i] = depth * num2;
			}
			Iron.Bar(points.ToArray(), array, array2, 0.065f);
		}

		private static float DefaultSkin(float y, float z)
		{
			float num = Math.Max(0f, Math.Min(1f, (y - 0.28f) / 0.34f));
			return -0.214f + 0.058f * num * num + 0.55f * Math.Abs(z - 0.005f);
		}

		private void Sleeve(float side, Func<float, float, float> skin)
		{
			Point[,] array = new Point[19, 17];
			for (int i = 0; i <= 18; i++)
			{
				for (int j = 0; j <= 16; j++)
				{
					float num = (float)i / 18f;
					float num2 = (float)j / 16f;
					float num3 = 0.268f + 0.347f * num;
					float num4 = 0.059f * (0.91f + 0.09f * (float)Math.Sin(num * 3.14f));
					float num5 = 0.02f + (num2 * 2f - 1f) * num4;
					float num6 = skin(num3, num5) - 0.002f;
					float num7 = Math.Abs(num5 - Post(side, num3).Z);
					float num8 = Math.Max(0f, Math.Min(1f, (num7 - 0.019f) / 0.023f));
					float num9 = 1f - num8 * num8 * (3f - 2f * num8);
					float num10 = Math.Max(0f, Math.Min(1f, (num3 - 0.268f) / 0.021f));
					float num11 = Post(side, num3).X - 0.0258f;
					float x = num6 - Math.Max(0f, num6 - num11) * num9 * num10;
					array[i, j] = new Point(x, num3, num5);
				}
			}
			for (int k = 1; k <= 18; k++)
			{
				for (int l = 1; l <= 16; l++)
				{
					Leather.Triangle(array[k - 1, l - 1], array[k, l], array[k, l - 1]);
					Leather.Triangle(array[k - 1, l - 1], array[k - 1, l], array[k, l]);
				}
			}
			Point[,] array2 = new Point[19, 17];
			for (int m = 0; m <= 18; m++)
			{
				for (int n = 0; n <= 16; n++)
				{
					array2[m, n] = array[m, n] + new Point(0.0022f, 0f, 0f);
				}
			}
			for (int num12 = 1; num12 <= 18; num12++)
			{
				for (int num13 = 1; num13 <= 16; num13++)
				{
					Lining.Triangle(array2[num12 - 1, num13 - 1], array2[num12, num13 - 1], array2[num12, num13]);
					Lining.Triangle(array2[num12 - 1, num13 - 1], array2[num12, num13], array2[num12 - 1, num13]);
				}
			}
			for (int num14 = 0; num14 < Lining.Triangles.Count; num14 += 3)
			{
				Leather.Triangle(Lining.Vertices[num14], Lining.Vertices[num14 + 1], Lining.Vertices[num14 + 2]);
			}
			for (int num15 = 1; num15 <= 18; num15++)
			{
				int[] array3 = new int[2] { 0, 16 };
				foreach (int num17 in array3)
				{
					bool reverse = num17 == 0;
					Leather.Face(array[num15 - 1, num17], array2[num15, num17], array[num15, num17], reverse);
					Leather.Face(array[num15 - 1, num17], array2[num15 - 1, num17], array2[num15, num17], reverse);
				}
			}
			for (int num18 = 1; num18 <= 16; num18++)
			{
				int[] array3 = new int[2] { 0, 18 };
				foreach (int num19 in array3)
				{
					bool reverse2 = num19 == 0;
					Leather.Face(array[num19, num18 - 1], array[num19, num18], array2[num19, num18], reverse2);
					Leather.Face(array[num19, num18 - 1], array2[num19, num18], array2[num19, num18 - 1], reverse2);
				}
			}
			Point[][] array4 = new Point[2][]
			{
				Surface.Ring(Post(side, 0.598f), 0.0278f, 0.0245f),
				Surface.Ring(Post(side, 0.62f), 0.0278f, 0.0245f)
			};
			Point[][] array5 = new Point[2][]
			{
				Surface.Ring(Post(side, 0.598f), 0.0241f, 0.021f),
				Surface.Ring(Post(side, 0.62f), 0.0241f, 0.021f)
			};
			Cuff.Loft(array4, caps: false);
			Cuff.Loft(array5, caps: false, reverse: true);
			Cuff.Rim(array4[1], array5[1], reverse: true);
			Cuff.Rim(array4[0], array5[0]);
			for (int num20 = 0; num20 < Cuff.Triangles.Count; num20 += 3)
			{
				Leather.Triangle(Cuff.Vertices[num20], Cuff.Vertices[num20 + 1], Cuff.Vertices[num20 + 2]);
			}
			for (int num21 = 1; num21 < 18; num21++)
			{
				int[] array3 = new int[2] { 1, 15 };
				foreach (int num22 in array3)
				{
					Point point = array[num21, num22] + new Point(-0.001f, 0f, 0f);
					Point point2 = array[num21 + 1, num22] + new Point(-0.001f, 0f, 0f);
					Thread.Tube(point + (point2 - point) * 0.12f, point + (point2 - point) * 0.58f, 0.0009f, 5);
				}
			}
			for (int num23 = 1; num23 < 15; num23++)
			{
				Point point3 = array[1, num23] + new Point(-0.001f, 0f, 0f);
				Point point4 = array[1, num23 + 1] + new Point(-0.001f, 0f, 0f);
				Thread.Tube(point3 + (point4 - point3) * 0.1f, point3 + (point4 - point3) * 0.64f, 0.0009f, 5);
			}
		}
	}
	internal sealed class ArmMotion
	{
		internal double X;

		internal double Y;

		internal double Z;

		private double vx;

		private double vy;

		private double vz;

		internal void Reset()
		{
			X = (Y = (Z = (vx = (vy = (vz = 0.0)))));
		}

		internal void Step(double tx, double ty, double tz, double dt, double spring, double damping, double limit)
		{
			if (dt <= 0.0)
			{
				return;
			}
			if (dt > 0.25)
			{
				Reset();
				return;
			}
			int num = (int)Math.Ceiling(dt / 0.008);
			double num2 = dt / (double)num;
			double num3 = 2.0 * damping * Math.Sqrt(spring);
			double num4 = Math.Sqrt(tx * tx + ty * ty + tz * tz);
			if (num4 > limit)
			{
				tx *= limit / num4;
				ty *= limit / num4;
				tz *= limit / num4;
			}
			for (int i = 0; i < num; i++)
			{
				vx += ((tx - X) * spring - num3 * vx) * num2;
				vy += ((ty - Y) * spring - num3 * vy) * num2;
				vz += ((tz - Z) * spring - num3 * vz) * num2;
				X += vx * num2;
				Y += vy * num2;
				Z += vz * num2;
				num4 = Math.Sqrt(X * X + Y * Y + Z * Z);
				if (num4 > limit)
				{
					X *= limit / num4;
					Y *= limit / num4;
					Z *= limit / num4;
					vx *= 0.5;
					vy *= 0.5;
					vz *= 0.5;
				}
			}
		}
	}
	[DefaultExecutionOrder(3150)]
	internal sealed class ArmRig : MonoBehaviour
	{
		private PackSkin skin;

		private Player wearer;

		private bool portable;

		private bool portableEquipped;

		private PortableContacts.GroundSettings ground;

		private Transform model;

		private Transform anchor;

		private Transform moving;

		private int revision = -1;

		private float retry;

		private LODGroup lod;

		private readonly ArmMotion motion = new ArmMotion();

		private Vector3 pivot;

		private Vector3 previousPosition;

		private Vector3 previousVelocity;

		private Vector3 previousForward;

		private Vector3 smoothedAcceleration;

		private bool motionReady;

		private readonly List<Mesh> meshes = new List<Mesh>();

		private readonly List<Material> materials = new List<Material>();

		private readonly List<Texture2D> textures = new List<Texture2D>();

		private readonly List<GameObject> parts = new List<GameObject>();

		private readonly List<Renderer> renderers = new List<Renderer>();

		internal Transform Anchor
		{
			get
			{
				if (!Object.op_Implicit((Object)(object)model) || !((Component)model).gameObject.activeInHierarchy)
				{
					return null;
				}
				return anchor;
			}
		}

		private void Awake()
		{
			wearer = ((Component)this).GetComponentInParent<Player>();
		}

		internal void SetPortable(bool equipped, PortableContacts.GroundSettings saved = null)
		{
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			if (ground != saved && (ground == null || saved == null || ground.ArmHeight != saved.ArmHeight || ground.ArmReach != saved.ArmReach || ground.ArmSide != saved.ArmSide || ground.ArmLift != saved.ArmLift || !(ground.ArmOffset == saved.ArmOffset)))
			{
				revision = -1;
				motionReady = false;
			}
			ground = saved;
			portable = true;
			portableEquipped = equipped;
			Ensure();
		}

		internal void Ensure()
		{
			//IL_03ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0200: Unknown result type (might be due to invalid IL or missing references)
			//IL_021c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			//IL_0221: Unknown result type (might be due to invalid IL or missing references)
			//IL_024c: Unknown result type (might be due to invalid IL or missing references)
			//IL_028e: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0318: Unknown result type (might be due to invalid IL or missing references)
			//IL_0334: Unknown result type (might be due to invalid IL or missing references)
			//IL_0339: Unknown result type (might be due to invalid IL or missing references)
			//IL_0349: Expected O, but got Unknown
			//IL_0366: Unknown result type (might be due to invalid IL or missing references)
			//IL_0475: Unknown result type (might be due to invalid IL or missing references)
			//IL_047a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0496: Unknown result type (might be due to invalid IL or missing references)
			//IL_048f: Unknown result type (might be due to invalid IL or missing references)
			//IL_049b: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_04cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0578: Unknown result type (might be due to invalid IL or missing references)
			//IL_057e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0583: Unknown result type (might be due to invalid IL or missing references)
			Plugin instance = Plugin.Instance;
			if (!Object.op_Implicit((Object)(object)instance) || Time.realtimeSinceStartup < retry)
			{
				return;
			}
			if (instance.Enabled.Value)
			{
				bool num;
				if (!portable)
				{
					num = ArmItems.EquippedFor(wearer);
				}
				else
				{
					if (!portableEquipped)
					{
						goto IL_006e;
					}
					if (ground == null)
					{
						goto IL_008e;
					}
					num = ground.Arm;
				}
				if (num)
				{
					goto IL_008e;
				}
			}
			goto IL_006e;
			IL_008e:
			try
			{
				if (!Object.op_Implicit((Object)(object)model))
				{
					Transform val = null;
					Transform[] componentsInChildren = ((Component)this).GetComponentsInChildren<Transform>(true);
					foreach (Transform val2 in componentsInChildren)
					{
						if (((Object)val2).name == "BackpackSpring")
						{
							val = val2;
							break;
						}
					}
					Material val3 = Plugin.PackMaterial();
					Mesh val4 = Plugin.PackMesh();
					if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val3) || !Object.op_Implicit((Object)(object)val4))
					{
						return;
					}
					Vector3[] vertices = val4.vertices;
					Vector2[] uv = val4.uv;
					Point[] array = new Point[vertices.Length];
					Point[] array2 = new Point[vertices.Length];
					for (int j = 0; j < vertices.Length; j++)
					{
						array[j] = new Point(vertices[j].x, vertices[j].y, vertices[j].z);
						array2[j] = new Point(uv[j].x, uv[j].y, 0f);
					}
					skin = new PackSkin(array, array2, val4.triangles);
					model = new GameObject("OctoPack_LanternArm").transform;
					model.SetParent(val, false);
					model.localPosition = -new Vector3(0f, 0.45f, 0.105f) + (ground?.ArmOffset ?? instance.Offset.Value);
					((Component)model).gameObject.layer = ((Component)this).gameObject.layer;
					moving = new GameObject("OctoPack_LanternArmFlex").transform;
					moving.SetParent(model, false);
					((Component)moving).gameObject.layer = ((Component)this).gameObject.layer;
					anchor = new GameObject("OctoPack_LanternArmHook").transform;
					anchor.SetParent(moving, false);
					((Component)anchor).gameObject.layer = ((Component)this).gameObject.layer;
					materials.Add(Material(val3, "Wood", new Color(0.39f, 0.22f, 0.1f), 0f));
					materials.Add(Material(val3, "Iron", new Color(0.23f, 0.25f, 0.26f), 0.65f));
					materials.Add(new Material(val3)
					{
						name = "OctoPack_LanternArm_PackLeather"
					});
					materials.Add(Material(val3, "LinenStitches", new Color(0.63f, 0.49f, 0.29f), 0f));
					revision = -1;
				}
				((Component)model).gameObject.SetActive(true);
				int num2 = ((ground == null) ? instance.Revision : int.MinValue);
				if (revision != num2)
				{
					Vector3 offset = ground?.ArmOffset ?? instance.Offset.Value;
					ClearParts();
					ArmGeometry armGeometry = ArmGeometry.Build(ground?.ArmHeight ?? instance.Height.Value, ground?.ArmReach ?? instance.Reach.Value, ground?.ArmSide ?? instance.Side.Value, ground?.ArmLift ?? instance.LoopLift.Value, (float y, float z) => skin.Sample(y + offset.y, z + offset.z).X - offset.x);
					model.localPosition = -new Vector3(0f, 0.45f, 0.105f) + (ground?.ArmOffset ?? instance.Offset.Value);
					pivot = new Vector3(armGeometry.Pivot.X, armGeometry.Pivot.Y, armGeometry.Pivot.Z);
					moving.localPosition = pivot;
					moving.localRotation = Quaternion.identity;
					Add("WoodPost", armGeometry.Wood, 0, flex: true);
					Add("PostInSleeve", armGeometry.BaseWood, 0, flex: false);
					Add("IronArmAndHook", armGeometry.Iron, 1, flex: true);
					Add("SewnLeatherSleeve", armGeometry.Leather, 2, flex: false);
					Add("SleeveStitches", armGeometry.Thread, 3, flex: false);
					anchor.localPosition = new Vector3(armGeometry.Hinge.X, armGeometry.Hinge.Y, armGeometry.Hinge.Z) - pivot;
					motion.Reset();
					motionReady = false;
					revision = num2;
					AttachLOD();
				}
				return;
			}
			catch (Exception e)
			{
				Shutdown();
				retry = Time.realtimeSinceStartup + 10f;
				instance.Warn(e);
				return;
			}
			IL_006e:
			if (Object.op_Implicit((Object)(object)model))
			{
				((Component)model).gameObject.SetActive(false);
			}
		}

		private Material Material(Material source, string name, Color color, float metallic)
		{
			//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_001c: 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_002b: Expected O, but got Unknown
			//IL_00e4: 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_00fb: Expected O, but got Unknown
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: 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_00ab: 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_005e: 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_021e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: Unknown result type (might be due to invalid IL or missing references)
			//IL_0240: Unknown result type (might be due to invalid IL or missing references)
			//IL_0249: Expected O, but got Unknown
			//IL_02bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c0: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(32, 32, (TextureFormat)4, false)
			{
				name = "LanternArm_" + name,
				filterMode = (FilterMode)0,
				wrapMode = (TextureWrapMode)0
			};
			Color[] array = (Color[])(object)new Color[1024];
			for (int i = 0; i < 32; i++)
			{
				for (int j = 0; j < 32; j++)
				{
					Point point = ((name == "Wood" || metallic > 0f) ? ArmTextures.Color(metallic > 0f, j, i) : new Point(color.r, color.g, color.b));
					array[i * 32 + j] = new Color(point.X, point.Y, point.Z, 1f);
				}
			}
			val.SetPixels(array);
			val.Apply(false, true);
			textures.Add(val);
			Material val2 = new Material(source)
			{
				name = "OctoPack_LanternArm_" + name
			};
			val2.SetTexture("_MainTex", (Texture)(object)val);
			val2.SetTextureScale("_MainTex", Vector2.one);
			val2.SetTextureOffset("_MainTex", Vector2.zero);
			if (val2.HasProperty("_Color"))
			{
				val2.SetColor("_Color", Color.white);
			}
			if (val2.HasProperty("_Metallic"))
			{
				val2.SetFloat("_Metallic", metallic);
			}
			if (val2.HasProperty("_Glossiness"))
			{
				val2.SetFloat("_Glossiness", (metallic > 0f) ? 0.28f : 0.1f);
			}
			string[] array2 = new string[5] { "_BumpMap", "_NormalMap", "_MetallicGlossMap", "_MetalGlossMap", "_MetalTex" };
			foreach (string text in array2)
			{
				if (val2.HasProperty(text))
				{
					val2.SetTexture(text, (Texture)null);
				}
			}
			val2.DisableKeyword("_NORMALMAP");
			val2.DisableKeyword("_METALLICGLOSSMAP");
			if (name == "Wood" || metallic > 0f)
			{
				Texture2D val3 = new Texture2D(32, 32, (TextureFormat)4, false, true)
				{
					name = "LanternArm_" + name + "_Normal",
					filterMode = (FilterMode)0,
					wrapMode = (TextureWrapMode)0
				};
				Color[] array3 = (Color[])(object)new Color[1024];
				for (int l = 0; l < 32; l++)
				{
					for (int m = 0; m < 32; m++)
					{
						Point point2 = ArmTextures.Normal(metallic > 0f, m, l);
						array3[l * 32 + m] = new Color(point2.X * 0.5f + 0.5f, point2.Y * 0.5f + 0.5f, point2.Z * 0.5f + 0.5f, 1f);
					}
				}
				val3.SetPixels(array3);
				val3.Apply(false, true);
				textures.Add(val3);
				bool flag = false;
				array2 = new string[2] { "_BumpMap", "_NormalMap" };
				foreach (string text2 in array2)
				{
					if (val2.HasProperty(text2))
					{
						val2.SetTexture(text2, (Texture)(object)val3);
						flag = true;
					}
				}
				if (flag)
				{
					val2.EnableKeyword("_NORMALMAP");
					if (val2.HasProperty("_BumpScale"))
					{
						val2.SetFloat("_BumpScale", 1f);
					}
				}
			}
			return val2;
		}

		private void Add(string name, Surface data, int material, bool flex)
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Expected O, but got Unknown
			//IL_0063: 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_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_025b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0262: Expected O, but got Unknown
			//IL_021a: Unknown result type (might be due to invalid IL or missing references)
			//IL_021f: 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_00cf: 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_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: 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)
			Vector3[] array = (Vector3[])(object)new Vector3[data.Vertices.Count];
			Color32[] array2 = (Color32[])(object)new Color32[array.Length];
			Vector2[] array3 = (Vector2[])(object)new Vector2[array.Length];
			for (int i = 0; i < array.Length; i++)
			{
				Point point = data.Vertices[i];
				array[i] = new Vector3(point.X, point.Y, point.Z) - (flex ? pivot : Vector3.zero);
				byte b = ((material == 0) ? ((byte)(239f + 16f * Surface.Noise((int)(point.Y * 900f) + (int)(point.X * 3100f) + (int)(point.Z * 5700f)))) : byte.MaxValue);
				array2[i] = new Color32(b, b, b, byte.MaxValue);
				if (material == 2)
				{
					Vector3 val = ground?.ArmOffset ?? Plugin.Instance.Offset.Value;
					Point point2 = skin.Sample(point.Y + val.y, point.Z + val.z);
					array3[i] = new Vector2(point2.Y, point2.Z);
				}
				else
				{
					array3[i] = new Vector2((point.X + point.Z) * (float)((material == 0) ? 8 : 12), point.Y * ((material == 0) ? 2.5f : 4f));
				}
			}
			Mesh val2 = new Mesh
			{
				name = "OctoPack_" + name
			};
			val2.vertices = array;
			val2.uv = array3;
			val2.colors32 = array2;
			val2.triangles = data.Triangles.ToArray();
			if (data.Smooth)
			{
				Point[] array4 = data.Normals();
				Vector3[] array5 = (Vector3[])(object)new Vector3[array4.Length];
				for (int j = 0; j < array4.Length; j++)
				{
					array5[j] = new Vector3(array4[j].X, array4[j].Y, array4[j].Z);
				}
				val2.normals = array5;
			}
			else
			{
				val2.RecalculateNormals();
			}
			val2.RecalculateTangents();
			val2.RecalculateBounds();
			meshes.Add(val2);
			GameObject val3 = new GameObject(name);
			val3.layer = ((Component)this).gameObject.layer;
			val3.transform.SetParent(flex ? moving : model, false);
			val3.AddComponent<MeshFilter>().sharedMesh = val2;
			MeshRenderer val4 = val3.AddComponent<MeshRenderer>();
			((Renderer)val4).sharedMaterial = materials[material];
			renderers.Add((Renderer)(object)val4);
			parts.Add(val3);
		}

		private void AttachLOD()
		{
			Player componentInParent = ((Component)this).GetComponentInParent<Player>();
			VisEquipment val = (Object.op_Implicit((Object)(object)componentInParent) ? ((Component)componentInParent).GetComponentInChildren<VisEquipment>() : null);
			lod = (Object.op_Implicit((Object)(object)val) ? ((Component)val).GetComponentInChildren<LODGroup>() : null);
			if (!Object.op_Implicit((Object)(object)lod))
			{
				return;
			}
			LOD[] lODs = lod.GetLODs();
			for (int i = 0; i < lODs.Length; i++)
			{
				List<Renderer> list = new List<Renderer>((IEnumerable<Renderer>)(((object)lODs[i].renderers) ?? ((object)new Renderer[0])));
				foreach (Renderer renderer in renderers)
				{
					if (!list.Contains(renderer))
					{
						list.Add(renderer);
					}
				}
				lODs[i].renderers = list.ToArray();
			}
			lod.SetLODs(lODs);
			lod.RecalculateBounds();
		}

		private void ClearParts()
		{
			if (Object.op_Implicit((Object)(object)lod))
			{
				LOD[] lODs = lod.GetLODs();
				for (int i = 0; i < lODs.Length; i++)
				{
					List<Renderer> list = new List<Renderer>();
					Renderer[] array = (Renderer[])(((object)lODs[i].renderers) ?? ((object)new Renderer[0]));
					foreach (Renderer val in array)
					{
						if (Object.op_Implicit((Object)(object)val) && !renderers.Contains(val))
						{
							list.Add(val);
						}
					}
					lODs[i].renderers = list.ToArray();
				}
				lod.SetLODs(lODs);
				lod.RecalculateBounds();
			}
			renderers.Clear();
			foreach (GameObject part in parts)
			{
				if (Object.op_Implicit((Object)(object)part))
				{
					Object.Destroy((Object)(object)part);
				}
			}
			parts.Clear();
			foreach (Mesh mesh in meshes)
			{
				if (Object.op_Implicit((Object)(object)mesh))
				{
					Object.Destroy((Object)(object)mesh);
				}
			}
			meshes.Clear();
		}

		private void LateUpdate()
		{
			//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_0083: 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_008f: 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_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_00e6: 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_00f2: 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_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: 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_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: 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_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: 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_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: 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_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: 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_015e: 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_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_022e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: Unknown result type (might be due to invalid IL or missing references)
			//IL_023a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0240: Unknown result type (might be due to invalid IL or missing references)
			//IL_0242: Unknown result type (might be due to invalid IL or missing references)
			//IL_0248: Unknown result type (might be due to invalid IL or missing references)
			//IL_0249: Unknown result type (might be due to invalid IL or missing references)
			Ensure();
			Plugin instance = Plugin.Instance;
			if (!Object.op_Implicit((Object)(object)instance) || !Object.op_Implicit((Object)(object)model) || !((Component)model).gameObject.activeInHierarchy || !Object.op_Implicit((Object)(object)moving))
			{
				return;
			}
			if (ground != null)
			{
				moving.localRotation = Quaternion.identity;
				motion.Reset();
				motionReady = false;
				return;
			}
			float deltaTime = Time.deltaTime;
			Vector3 val = model.TransformPoint(pivot);
			Vector3 forward = model.forward;
			Vector3 val2;
			if (instance.Sway.Value && motionReady && !(deltaTime > 0.25f))
			{
				val2 = val - previousPosition;
				if (!(((Vector3)(ref val2)).sqrMagnitude > 4f))
				{
					if (!(deltaTime <= 0f))
					{
						Vector3 val3 = (val - previousPosition) / deltaTime;
						Vector3 val4 = model.InverseTransformDirection(Vector3.ClampMagnitude((val3 - previousVelocity) / deltaTime, 18f));
						smoothedAcceleration = Vector3.Lerp(smoothedAcceleration, val4, 1f - Mathf.Exp((0f - deltaTime) / 0.08f));
						Vector3 val5 = smoothedAcceleration;
						float num = Vector3.SignedAngle(previousForward, forward, model.up) / deltaTime;
						motion.Step((0f - val5.z) * instance.MotionAmount.Value, (0f - num) * 0.025f, val5.x * instance.MotionAmount.Value, deltaTime, instance.Spring.Value, instance.Damping.Value, instance.MaxSwing.Value);
						moving.localRotation = Quaternion.Euler((float)motion.X, (float)motion.Y, (float)motion.Z);
						previousPosition = val;
						previousVelocity = val3;
						previousForward = forward;
					}
					return;
				}
			}
			motion.Reset();
			moving.localRotation = Quaternion.identity;
			previousPosition = val;
			val2 = (previousVelocity = (smoothedAcceleration = Vector3.zero));
			previousForward = forward;
			motionReady = true;
		}

		internal void Shutdown()
		{
			ClearParts();
			if (Object.op_Implicit((Object)(object)model))
			{
				((Component)model).gameObject.SetActive(false);
				Object.Destroy((Object)(object)((Component)model).gameObject);
			}
			model = (anchor = (moving = null));
			skin = null;
			motionReady = false;
			motion.Reset();
			foreach (Material material in materials)
			{
				if (Object.op_Implicit((Object)(object)material))
				{
					Object.Destroy((Object)(object)material);
				}
			}
			materials.Clear();
			foreach (Texture2D texture in textures)
			{
				if (Object.op_Implicit((Object)(object)texture))
				{
					Object.Destroy((Object)(object)texture);
				}
			}
			textures.Clear();
			revision = -1;
		}

		private void OnDestroy()
		{
			Shutdown();
		}
	}
	internal static class ArmTextures
	{
		internal const int Size = 32;

		private static float Frac(double x)
		{
			return (float)(x - Math.Floor(x));
		}

		private static float Hash(int x, int y)
		{
			return Frac(Math.Sin((double)x * 127.1 + (double)y * 311.7) * 43758.5453);
		}

		private static int Wrap(int x)
		{
			return (x % 32 + 32) % 32;
		}

		private static float Distance(float a, float b)
		{
			float num = Math.Abs(a - b);
			return Math.Min(num, 32f - num);
		}

		internal static float Height(bool iron, int x, int y)
		{
			x = Wrap(x);
			y = Wrap(y);
			if (iron)
			{
				float num = 0f;
				for (int i = 0; i < 4; i++)
				{
					for (int j = 0; j < 4; j++)
					{
						float b = (float)(j * 8 + 2) + Hash(j, i) * 4f;
						float b2 = (float)(i * 8 + 2) + Hash(i + 13, j + 7) * 4f;
						float num2 = Distance(x, b);
						float num3 = Distance(y, b2);
						float num4 = 2.7f + Hash(j + 3, i + 9) * 1.3f;
						float num5 = (float)Math.Sqrt(num2 * num2 + num3 * num3) / num4;
						if (num5 < 1f)
						{
							num -= ((float)Math.Cos((double)num5 * Math.PI) + 1f) * 0.5f * (0.33f + Hash(i, j) * 0.3f);
						}
					}
				}
				return num;
			}
			double num6 = (double)x * 0.7 + 0.18 * Math.Sin((double)y * 0.25) + 0.07 * Math.Sin((double)y * 0.65);
			float num7 = 0f;
			for (int k = 0; k < 4; k++)
			{
				for (int l = 0; l < 4; l++)
				{
					float num8 = Distance(x, (float)(l * 8 + 2) + Hash(l, k) * 3f) / 3.5f;
					float num9 = Distance(y, (float)(k * 8) + Hash(k, l) * 3f) / 6f;
					if (num8 * num8 + num9 * num9 < 1f)
					{
						num7 -= 0.12f * (1f - num8 * num8 - num9 * num9);
					}
				}
			}
			return num7 + 0.035f * (float)Math.Sin(num6 * 5.0);
		}

		internal static Point Normal(bool iron, int x, int y)
		{
			float num = (iron ? 1.25f : 0.48f);
			return new Point((Height(iron, x - 1, y) - Height(iron, x + 1, y)) * num, (Height(iron, x, y - 1) - Height(iron, x, y + 1)) * num, 1f).Unit;
		}

		internal static Point Color(bool iron, int x, int y)
		{
			x = Wrap(x);
			y = Wrap(y);
			if (iron)
			{
				float num = 0.92f + 0.045f * (float)Math.Sin((double)x * 0.37 + (double)y * 0.19) + 0.06f * Height(iron: true, x, y);
				return new Point(0.245f * num, 0.255f * num, 0.265f * num);
			}
			double num2 = (double)x * 0.7 + 0.18 * Math.Sin((double)y * 0.25) + 0.07 * Math.Sin((double)y * 0.65);
			float num3 = 1f + 0.08f * (float)Math.Sin(num2) + 0.045f * (float)Math.Sin(num2 * 5.0) + Height(iron: false, x, y) * 0.8f;
			float num4 = Distance(x, 11f) * 1.15f;
			float num5 = Distance(y, 20f) * 0.45f;
			float num6 = (float)Math.Sqrt(num4 * num4 + num5 * num5);
			if (num6 < 5f)
			{
				num3 -= 0.16f * (1f - num6 / 5f) * (1f + 0.4f * (float)Math.Cos(num6 * 3f));
			}
			return new Point(0.52f * num3, 0.37f * num3, 0.205f * num3);
		}
	}
	internal sealed class PackSkin
	{
		private readonly Point[] vertices;

		private readonly Point[] uv;

		private readonly int[] triangles;

		internal PackSkin(Point[] vertices, Point[] uv, int[] triangles)
		{
			this.vertices = vertices;
			this.uv = uv;
			this.triangles = triangles;
		}

		internal Point Sample(float y, float z)
		{
			float num = float.PositiveInfinity;
			Point result = default(Point);
			for (int i = 0; i < triangles.Length; i += 3)
			{
				int num2 = triangles[i];
				int num3 = triangles[i + 1];
				int num4 = triangles[i + 2];
				Point point = vertices[num2];
				Point point2 = vertices[num3];
				Point point3 = vertices[num4];
				float num5 = (point2.Z - point3.Z) * (point.Y - point3.Y) + (point3.Y - point2.Y) * (point.Z - point3.Z);
				if (Math.Abs(num5) < 1E-10f)
				{
					continue;
				}
				float num6 = ((point2.Z - point3.Z) * (y - point3.Y) + (point3.Y - point2.Y) * (z - point3.Z)) / num5;
				float num7 = ((point3.Z - point.Z) * (y - point3.Y) + (point.Y - point3.Y) * (z - point3.Z)) / num5;
				float num8 = 1f - num6 - num7;
				if (!(num6 < -1E-05f) && !(num7 < -1E-05f) && !(num8 < -1E-05f))
				{
					float num9 = num6 * point.X + num7 * point2.X + num8 * point3.X;
					if (!(num9 >= num))
					{
						num = num9;
						Point point4 = uv[num2] * num6 + uv[num3] * num7 + uv[num4] * num8;
						result = new Point(num9, point4.X, point4.Y);
					}
				}
			}
			if (!float.IsPositiveInfinity(num))
			{
				return result;
			}
			float num10 = float.PositiveInfinity;
			for (int j = 0; j < vertices.Length; j++)
			{
				Point point5 = vertices[j];
				if (!(point5.X > 0f))
				{
					float num11 = (point5.Y - y) * (point5.Y - y) + (point5.Z - z) * (point5.Z - z);
					if (!(num11 >= num10))
					{
						num10 = num11;
						result = new Point(point5.X, uv[j].X, uv[j].Y);
					}
				}
			}
			return result;
		}
	}
	internal sealed class Plugin : MonoBehaviour
	{
		internal static Plugin Instance;

		private ConfigFile Config;

		private ManualLogSource Logger;

		internal ConfigEntry<bool> Enabled;

		internal ConfigEntry<bool> Sway;

		internal ConfigEntry<float> Height;

		internal ConfigEntry<float> Reach;

		internal ConfigEntry<float> Side;

		internal ConfigEntry<float> LoopLift;

		internal ConfigEntry<float> MotionAmount;

		internal ConfigEntry<float> Spring;

		internal ConfigEntry<float> Damping;

		internal ConfigEntry<float> MaxSwing;

		internal ConfigEntry<Vector3> Offset;

		internal int Revision;

		private bool ready;

		private Harmony harmony;

		private readonly Func<Player, Transform, Transform> provider = GetAttachment;

		internal static readonly Type RigType = typeof(BackpackPlugin).Assembly.GetType("OctoPack.BackpackRig", throwOnError: true);

		private static readonly FieldInfo RigRoot = AccessTools.Field(RigType, "root");

		internal void Initialize(ConfigFile config, ManualLogSource logger)
		{
			//IL_00c4: 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_014e: Expected O, but got Unknown
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Expected O, but got Unknown
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Expected O, but got Unknown
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f9: Expected O, but got Unknown
			//IL_0229: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Expected O, but got Unknown
			//IL_02a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02af: Expected O, but got Unknown
			//IL_0383: Unknown result type (might be due to invalid IL or missing references)
			//IL_0390: Expected O, but got Unknown
			//IL_03bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03df: Expected O, but got Unknown
			//IL_03df: Expected O, but got Unknown
			Config = config;
			Logger = logger;
			ArmConfigMigration armConfigMigration = new ArmConfigMigration(config, Path.Combine(Paths.ConfigPath, "OctoPack_addon_LanternArm.cfg"));
			Instance = this;
			Enabled = armConfigMigration.Bind("General", "Enabled", fallback: true, "Show the crafted lantern arm only when equipped in backpack slots; hang backpack-carried lanterns from it. Off-hand mode stays unchanged.");
			Height = Number(armConfigMigration, "PostHeight", 1f, 0.76f, 1.35f, "Top of the upright in unscaled pack coordinates.");
			Reach = Number(armConfigMigration, "ForwardReach", 0.36f, 0.16f, 0.7f, "Arm reach forward over the left shoulder, in unscaled pack coordinates.");
			Side = Number(armConfigMigration, "SidePosition", -0.215f, -0.4f, -0.18f, "Left-side position of the upright. More negative moves it outward.");
			Offset = armConfigMigration.Bind<Vector3>("Placement", "Offset", Vector3.zero, "Move the whole arm and lantern hinge together in pack coordinates.");
			LoopLift = Number(armConfigMigration, "LanternLoopLift", 0.008f, -0.02f, 0.04f, "Raise the lantern loop slightly within the hook, in unscaled pack metres.");
			Sway = armConfigMigration.Bind("Motion", "Enabled", fallback: true, "Independent, restrained flex of the upper post and arm. The sewn leather sleeve stays attached to the pack.");
			MotionAmount = armConfigMigration.Bind("Motion", "MovementResponse", 0.45f, new ConfigDescription("Degrees of arm response per metre/second squared of movement acceleration.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2f), Array.Empty<object>()));
			Spring = armConfigMigration.Bind("Motion", "SpringStrength", 38f, new ConfigDescription("Restoring spring strength.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(10f, 100f), Array.Empty<object>()));
			Damping = armConfigMigration.Bind("Motion", "Damping", 0.72f, new ConfigDescription("Damping ratio; larger values settle sooner.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.2f, 2f), Array.Empty<object>()));
			MaxSwing = armConfigMigration.Bind("Motion", "MaxSwingDegrees", 3.5f, new ConfigDescription("Maximum combined independent arm deflection.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 6f), Array.Empty<object>()));
			Config.SettingChanged += SettingsChanged;
			armConfigMigration.Complete();
			if (Application.isBatchMode)
			{
				return;
			}
			harmony = new Harmony("OctoPack_addon_LanternArm");
			try
			{
				MethodInfo methodInfo = AccessTools.Method(RigType, "Initialize", new Type[2]
				{
					typeof(VisEquipment),
					BackpackBridge.CoreType
				}, (Type[])null);
				if (methodInfo == null || methodInfo.ReturnType != typeof(void))
				{
					throw new MissingMethodException("OctoPack rig initialization contract changed.");
				}
				harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(Plugin), "PackReady", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				ItemHook(typeof(Humanoid), "UseItem", "Use", null);
				ItemHook(typeof(Humanoid), "EquipItem", "Equip", null);
				ItemHook(typeof(Humanoid), "UnequipItem", "Unequip", null);
				ItemHook(typeof(Humanoid), "IsItemEquiped", null, "IsEquipped");
				ItemHook(typeof(Player), "CreateTombStone", "BeforeDeath", null);
				harmony.Patch((MethodBase)AccessTools.Method(typeof(Inventory), "Load", new Type[2]
				{
					typeof(ZPackage),
					typeof(bool)
				}, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(ArmItems), "Loaded", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				harmony.Patch((MethodBase)AccessTools.Method(typeof(InventoryGui), "DoCrafting", (Type[])null, (Type[])null), new HarmonyMethod(typeof(ArmItems), "BeforeCraft", (Type[])null), new HarmonyMethod(typeof(ArmItems), "AfterCraft", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				LanternAttachments.Register(this, provider);
				ready = true;
				Object[] array = Object.FindObjectsByType(RigType, (FindObjectsSortMode)0);
				for (int i = 0; i < array.Length; i++)
				{
					PackReady(array[i]);
				}
				Logger.LogInfo((object)"Lantern arm ready. Equip the crafted arm from a backpack slot to use the hook; F9 off-hand carry stays available.");
			}
			catch (Exception ex)
			{
				LanternAttachments.Unregister(this);
				harmony.UnpatchSelf();
				Logger.LogError((object)("Lantern arm activation failed; original bedroll attachment retained: " + ex));
			}
		}

		private ConfigEntry<float> Number(ArmConfigMigration migration, string name, float value, float min, float max, string text)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			return migration.Bind("Placement", name, value, new ConfigDescription(text, (AcceptableValueBase)(object)new AcceptableValueRange<float>(min, max), Array.Empty<object>()));
		}

		private void SettingsChanged(object sender, SettingChangedEventArgs e)
		{
			if ((object)e.ChangedSetting == Height || (object)e.ChangedSetting == Reach || (object)e.ChangedSetting == Side || (object)e.ChangedSetting == LoopLift || (object)e.ChangedSetting == Offset)
			{
				Revision++;
			}
		}

		private static void PackReady(object __instance)
		{
			if (Object.op_Implicit((Object)(object)Instance))
			{
				object? value = RigRoot.GetValue(__instance);
				Transform val = (Transform)((value is Transform) ? value : null);
				if (Object.op_Implicit((Object)(object)val))
				{
					Ensure(val);
				}
			}
		}

		private static ArmRig Ensure(Transform root)
		{
			ArmRig armRig = ((Component)root).GetComponent<ArmRig>();
			if (!Object.op_Implicit((Object)(object)armRig))
			{
				armRig = ((Component)root).gameObject.AddComponent<ArmRig>();
				armRig.Ensure();
			}
			return armRig;
		}

		internal static ArmRig Portable(Transform root, bool equipped, PortableContacts.GroundSettings ground = null)
		{
			if (!Object.op_Implicit((Object)(object)Instance) || !Object.op_Implicit((Object)(object)root))
			{
				return null;
			}
			ArmRig armRig = ((Component)root).GetComponent<ArmRig>();
			if (!Object.op_Implicit((Object)(object)armRig))
			{
				armRig = ((Component)root).gameObject.AddComponent<ArmRig>();
			}
			armRig.SetPortable(equipped, ground);
			return armRig;
		}

		private static Transform GetAttachment(Player player, Transform root)
		{
			if (!Object.op_Implicit((Object)(object)Instance) || !Instance.Enabled.Value || !Object.op_Implicit((Object)(object)root))
			{
				return null;
			}
			return Ensure(root).Anchor;
		}

		internal static Material PackMaterial()
		{
			object asset = BackpackBridge.Asset;
			if (asset == null)
			{
				return null;
			}
			if (AccessTools.Field(asset.GetType(), "Materials").GetValue(asset) is List<Material> list)
			{
				foreach (Material item in list)
				{
					if (Object.op_Implicit((Object)(object)item) && ((Object)item).name == "OctoPack_Leather")
					{
						return item;
					}
				}
			}
			return null;
		}

		internal static Mesh PackMesh()
		{
			object asset = BackpackBridge.Asset;
			if (asset == null)
			{
				return null;
			}
			if (AccessTools.Field(asset.GetType(), "Meshes").GetValue(asset) is List<Mesh> list)
			{
				foreach (Mesh item in list)
				{
					if (Object.op_Implicit((Object)(object)item) && ((Object)item).name == "OctoPack_Leather")
					{
						return item;
					}
				}
			}
			return null;
		}

		internal void Warn(Exception e)
		{
			Logger.LogWarning((object)("Lantern arm visual unavailable; original lantern attachment will be used: " + e));
		}

		private void ItemHook(Type type, string name, string before, string after)
		{
			//IL_001e: 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)
			harmony.Patch((MethodBase)AccessTools.Method(type, name, (Type[])null, (Type[])null), (before == null) ? ((HarmonyMethod)null) : new HarmonyMethod(typeof(ArmItems), before, (Type[])null), (after == null) ? ((HarmonyMethod)null) : new HarmonyMethod(typeof(ArmItems), after, (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}

		private void Update()
		{
			if (ready && !Application.isBatchMode)
			{
				try
				{
					ArmItems.Tick();
				}
				catch (Exception e)
				{
					Warn(e);
				}
			}
		}

		private void OnDestroy()
		{
			Shutdown();
		}

		internal void Shutdown()
		{
			if (!((Object)(object)Instance != (Object)(object)this))
			{
				ready = false;
				Config.SettingChanged -= SettingsChanged;
				ArmItems.Dispose();
				LanternAttachments.Unregister(this);
				Harmony obj = harmony;
				if (obj != null)
				{
					obj.UnpatchSelf();
				}
				ArmRig[] array = Object.FindObjectsByType<ArmRig>((FindObjectsInactive)1, (FindObjectsSortMode)0);
				foreach (ArmRig obj2 in array)
				{
					obj2.Shutdown();
					Object.Destroy((Object)(object)obj2);
				}
				Instance = null;
			}
		}
	}
}
namespace OctoPack_addon_Lantern
{
	internal static class AbilityActivationSound
	{
		internal const int Rate = 44100;

		internal static float Duration(int kind)
		{
			return kind switch
			{
				1 => 2.65f, 
				2 => 3.25f, 
				3 => 2.75f, 
				4 => 3.2f, 
				5 => 3.25f, 
				_ => throw new ArgumentOutOfRangeException("kind"), 
			};
		}

		internal static float[] Samples(int kind)
		{
			int num = (int)Math.Round((double)Duration(kind) * 44100.0, MidpointRounding.AwayFromZero);
			using Stream stream = typeof(AbilityActivationSound).Assembly.GetManifestResourceStream("OctoPack_addon_Lantern.Activation" + kind);
			if (stream == null)
			{
				throw new InvalidDataException("Missing lantern activation sound " + kind);
			}
			float[] array = ReadWave(stream);
			if (array.Length != num)
			{
				throw new InvalidDataException("Unexpected lantern activation sound duration " + kind);
			}
			return array;
		}

		internal static float[] ReadWave(Stream stream)
		{
			if (stream == null)
			{
				throw new ArgumentNullException("stream");
			}
			try
			{
				using BinaryReader binaryReader = new BinaryReader(stream, Encoding.UTF8, leaveOpen: true);
				if (binaryReader.ReadUInt32() != 1179011410)
				{
					throw new InvalidDataException("Activation sound must be RIFF WAVE");
				}
				uint num = binaryReader.ReadUInt32();
				if (binaryReader.ReadUInt32() != 1163280727 || binaryReader.ReadUInt32() != 544501094 || binaryReader.ReadUInt32() != 16)
				{
					throw new InvalidDataException("Activation sound requires the standard PCM WAVE header");
				}
				ushort num2 = binaryReader.ReadUInt16();
				ushort num3 = binaryReader.ReadUInt16();
				uint num4 = binaryReader.ReadUInt32();
				uint num5 = binaryReader.ReadUInt32();
				ushort num6 = binaryReader.ReadUInt16();
				ushort num7 = binaryReader.ReadUInt16();
				if (num2 != 1 || num3 != 1 || num4 != 44100 || num5 != 88200 || num6 != 2 || num7 != 16)
				{
					throw new InvalidDataException("Activation sound must be mono PCM16 at 44100 Hz");
				}
				if (binaryReader.ReadUInt32() != 1635017060)
				{
					throw new InvalidDataException("Activation sound is missing PCM data");
				}
				uint num8 = binaryReader.ReadUInt32();
				if (num8 < 44100 || (double)num8 > 308700.0 || num8 % 2 != 0 || num != 36 + num8)
				{
					throw new InvalidDataException("Activation sound length is invalid or unbounded");
				}
				float[] array = new float[num8 / 2];
				for (int i = 0; i < array.Length; i++)
				{
					array[i] = (float)binaryReader.ReadInt16() / 32768f;
				}
				if (stream.ReadByte() != -1)
				{
					throw new InvalidDataException("Activation sound has trailing data");
				}
				return array;
			}
			catch (EndOfStreamException innerException)
			{
				throw new InvalidDataException("Activation sound is truncated", innerException);
			}
		}
	}
	internal sealed class AbilityFeedbackGate<T>
	{
		private readonly Dictionary<T, string> played = new Dictionary<T, string>();

		internal bool TryMark(T source, string activation, double age, bool emitterReady, bool visible)
		{
			if (played.TryGetValue(source, out var value) && value == activation)
			{
				return false;
			}
			if (!AbilityFeedbackRules.Fresh(age) || !visible)
			{
				played[source] = activation;
				return false;
			}
			if (!emitterReady)
			{
				return false;
			}
			played[source] = activation;
			return true;
		}

		internal void Clear()
		{
			played.Clear();
		}
	}
	internal static class AbilityFeedbackRules
	{
		internal const double FreshSeconds = 1.5;

		internal static bool Fresh(double age)
		{
			if (age >= 0.0)
			{
				return age <= 1.5;
			}
			return false;
		}

		internal static float VisualDuration(int k)
		{
			return AuraEffects.Duration(k);
		}
	}
	internal static class AbilityRules
	{
		internal static double Remaining(double now, double end)
		{
			return Math.Max(0.0, end - now);
		}

		internal static float Recovery(double previousAge, double age, float duration, float total)
		{
			return (float)(Math.Max(0.0, Math.Min(age, duration) - Math.Max(0.0, previousAge)) * (double)total / (double)duration);
		}
	}
	internal sealed class AuraParticleRenderer : IDisposable
	{
		private sealed class Batch : IDisposable
		{
			private readonly GameObject obj;

			private readonly Mesh mesh;

			private readonly MeshRenderer renderer;

			private readonly List<Vector3> vertices = new List<Vector3>(12672);

			private readonly List<Vector2> uvs = new List<Vector2>(12672);

			private readonly List<Color> colors = new List<Color>(12672);

			private readonly List<int> indices = new List<int>(19008);

			private Vector3 minimum;

			private Vector3 maximum;

			internal Batch(Transform root, string name, Material material)
			{
				//IL_0048: Unknown result type (might be due to invalid IL or missing references)
				//IL_0052: Expected O, but got Unknown
				//IL_0065: Unknown result type (might be due to invalid IL or missing references)
				//IL_006a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0076: Expected O, but got Unknown
				obj = new GameObject(name);
				obj.transform.SetParent(root, false);
				mesh = new Mesh
				{
					name = name
				};
				mesh.MarkDynamic();
				obj.AddComponent<MeshFilter>().sharedMesh = mesh;
				renderer = obj.AddComponent<MeshRenderer>();
				((Renderer)renderer).sharedMaterial = material;
				((Renderer)renderer).shadowCastingMode = (ShadowCastingMode)0;
				((Renderer)renderer).receiveShadows = false;
				((Renderer)renderer).lightProbeUsage = (LightProbeUsage)0;
				((Renderer)renderer).reflectionProbeUsage = (ReflectionProbeUsage)0;
			}

			internal void Clear()
			{
				vertices.Clear();
				uvs.Clear();
				colors.Clear();
				indices.Clear();
			}

			internal void Hide()
			{
				if (Object.op_Implicit((Object)(object)renderer))
				{
					((Renderer)renderer).enabled = false;
				}
			}

			internal void Quad(Vector3 a, Vector3 b, Vector3 c, Vector3 d, AuraTint color, int sprite)
			{
				//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)
				Quad(a, b, c, d, color, color, color, color, sprite);
			}

			internal void Quad(Vector3 a, Vector3 b, Vector3 c, Vector3 d, AuraTint ca, AuraTint cb, AuraTint cc, AuraTint cd, int sprite)
			{
				//IL_0020: 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_002e: 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_0042: 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_005a: 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_00a7: Unknown result type (might be due to invalid IL or missing references)
				//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d3: 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_0115: Unknown result type (might be due to invalid IL or missing references)
				//IL_0141: 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_0199: 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_0012: 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_0014: 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_001a: Unknown result type (might be due to invalid IL or missing references)
				int count = vertices.Count;
				if (count == 0)
				{
					minimum = (maximum = a);
				}
				Include(a);
				Include(b);
				Include(c);
				Include(d);
				vertices.Add(a);
				vertices.Add(b);
				vertices.Add(c);
				vertices.Add(d);
				float num = ((float)(sprite * 128) + 0.5f) / 768f;
				float num2 = ((float)((sprite + 1) * 128) - 0.5f) / 768f;
				uvs.Add(new Vector2(num, 0.004f));
				uvs.Add(new Vector2(num2, 0.004f));
				uvs.Add(new Vector2(num2, 0.996f));
				uvs.Add(new Vector2(num, 0.996f));
				colors.Add(new Color(ca.R, ca.G, ca.B, ca.A));
				colors.Add(new Color(cb.R, cb.G, cb.B, cb.A));
				colors.Add(new Color(cc.R, cc.G, cc.B, cc.A));
				colors.Add(new Color(cd.R, cd.G, cd.B, cd.A));
				indices.Add(count);
				indices.Add(count + 1);
				indices.Add(count + 2);
				indices.Add(count);
				indices.Add(count + 2);
				indices.Add(count + 3);
			}

			private void Include(Vector3 p)
			{
				//IL_000c: 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_0038: 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_0048: 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_006f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0085: Unknown result type (might be due to invalid IL or missing references)
				//IL_0090: 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)
				minimum = new Vector3(Math.Min(minimum.x, p.x), Math.Min(minimum.y, p.y), Math.Min(minimum.z, p.z));
				maximum = new Vector3(Math.Max(maximum.x, p.x), Math.Max(maximum.y, p.y), Math.Max(maximum.z, p.z));
			}

			internal void Upload()
			{
				//IL_0081: Unknown result type (might be due to invalid IL or missing references)
				//IL_0087: Unknown result type (might be due to invalid IL or missing references)
				//IL_008c: 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_009c: 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_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)
				((Renderer)renderer).enabled = vertices.Count > 0;
				if (((Renderer)renderer).enabled)
				{
					mesh.Clear(false);
					mesh.SetVertices(vertices);
					mesh.SetUVs(0, uvs);
					mesh.SetColors(colors);
					mesh.SetTriangles(indices, 0, false);
					mesh.bounds = new Bounds((minimum + maximum) * 0.5f, maximum - minimum + new Vector3(0.002f, 0.002f, 0.002f));
				}
			}

			public void Dispose()
			{
				if (Object.op_Implicit((Object)(object)obj))
				{
					Object.Destroy((Object)(object)obj);
				}
				if (Object.op_Implicit((Object)(object)mesh))
				{
					Object.Destroy((Object)(object)mesh);
				}
			}
		}

		private static Material glowMaterial;

		private static Material smokeMaterial;

		private static Texture2D atlas;

		private readonly Batch glow;

		private readonly Batch smoke;

		private readonly int[] order = new int[768];

		private readonly float[] depth = new float[768];

		internal AuraParticleRenderer(Transform root)
		{
			Prepare();
			try
			{
				glow = new Batch(root, "Aura luminous particles", glowMaterial);
				smoke = new Batch(root, "Aura translucent vapour", smokeMaterial);
			}
			catch
			{
				Dispose();
				throw;
			}
		}

		private static Shader Find(string preferred)
		{
			string[] array = new string[3] { preferred, "Particles/Standard Unlit", "Sprites/Default" };
			for (int i = 0; i < array.Length; i++)
			{
				Shader val = Shader.Find(array[i]);
				if (Object.op_Implicit((Object)(object)val) && val.isSupported)
				{
					return val;
				}
			}
			Material[] array2 = Resources.FindObjectsOfTypeAll<Material>();
			foreach (Material val2 in array2)
			{
				if (Object.op_Implicit((Object)(object)val2) && Object.op_Implicit((Object)(object)val2.shader) && val2.shader.isSupported && (((Object)val2.shader).name == preferred || ((Object)val2.shader).name == "Sprites/Default" || (((Object)val2.shader).name.StartsWith("Custom/Particle", StringComparison.Ordinal) && val2.HasProperty("_MainTex"))))
				{
					return val2.shader;
				}
			}
			throw new InvalidOperationException("No supported vertex-colour particle shader is loaded");
		}

		private static Material Material(Shader shader, string name, bool additive)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: 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_0023: Expected O, but got Unknown
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			Material val = new Material(shader)
			{
				name = name,
				renderQueue = (additive ? 3100 : 3050)
			};
			if (val.HasProperty("_Mode"))
			{
				val.SetFloat("_Mode", (float)(additive ? 4 : 2));
			}
			bool flag = ((Object)shader).name == "Legacy Shaders/Particles/Additive" || ((Object)shader).name == "Legacy Shaders/Particles/Alpha Blended";
			if (val.HasProperty("_Color"))
			{
				val.SetColor("_Color", Color.white);
			}
			if (val.HasProperty("_TintColor"))
			{
				val.SetColor("_TintColor", (Color)(flag ? new Color(0.5f, 0.5f, 0.5f, 0.5f) : Color.white));
			}
			if (val.HasProperty("_SrcBlend"))
			{
				val.SetInt("_SrcBlend", 5);
			}
			if (val.HasProperty("_DstBlend"))
			{
				val.SetInt("_DstBlend", additive ? 1 : 10);
			}
			if (val.HasProperty("_ZWrite"))
			{
				val.SetInt("_ZWrite", 0);
			}
			if (val.HasProperty("_Cull"))
			{
				val.SetInt("_Cull", 0);
			}
			val.DisableKeyword("SOFTPARTICLES_ON");
			val.DisableKeyword("_ALPHATEST_ON");
			val.DisableKeyword("_ALPHAPREMULTIPLY_ON");
			val.mainTexture = (Texture)(object)atlas;
			return val;
		}

		private static void Prepare()
		{
			//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_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Expected O, but got Unknown
			//IL_00b6: 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 (Object.op_Implicit((Object)(object)glowMaterial) && Object.op_Implicit((Object)(object)smokeMaterial) && Object.op_Implicit((Object)(object)atlas))
			{
				return;
			}
			Shader shader = Find("Legacy Shaders/Particles/Additive");
			Shader shader2 = Find("Legacy Shaders/Particles/Alpha Blended");
			if (!Object.op_Implicit((Object)(object)atlas))
			{
				int num = 128;
				int num2 = num * 6;
				Color32[] array = (Color32[])(object)new Color32[num2 * num];
				for (int i = 0; i < 6; i++)
				{
					for (int j = 0; j < num; j++)
					{
						for (int k = 0; k < num; k++)
						{
							array[j * num2 + i * num + k] = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, (byte)Math.Round(255f * AuraSprites.Alpha(i, ((float)k + 0.5f) / (float)num, ((float)j + 0.5f) / (float)num)));
						}
					}
				}
				atlas = new Texture2D(num2, num, (TextureFormat)4, false)
				{
					name = "OctoPack_AuraParticleAtlas",
					wrapMode = (TextureWrapMode)1,
					filterMode = (FilterMode)1
				};
				atlas.SetPixels32(array);
				atlas.Apply(false, true);
			}
			if (!Object.op_Implicit((Object)(object)glowMaterial))
			{
				glowMaterial = Material(shader, "OctoPack_AuraLuminous", additive: true);
			}
			if (!Object.op_Implicit((Object)(object)smokeMaterial))
			{
				smokeMaterial = Material(shader2, "OctoPack_AuraVapour", additive: false);
			}
		}

		internal static void Warm()
		{
			Prepare();
		}

		internal void Draw(AuraFrame frame, float scale)
		{
			//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_0037: 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_0043: 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_0083: 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_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: 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_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: 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_013b: 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)
			//IL_012b: 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_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			Camera main = Camera.main;
			if (!Object.op_Implicit((Object)(object)main))
			{
				glow.Hide();
				smoke.Hide();
				return;
			}
			Vector3 right = ((Component)main).transform.right;
			Vector3 up = ((Component)main).transform.up;
			Vector3 forward = ((Component)main).transform.forward;
			glow.Clear();
			smoke.Clear();
			for (int i = 0; i < frame.QuadCount; i++)
			{
				AuraQuad auraQuad = frame.Quads[i];
				glow.Quad(V(auraQuad.A) * scale, V(auraQuad.B) * scale, V(auraQuad.C) * scale, V(auraQuad.D) * scale, auraQuad.Color, auraQuad.ColorB, auraQuad.ColorC, auraQuad.ColorD, auraQuad.Sprite);
			}
			int num = 0;
			for (int j = 0; j < frame.DotCount; j++)
			{
				AuraDot dot = frame.Dots[j];
				if (!dot.Smoke)
				{
					Dot(glow, dot, scale, right, up);
					continue;
				}
				float num2 = Vector3.Dot(V(dot.Position), forward);
				int num3 = num;
				while (num3 > 0 && depth[num3 - 1] < num2)
				{
					order[num3] = order[num3 - 1];
					depth[num3] = depth[num3 - 1];
					num3--;
				}
				order[num3] = j;
				depth[num3] = num2;
				num++;
			}
			for (int k = 0; k < num; k++)
			{
				Dot(smoke, frame.Dots[order[k]], scale, right, up);
			}
			glow.Upload();
			smoke.Upload();
		}

		private static Vector3 V(AuraVec p)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			return new Vector3(p.X, p.Y, p.Z);
		}

		private static void Dot(Batch batch, AuraDot dot, float scale, Vector3 right, Vector3 up)
		{
			//IL_0018: 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_001f: 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_0027: 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)
			//IL_0038: 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_003e: 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_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: 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_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: 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 miss