Decompiled source of UtgardeBackpacks v1.0.0

plugins/UtgardeBackpacks.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using AdventureBackpacks.API;
using AdventureBackpacks.Assets.Effects;
using AdventureBackpacks.Assets.Factories;
using AdventureBackpacks.Configuration;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using MagicaCloth2;
using UnityEngine;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace UtgardeBackpacks;

public sealed class BackpackCapeCloth : MonoBehaviour
{
	internal static bool EnableCapeCloth;

	[SerializeField]
	private SkinnedMeshRenderer _renderer;

	[SerializeField]
	private SkinnedMeshRenderer _bodyRenderer;

	private MagicaCloth _cloth;

	private GameObject _host;

	private GameObject _packHost;

	private Transform[] _boundBones;

	private Transform[] _pendingBones;

	private bool _materialsReady;

	private bool _building;

	private bool _failed;

	private Vector3 _lastPosition;

	private Quaternion _lastRotation;

	private static ManualLogSource _logger;

	internal static void Configure(ConfigFile config)
	{
		EnableCapeCloth = config.Bind<bool>("Motion", "EnableCapeCloth", false, "Enable Deep North cape cloth. Takes effect after restart.").Value;
	}

	internal static void SetLogger(ManualLogSource logger)
	{
		_logger = logger;
	}

	internal void Initialize(SkinnedMeshRenderer renderer, SkinnedMeshRenderer body)
	{
		_renderer = renderer;
		_bodyRenderer = body;
	}

	internal void RequestBuild()
	{
		_materialsReady = true;
		_failed = false;
	}

	internal bool NeedsRebind()
	{
		if (_pendingBones == null)
		{
			if (_boundBones != null)
			{
				return !_renderer.bones.Take(53).SequenceEqual(_boundBones);
			}
			return false;
		}
		return true;
	}

	internal bool PrepareMeshChange()
	{
		CapturePendingBones();
		_materialsReady = false;
		if ((Object)(object)_cloth != (Object)null)
		{
			((Behaviour)_cloth).enabled = false;
		}
		if (_building)
		{
			_renderer.bones = _pendingBones;
			return false;
		}
		DisposeCloth();
		_renderer.bones = _pendingBones;
		_pendingBones = null;
		return true;
	}

	private void CapturePendingBones()
	{
		if (!((Object)(object)_renderer == (Object)null))
		{
			Transform[] array = _renderer.bones.Take(53).ToArray();
			if (_pendingBones == null || (_boundBones != null && !array.SequenceEqual(_boundBones)))
			{
				_pendingBones = array;
			}
		}
	}

	private void OnEnable()
	{
		_materialsReady = false;
	}

	private void OnDisable()
	{
		CapturePendingBones();
		_materialsReady = false;
		if ((Object)(object)_host != (Object)null)
		{
			_host.SetActive(false);
		}
		if ((Object)(object)_packHost != (Object)null)
		{
			_packHost.SetActive(false);
		}
		if ((Object)(object)_renderer != (Object)null && _pendingBones != null)
		{
			_renderer.bones = _pendingBones;
		}
	}

	private void OnDestroy()
	{
		DisposeCloth();
	}

	private void LateUpdate()
	{
		//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_0100: 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_0113: 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_013f: 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_0146: Unknown result type (might be due to invalid IL or missing references)
		//IL_0147: Unknown result type (might be due to invalid IL or missing references)
		if (!EnableCapeCloth || !_materialsReady || _failed || (Object)(object)_renderer == (Object)null)
		{
			return;
		}
		if ((Object)(object)_cloth == (Object)null)
		{
			Transform val = ((IEnumerable<Transform>)_renderer.bones).FirstOrDefault((Func<Transform, bool>)((Transform bone) => (Object)(object)bone != (Object)null && ((Object)bone).name == "Spine2"));
			VisEquipment val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponentInParent<VisEquipment>() : null);
			if ((Object)(object)val2 == (Object)null || (Object)(object)val2.m_playerComponent == (Object)null)
			{
				return;
			}
			try
			{
				Build(val2);
				return;
			}
			catch (Exception ex)
			{
				_failed = true;
				DisposeCloth();
				ManualLogSource logger = _logger;
				if (logger != null)
				{
					logger.LogError((object)("UTGARDE_CLOTH failed: " + ex));
				}
				return;
			}
		}
		if (_cloth.IsValid())
		{
			Vector3 position = _boundBones[0].position;
			Quaternion rotation = _boundBones[0].rotation;
			if (Vector3.Distance(position, _lastPosition) > 2f || Quaternion.Angle(rotation, _lastRotation) > 90f || Time.deltaTime > 0.25f)
			{
				_cloth.ResetCloth(false);
			}
			_lastPosition = position;
			_lastRotation = rotation;
		}
	}

	internal static VertexAttribute[] Attributes(Mesh mesh)
	{
		Vector2[] uv = mesh.uv2;
		if (uv.Length != mesh.vertexCount || uv.Any((Vector2 value) => (value.x != 0f && value.x != 1f) || value.y != 0f))
		{
			throw new InvalidOperationException("Cape UV2 pin mask is missing or malformed.");
		}
		VertexAttribute[] array = uv.Select((Vector2 value) => (value.x != 1f) ? VertexAttribute.Move : VertexAttribute.Fixed).ToArray();
		if (!array.Any((VertexAttribute value) => ((VertexAttribute)(ref value)).IsFixed()) || !array.Any((VertexAttribute value) => ((VertexAttribute)(ref value)).IsMove()))
		{
			throw new InvalidOperationException("Cape pin mask needs both fixed and moving vertices.");
		}
		return array;
	}

	private void Build(VisEquipment equipment)
	{
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a3: Expected O, but got Unknown
		//IL_00e5: 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_01bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c4: 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_01e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f3: Expected O, but got Unknown
		//IL_025c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0261: Unknown result type (might be due to invalid IL or missing references)
		//IL_027c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0281: Unknown result type (might be due to invalid IL or missing references)
		//IL_0286: Unknown result type (might be due to invalid IL or missing references)
		//IL_0290: Expected O, but got Unknown
		//IL_02a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_03b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_03bb: Expected O, but got Unknown
		//IL_0473: Unknown result type (might be due to invalid IL or missing references)
		//IL_0478: Unknown result type (might be due to invalid IL or missing references)
		//IL_0486: Unknown result type (might be due to invalid IL or missing references)
		//IL_048b: Unknown result type (might be due to invalid IL or missing references)
		List<ColliderComponent> clothColliders = equipment.m_clothColliders;
		if (clothColliders == null || clothColliders.Count != 7 || clothColliders.Any((ColliderComponent collider) => (Object)(object)collider == (Object)null) || clothColliders.Distinct().Count() != 7)
		{
			throw new InvalidOperationException("Cape needs the seven registered player cloth colliders.");
		}
		VertexAttribute[] item = Attributes(_renderer.sharedMesh);
		ColliderComponent[] second = BackpackCapeColliders.Create(_bodyRenderer, out _packHost);
		_boundBones = _renderer.bones.Take(53).ToArray();
		_host = new GameObject("UtgardeCapeCloth");
		_host.SetActive(false);
		_host.transform.SetParent(((Component)this).transform, false);
		_cloth = _host.AddComponent<MagicaCloth>();
		ClothSerializeData serializeData = _cloth.SerializeData;
		serializeData.clothType = (ClothType)0;
		serializeData.sourceRenderers = new List<Renderer> { (Renderer)(object)_renderer };
		serializeData.paintMode = (PaintMode)0;
		serializeData.gravity = 7f;
		serializeData.damping.value = 0.1f;
		serializeData.damping.useCurve = false;
		serializeData.radius.value = 0.01f;
		serializeData.radius.useCurve = false;
		serializeData.animationPoseRatio = 0f;
		serializeData.inertiaConstraint.depthInertia = 0.7f;
		serializeData.angleRestorationConstraint.useAngleRestoration = true;
		serializeData.angleRestorationConstraint.stiffness.value = 0.15f;
		serializeData.angleRestorationConstraint.stiffness.useCurve = true;
		serializeData.angleRestorationConstraint.stiffness.curve = new AnimationCurve((Keyframe[])(object)new Keyframe[2]
		{
			new Keyframe(0f, 1f, 0f, 0f),
			new Keyframe(1f, 0.09678346f, -0.7f, -0.7f)
		});
		serializeData.angleRestorationConstraint.velocityAttenuation = 0.8f;
		serializeData.angleLimitConstraint.useAngleLimit = true;
		serializeData.angleLimitConstraint.limitAngle.value = 45f;
		serializeData.angleLimitConstraint.limitAngle.useCurve = true;
		serializeData.angleLimitConstraint.limitAngle.curve = new AnimationCurve((Keyframe[])(object)new Keyframe[2]
		{
			new Keyframe(0f, 0f, 2f, 2f),
			new Keyframe(1f, 1f, 0f, 0f)
		});
		serializeData.angleLimitConstraint.stiffness = 1f;
		serializeData.colliderCollisionConstraint.mode = (Mode)1;
		serializeData.colliderCollisionConstraint.friction = 0.2f;
		serializeData.colliderCollisionConstraint.limitDistance.value = 0.05f;
		serializeData.colliderCollisionConstraint.limitDistance.useCurve = false;
		serializeData.colliderCollisionConstraint.colliderList = new List<ColliderComponent>(clothColliders.Concat(second));
		serializeData.wind.influence = 0.15f;
		serializeData.wind.frequency = 1f;
		serializeData.wind.turbulence = 1f;
		serializeData.wind.blend = 0.7f;
		serializeData.wind.synchronization = 0.7f;
		serializeData.wind.depthWeight = 0f;
		serializeData.wind.movingWind = 0f;
		serializeData.reductionSetting.simpleDistance = 0.01f;
		serializeData.reductionSetting.shapeDistance = 0f;
		ClothSerializeData2 serializeData2 = _cloth.GetSerializeData2();
		serializeData2.vertexAttributeList.Add(item);
		serializeData2.preBuildData.enabled = false;
		serializeData2.preBuildData.uniquePreBuildData = new UniquePreBuildData();
		_cloth.OnBuildComplete = BuildComplete;
		_cloth.Initialize();
		_cloth.DisableAutoBuild();
		_cloth.ReplaceTransform(_boundBones.ToDictionary((Transform bone) => ((Object)bone).name, (Transform bone) => bone));
		_packHost.SetActive(true);
		_host.SetActive(true);
		_host.AddComponent<PlayerClothWindShelter>().SetPlayer(equipment.m_playerComponent);
		_lastPosition = _boundBones[0].position;
		_lastRotation = _boundBones[0].rotation;
		_building = true;
		if (!_cloth.BuildAndRun())
		{
			_building = false;
			_failed = true;
			throw new InvalidOperationException("Cape runtime build did not start; see the cloth failure log.");
		}
	}

	private void BuildComplete(MagicaCloth cloth, bool success)
	{
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_0067: 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)
		//IL_007f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0084: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)cloth != (Object)(object)_cloth)
		{
			return;
		}
		ResultCode result;
		if (!success)
		{
			result = cloth.Process.Result;
			if (((ResultCode)(ref result)).IsProcess())
			{
				return;
			}
			result = cloth.Process.Result;
			if (((ResultCode)(ref result)).IsSuccess())
			{
				return;
			}
		}
		_building = false;
		_failed = !success;
		if (!success)
		{
			ManualLogSource logger = _logger;
			if (logger != null)
			{
				result = cloth.Process.Result;
				string resultString = ((ResultCode)(ref result)).GetResultString();
				result = cloth.Process.Result;
				logger.LogError((object)("UTGARDE_CLOTH build failed: " + resultString + " " + ((ResultCode)(ref result)).GetResultInformation()));
			}
			PrepareMeshChange();
		}
	}

	private void DisposeCloth()
	{
		if ((Object)(object)_cloth != (Object)null)
		{
			_cloth.OnBuildComplete = null;
			((Behaviour)_cloth).enabled = false;
			_cloth.Process.Dispose();
		}
		if ((Object)(object)_host != (Object)null)
		{
			Object.Destroy((Object)(object)_host);
		}
		if ((Object)(object)_packHost != (Object)null)
		{
			Object.Destroy((Object)(object)_packHost);
		}
		_packHost = null;
		_host = null;
		_cloth = null;
		_boundBones = null;
		_building = false;
	}
}
internal static class BackpackCapeColliders
{
	internal static ColliderComponent[] Create(SkinnedMeshRenderer body, out GameObject host)
	{
		//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e9: Expected O, but got Unknown
		//IL_0119: Unknown result type (might be due to invalid IL or missing references)
		//IL_012a: Unknown result type (might be due to invalid IL or missing references)
		//IL_012f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0134: Unknown result type (might be due to invalid IL or missing references)
		//IL_0138: Unknown result type (might be due to invalid IL or missing references)
		//IL_0149: Unknown result type (might be due to invalid IL or missing references)
		//IL_014e: 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_015e: Unknown result type (might be due to invalid IL or missing references)
		//IL_016c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0191: Unknown result type (might be due to invalid IL or missing references)
		//IL_019e: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c4: 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_01ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
		//IL_0202: Unknown result type (might be due to invalid IL or missing references)
		//IL_0207: Unknown result type (might be due to invalid IL or missing references)
		//IL_0218: Unknown result type (might be due to invalid IL or missing references)
		//IL_021d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0222: Unknown result type (might be due to invalid IL or missing references)
		//IL_0276: Unknown result type (might be due to invalid IL or missing references)
		//IL_0278: Unknown result type (might be due to invalid IL or missing references)
		//IL_027d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0289: 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_0349: Unknown result type (might be due to invalid IL or missing references)
		//IL_037a: Unknown result type (might be due to invalid IL or missing references)
		//IL_039a: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_03e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_0408: Unknown result type (might be due to invalid IL or missing references)
		//IL_0428: Unknown result type (might be due to invalid IL or missing references)
		//IL_043b: 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_04a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_04bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_04d7: Unknown result type (might be due to invalid IL or missing references)
		//IL_0507: Unknown result type (might be due to invalid IL or missing references)
		//IL_0529: Unknown result type (might be due to invalid IL or missing references)
		//IL_0537: Unknown result type (might be due to invalid IL or missing references)
		//IL_054b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0558: Unknown result type (might be due to invalid IL or missing references)
		//IL_055d: Unknown result type (might be due to invalid IL or missing references)
		//IL_05ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_05bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_05d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_05da: Unknown result type (might be due to invalid IL or missing references)
		host = null;
		if ((Object)(object)body == (Object)null || (Object)(object)body.sharedMesh == (Object)null || !body.sharedMesh.isReadable)
		{
			throw new InvalidOperationException("Pack colliders need a readable body mesh.");
		}
		Mesh sharedMesh = body.sharedMesh;
		Transform[] bones = body.bones;
		if (bones.Length != 55 || sharedMesh.bindposes.Length != 55 || sharedMesh.boneWeights.Length != sharedMesh.vertexCount)
		{
			throw new InvalidOperationException("Pack colliders need the bound 55-slot body.");
		}
		int spineSlot = Array.FindIndex(bones, (Transform bone) => (Object)(object)bone != (Object)null && ((Object)bone).name == "Spine2");
		int num = Array.FindIndex(bones, (Transform bone) => (Object)(object)bone != (Object)null && ((Object)bone).name == "Hips");
		if (spineSlot < 0 || num < 0)
		{
			throw new InvalidOperationException("Pack collider anchors are missing.");
		}
		host = new GameObject("UtgardePackColliders");
		try
		{
			host.SetActive(false);
			host.transform.SetParent(bones[spineSlot], false);
			Transform transform = host.transform;
			Matrix4x4 val = sharedMesh.bindposes[spineSlot] * ((Matrix4x4)(ref sharedMesh.bindposes[num])).inverse;
			transform.localRotation = ((Matrix4x4)(ref val)).rotation;
			Vector3 lossyScale = host.transform.lossyScale;
			if (lossyScale.x <= 0f || lossyScale.y <= 0f || lossyScale.z <= 0f)
			{
				throw new InvalidOperationException("Pack collider scale must be positive.");
			}
			host.transform.localScale = new Vector3(1f / lossyScale.x, 1f / lossyScale.y, 1f / lossyScale.z);
			Vector3 val2 = host.transform.lossyScale - Vector3.one;
			if (((Vector3)(ref val2)).sqrMagnitude > 0.0001f)
			{
				throw new InvalidOperationException("Pack collider axes could not be normalized.");
			}
			Matrix4x4 conversion = host.transform.worldToLocalMatrix * bones[spineSlot].localToWorldMatrix * sharedMesh.bindposes[spineSlot];
			Vector3[] vertices = sharedMesh.vertices;
			BoneWeight[] weights = sharedMesh.boneWeights;
			Vector3[] vertices2 = (from index in Enumerable.Range(0, vertices.Length)
				where ((BoneWeight)(ref weights[index])).boneIndex0 == spineSlot && ((BoneWeight)(ref weights[index])).weight0 > 0.999f
				select vertices[index]).ToArray();
			Bounds bounds = BackpackMeshConversion.BoundsInSpace(vertices2, conversion);
			Vector3 size = ((Bounds)(ref bounds)).size;
			if (!Finite(size.x) || !Finite(size.y) || !Finite(size.z) || size.x < 0.01f || size.y < 0.01f || size.z < 0.01f)
			{
				throw new InvalidOperationException("Pack rigid-body bounds are empty or malformed.");
			}
			float margin = 0.005f;
			float radius = Mathf.Min(size.z * 0.4f, size.x * 0.4f);
			float left = ((Bounds)(ref bounds)).min.x + radius;
			Transform parent = host.transform;
			MagicaCapsuleCollider[] first = new float[3]
			{
				((Bounds)(ref bounds)).min.z + radius * 0.35f,
				((Bounds)(ref bounds)).center.z,
				((Bounds)(ref bounds)).max.z - radius * 0.35f
			}.Select((float depth, int index) => Capsule(parent, "LeftFace" + index, new Vector3(left, ((Bounds)(ref bounds)).center.y, depth), radius + margin, size.y + (radius + margin) * 2f, (Direction)1)).ToArray();
			float right = ((Bounds)(ref bounds)).max.x - radius;
			MagicaCapsuleCollider[] second = new float[3]
			{
				((Bounds)(ref bounds)).min.z + radius * 0.35f,
				((Bounds)(ref bounds)).center.z,
				((Bounds)(ref bounds)).max.z - radius * 0.35f
			}.Select((float depth, int index) => Capsule(parent, "RightFace" + index, new Vector3(right, ((Bounds)(ref bounds)).center.y, depth), radius + margin, size.y + (radius + margin) * 2f, (Direction)1)).ToArray();
			float num2 = Mathf.Min(size.y, size.z) * 0.15f;
			Vector3 val3 = default(Vector3);
			((Vector3)(ref val3))..ctor(((Bounds)(ref bounds)).min.x + num2, ((Bounds)(ref bounds)).max.y - num2, ((Bounds)(ref bounds)).center.z);
			MagicaCapsuleCollider val4 = Capsule(host.transform, "TopCoverEdge", val3, num2 + margin, size.z + margin * 2f, (Direction)2);
			MagicaSphereCollider val5 = new GameObject("TopCoverCorner").AddComponent<MagicaSphereCollider>();
			((Component)val5).transform.SetParent(host.transform, false);
			((ColliderComponent)val5).center = new Vector3(val3.x - margin, val3.y + margin, ((Bounds)(ref bounds)).min.z + num2);
			val5.SetSize(num2 + margin);
			float num3 = Mathf.Min(size.z * 0.25f, size.y * 0.18f);
			MagicaCapsuleCollider val6 = Capsule(host.transform, "BottomRoll", new Vector3(((Bounds)(ref bounds)).center.x, ((Bounds)(ref bounds)).min.y + num3, ((Bounds)(ref bounds)).center.z), num3 + margin, size.x + margin * 2f, (Direction)0);
			return first.Concat(second).Cast<ColliderComponent>().Concat((IEnumerable<ColliderComponent>)(object)new ColliderComponent[3]
			{
				(ColliderComponent)val4,
				(ColliderComponent)val5,
				(ColliderComponent)val6
			})
				.ToArray();
		}
		catch
		{
			Object.Destroy((Object)(object)host);
			host = null;
			throw;
		}
	}

	private static bool Finite(float value)
	{
		if (!float.IsNaN(value))
		{
			return !float.IsInfinity(value);
		}
		return false;
	}

	private static MagicaCapsuleCollider Capsule(Transform parent, string name, Vector3 centre, float radius, float length, Direction direction)
	{
		//IL_0001: 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)
		//IL_0020: 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)
		MagicaCapsuleCollider obj = new GameObject(name).AddComponent<MagicaCapsuleCollider>();
		((Component)obj).transform.SetParent(parent, false);
		((ColliderComponent)obj).center = centre;
		obj.direction = direction;
		obj.alignedOnCenter = true;
		obj.SetSize(radius, radius, Mathf.Max(length, radius * 2f));
		return obj;
	}
}
internal sealed class BackpackClones
{
	private readonly ManualLogSource _logger;

	private readonly BackpackVisuals _visuals;

	private readonly bool _headless;

	private GameObject _container;

	private GameObject _source;

	internal BackpackClones(ManualLogSource logger)
	{
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0014: Invalid comparison between Unknown and I4
		_logger = logger;
		_headless = (int)SystemInfo.graphicsDeviceType == 4 || Environment.GetCommandLineArgs().Any((string argument) => string.Equals(argument, "-nographics", StringComparison.OrdinalIgnoreCase));
		if (_headless)
		{
			_logger.LogInfo((object)"Headless process: skipping backpack visuals and inventory icons.");
		}
		else
		{
			_visuals = new BackpackVisuals(logger);
		}
	}

	internal GameObject Create(BackpackSpec spec)
	{
		//IL_012a: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = LoadSource();
		if ((Object)(object)val == (Object)null)
		{
			return null;
		}
		GameObject val2 = Object.Instantiate<GameObject>(val, GetContainer().transform, false);
		((Object)val2).name = spec.PrefabName;
		ItemDrop component = val2.GetComponent<ItemDrop>();
		if ((Object)(object)component == (Object)null)
		{
			_logger.LogError((object)("BackpackMistlands has no ItemDrop; cannot build " + spec.PrefabName + "."));
			Object.Destroy((Object)(object)val2);
			return null;
		}
		SharedData shared = component.m_itemData.m_shared;
		shared.m_name = "$" + spec.NameToken;
		shared.m_description = "$" + spec.DescriptionToken;
		shared.m_damageModifiers = new List<DamageModPair>(spec.DamageModifiers);
		if (!_headless)
		{
			try
			{
				if (spec == Backpacks.Ashlands)
				{
					shared.m_icons = (Sprite[])(object)new Sprite[1] { InventoryIcons.Ashlands() };
				}
				if (spec == Backpacks.Ashlands || spec == Backpacks.DeepNorth)
				{
					if (!_visuals.Apply(val2, (spec == Backpacks.Ashlands) ? "Ashlands" : "DeepNorth"))
					{
						_logger.LogWarning((object)(spec.PrefabName + " visuals failed; item registration will continue."));
					}
				}
				else
				{
					Tint(val2, spec.Tint);
				}
			}
			catch (Exception arg)
			{
				_logger.LogWarning((object)$"{spec.PrefabName} visual assets failed; item registration will continue: {arg}");
			}
		}
		return val2;
	}

	private GameObject LoadSource()
	{
		if ((Object)(object)_source != (Object)null)
		{
			return _source;
		}
		AssetBundle val = ((IEnumerable<AssetBundle>)Resources.FindObjectsOfTypeAll<AssetBundle>()).FirstOrDefault((Func<AssetBundle, bool>)((AssetBundle loaded) => ((Object)loaded).name == "backpack_mistlands"));
		if ((Object)(object)val == (Object)null)
		{
			using Stream stream = typeof(ABAPI).Assembly.GetManifestResourceStream("AdventureBackpacks.Assets.Bundles.backpack_mistlands");
			if (stream == null)
			{
				_logger.LogError((object)"AdventureBackpacks has no embedded resource AdventureBackpacks.Assets.Bundles.backpack_mistlands.");
				return null;
			}
			using MemoryStream memoryStream = new MemoryStream();
			stream.CopyTo(memoryStream);
			val = AssetBundle.LoadFromMemory(memoryStream.ToArray());
		}
		if ((Object)(object)val == (Object)null)
		{
			_logger.LogError((object)"Could not load the backpack_mistlands asset bundle.");
			return null;
		}
		_source = val.LoadAsset<GameObject>("BackpackMistlands");
		if ((Object)(object)_source == (Object)null)
		{
			_logger.LogError((object)"Asset bundle backpack_mistlands has no prefab BackpackMistlands.");
		}
		return _source;
	}

	private GameObject GetContainer()
	{
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Expected O, but got Unknown
		if ((Object)(object)_container == (Object)null)
		{
			_container = new GameObject("UtgardeBackpacksPrefabs");
			Object.DontDestroyOnLoad((Object)(object)_container);
			_container.SetActive(false);
		}
		return _container;
	}

	private static void Tint(GameObject clone, Color tint)
	{
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_006b: Expected O, but got Unknown
		//IL_006f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0074: Unknown result type (might be due to invalid IL or missing references)
		//IL_0075: Unknown result type (might be due to invalid IL or missing references)
		Renderer[] componentsInChildren = clone.GetComponentsInChildren<Renderer>(true);
		foreach (Renderer val in componentsInChildren)
		{
			if (val is ParticleSystemRenderer)
			{
				continue;
			}
			Material[] sharedMaterials = val.sharedMaterials;
			for (int j = 0; j < sharedMaterials.Length; j++)
			{
				Material val2 = sharedMaterials[j];
				if (!((Object)(object)val2 == (Object)null) && val2.HasProperty("_Color"))
				{
					Material val3 = new Material(val2)
					{
						name = ((Object)val2).name + "_" + ((Object)clone).name
					};
					val3.color = val2.color * tint;
					sharedMaterials[j] = val3;
				}
			}
			val.sharedMaterials = sharedMaterials;
		}
	}
}
internal static class BackpackMeshConversion
{
	internal static Mesh Convert(Mesh source, Matrix4x4 conversion, string name)
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_005a: Unknown result type (might be due to invalid IL or missing references)
		//IL_005e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: Unknown result type (might be due to invalid IL or missing references)
		//IL_0070: Unknown result type (might be due to invalid IL or missing references)
		//IL_0138: Unknown result type (might be due to invalid IL or missing references)
		//IL_013d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0145: Unknown result type (might be due to invalid IL or missing references)
		//IL_014c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0153: Unknown result type (might be due to invalid IL or missing references)
		//IL_015a: Unknown result type (might be due to invalid IL or missing references)
		//IL_015f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0164: Unknown result type (might be due to invalid IL or missing references)
		//IL_0166: Unknown result type (might be due to invalid IL or missing references)
		//IL_016b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0170: 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_017f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0184: Unknown result type (might be due to invalid IL or missing references)
		//IL_0189: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01de: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_0204: Unknown result type (might be due to invalid IL or missing references)
		//IL_0209: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)source == (Object)null || !source.isReadable || Mathf.Abs(((Matrix4x4)(ref conversion)).determinant) < 1E-10f)
		{
			throw new InvalidOperationException("Cannot convert an unreadable mesh or singular transform.");
		}
		Mesh val = Object.Instantiate<Mesh>(source);
		((Object)val).name = name;
		Matrix4x4 inverse = ((Matrix4x4)(ref conversion)).inverse;
		Matrix4x4 normalMatrix = ((Matrix4x4)(ref inverse)).transpose;
		val.vertices = ((IEnumerable<Vector3>)source.vertices).Select((Func<Vector3, Vector3>)((Matrix4x4)(object)conversion).MultiplyPoint3x4).ToArray();
		Vector3[] array = (val.normals = source.normals.Select(delegate(Vector3 normal)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val4 = ((Matrix4x4)(ref normalMatrix)).MultiplyVector(normal);
			return ((Vector3)(ref val4)).normalized;
		}).ToArray());
		if (((Matrix4x4)(ref conversion)).determinant < 0f)
		{
			for (int num = 0; num < val.subMeshCount; num++)
			{
				int[] triangles = val.GetTriangles(num);
				for (int num2 = 0; num2 < triangles.Length; num2 += 3)
				{
					int num3 = triangles[num2 + 1];
					triangles[num2 + 1] = triangles[num2 + 2];
					triangles[num2 + 2] = num3;
				}
				val.SetTriangles(triangles, num);
			}
		}
		Vector4[] tangents = source.tangents;
		for (int num4 = 0; num4 < tangents.Length; num4++)
		{
			Vector4 val2 = tangents[num4];
			Vector3 val3 = ((Matrix4x4)(ref conversion)).MultiplyVector(new Vector3(val2.x, val2.y, val2.z));
			val3 -= array[num4] * Vector3.Dot(val3, array[num4]);
			if (((Vector3)(ref val3)).sqrMagnitude < 1E-10f)
			{
				val3 = Vector3.Cross((Mathf.Abs(array[num4].y) < 0.9f) ? Vector3.up : Vector3.right, array[num4]);
			}
			((Vector3)(ref val3)).Normalize();
			tangents[num4] = new Vector4(val3.x, val3.y, val3.z, val2.w * Mathf.Sign(((Matrix4x4)(ref conversion)).determinant));
		}
		val.tangents = tangents;
		val.bindposes = source.bindposes.Select((Matrix4x4 bindpose) => bindpose * ((Matrix4x4)(ref conversion)).inverse).ToArray();
		val.RecalculateBounds();
		return val;
	}

	internal static Bounds BoundsInSpace(Vector3[] vertices, Matrix4x4 conversion)
	{
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_003b: 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_0050: Unknown result type (might be due to invalid IL or missing references)
		if (vertices.Length == 0)
		{
			throw new InvalidOperationException("Cannot fit bounds to an empty mesh.");
		}
		Bounds result = default(Bounds);
		((Bounds)(ref result))..ctor(((Matrix4x4)(ref conversion)).MultiplyPoint3x4(vertices[0]), Vector3.zero);
		foreach (Vector3 val in vertices)
		{
			((Bounds)(ref result)).Encapsulate(((Matrix4x4)(ref conversion)).MultiplyPoint3x4(val));
		}
		return result;
	}
}
internal static class BackpackNormals
{
	private readonly struct WeldKey : IEquatable<WeldKey>
	{
		private readonly Vector3 _position;

		private readonly BoneWeight _weight;

		private readonly Vector2 _pin;

		internal WeldKey(Vector3 position, BoneWeight weight, Vector2 pin)
		{
			//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_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			_position = position;
			_weight = weight;
			_pin = pin;
		}

		public bool Equals(WeldKey other)
		{
			//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_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = _position;
			if (((Vector3)(ref position)).Equals(other._position))
			{
				BoneWeight weight = _weight;
				if (((BoneWeight)(ref weight)).Equals(other._weight))
				{
					Vector2 pin = _pin;
					return ((Vector2)(ref pin)).Equals(other._pin);
				}
			}
			return false;
		}

		public override bool Equals(object other)
		{
			if (other is WeldKey other2)
			{
				return Equals(other2);
			}
			return false;
		}

		public override int GetHashCode()
		{
			//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_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: 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)
			return (((object)_position/*cast due to .constrained prefix*/).GetHashCode() * 31 + ((object)_weight/*cast due to .constrained prefix*/).GetHashCode()) * 31 + ((object)_pin/*cast due to .constrained prefix*/).GetHashCode();
		}
	}

	internal static void Smooth(Mesh mesh, float maximumAngle)
	{
		//IL_0118: 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_0125: Unknown result type (might be due to invalid IL or missing references)
		//IL_012d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0135: Unknown result type (might be due to invalid IL or missing references)
		//IL_013a: Unknown result type (might be due to invalid IL or missing references)
		//IL_013f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0144: Unknown result type (might be due to invalid IL or missing references)
		//IL_0207: Unknown result type (might be due to invalid IL or missing references)
		//IL_020c: Unknown result type (might be due to invalid IL or missing references)
		//IL_020e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0210: Unknown result type (might be due to invalid IL or missing references)
		//IL_0237: Unknown result type (might be due to invalid IL or missing references)
		//IL_023c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0185: Unknown result type (might be due to invalid IL or missing references)
		//IL_0196: Unknown result type (might be due to invalid IL or missing references)
		//IL_019b: Unknown result type (might be due to invalid IL or missing references)
		//IL_019d: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_0230: Unknown result type (might be due to invalid IL or missing references)
		//IL_0225: Unknown result type (might be due to invalid IL or missing references)
		//IL_0235: Unknown result type (might be due to invalid IL or missing references)
		//IL_0257: Unknown result type (might be due to invalid IL or missing references)
		//IL_025c: Unknown result type (might be due to invalid IL or missing references)
		//IL_025e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0262: Unknown result type (might be due to invalid IL or missing references)
		//IL_0276: Unknown result type (might be due to invalid IL or missing references)
		//IL_0278: Unknown result type (might be due to invalid IL or missing references)
		//IL_027a: Unknown result type (might be due to invalid IL or missing references)
		//IL_027f: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b7: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)mesh == (Object)null || !mesh.isReadable || mesh.vertexCount == 0 || float.IsNaN(maximumAngle) || float.IsInfinity(maximumAngle) || maximumAngle <= 0f || maximumAngle > 180f)
		{
			throw new InvalidOperationException("Cannot smooth an empty, unreadable mesh or invalid angle.");
		}
		Vector3[] vertices = mesh.vertices;
		BoneWeight[] weights = mesh.boneWeights;
		Vector2[] pins = mesh.uv2;
		WeldKey[] array = vertices.Select((Vector3 position, int index) => new WeldKey(position, (BoneWeight)((weights.Length == 0) ? default(BoneWeight) : weights[index]), (Vector2)((pins.Length == 0) ? default(Vector2) : pins[index]))).ToArray();
		Dictionary<WeldKey, List<Vector3>> dictionary = new Dictionary<WeldKey, List<Vector3>>();
		Vector3[] array2 = (Vector3[])(object)new Vector3[vertices.Length];
		WeldKey[] array3 = array;
		foreach (WeldKey key in array3)
		{
			if (!dictionary.ContainsKey(key))
			{
				dictionary.Add(key, new List<Vector3>());
			}
		}
		foreach (int item in Enumerable.Range(0, mesh.subMeshCount))
		{
			int[] triangles = mesh.GetTriangles(item);
			for (int num2 = 0; num2 < triangles.Length; num2 += 3)
			{
				int num3 = triangles[num2];
				int num4 = triangles[num2 + 1];
				int num5 = triangles[num2 + 2];
				Vector3 val = Vector3.Cross(vertices[num4] - vertices[num3], vertices[num5] - vertices[num3]);
				if (!(((Vector3)(ref val)).sqrMagnitude < 1E-20f))
				{
					int[] array4 = new int[3] { num3, num4, num5 };
					foreach (int num6 in array4)
					{
						dictionary[array[num6]].Add(val);
						ref Vector3 reference = ref array2[num6];
						reference += val;
					}
				}
			}
		}
		Vector3[] normals = mesh.normals;
		float num7 = Mathf.Cos(maximumAngle * ((float)Math.PI / 180f));
		for (int num8 = 0; num8 < vertices.Length; num8++)
		{
			Vector3 val2 = ((Vector3)(ref array2[num8])).normalized;
			if (val2 == Vector3.zero)
			{
				val2 = ((normals.Length == vertices.Length) ? normals[num8] : Vector3.up);
			}
			Vector3 val3 = Vector3.zero;
			foreach (Vector3 item2 in dictionary[array[num8]])
			{
				Vector3 current2 = item2;
				if (Vector3.Dot(val2, ((Vector3)(ref current2)).normalized) >= num7 - 1E-05f)
				{
					val3 += current2;
				}
			}
			array2[num8] = ((((Vector3)(ref val3)).sqrMagnitude > 1E-20f) ? ((Vector3)(ref val3)).normalized : val2);
		}
		mesh.normals = array2;
	}
}
public sealed class BackpackRenderer : MonoBehaviour
{
	internal const float AttachmentScale = 0.85f;

	[SerializeField]
	private float _attachmentScale;

	[SerializeField]
	private Renderer _renderer;

	[SerializeField]
	private string _rootBoneName;

	[SerializeField]
	private Mesh _shippedMesh;

	[SerializeField]
	private Material[] _legacyMaterials;

	[SerializeField]
	private int[] _settings;

	[SerializeField]
	private GameObject _proxyVolume;

	[SerializeField]
	private float _motionPadding;

	[SerializeField]
	private BackpackCapeCloth _capeCloth;

	private Material[] _instanceMaterials;

	private bool _pending;

	private int _stateWrites;

	private static ManualLogSource _logger;

	internal Renderer Target => _renderer;

	internal static void SetLogger(ManualLogSource logger)
	{
		_logger = logger;
	}

	internal void Initialize(Renderer original, Renderer imported, string biome, Material[] legacyMaterials, Shader standardShader, Renderer settingsSource = null, Matrix4x4? visualRootMatrix = null)
	{
		//IL_0044: 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_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_0059: Unknown result type (might be due to invalid IL or missing references)
		//IL_0076: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_007b: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0086: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
		//IL_0103: Unknown result type (might be due to invalid IL or missing references)
		//IL_0104: Unknown result type (might be due to invalid IL or missing references)
		//IL_0109: Unknown result type (might be due to invalid IL or missing references)
		//IL_010a: Unknown result type (might be due to invalid IL or missing references)
		//IL_010f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0113: Unknown result type (might be due to invalid IL or missing references)
		//IL_0153: Unknown result type (might be due to invalid IL or missing references)
		//IL_0158: Unknown result type (might be due to invalid IL or missing references)
		//IL_0163: Unknown result type (might be due to invalid IL or missing references)
		//IL_0168: Unknown result type (might be due to invalid IL or missing references)
		//IL_016d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0178: Unknown result type (might be due to invalid IL or missing references)
		//IL_017d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0182: Unknown result type (might be due to invalid IL or missing references)
		//IL_0264: Unknown result type (might be due to invalid IL or missing references)
		//IL_026b: Expected O, but got Unknown
		//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_01af: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c4: 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_01ce: Unknown result type (might be due to invalid IL or missing references)
		_renderer = original;
		_attachmentScale = 1f;
		_legacyMaterials = legacyMaterials;
		_settings = CaptureSettings(settingsSource ?? original);
		_proxyVolume = (settingsSource ?? original).lightProbeProxyVolumeOverride;
		Matrix4x4 val = ((Component)this).transform.worldToLocalMatrix * ((Component)imported).transform.localToWorldMatrix;
		Matrix4x4 val2 = (Matrix4x4)(((??)visualRootMatrix) ?? ((Component)this).transform.localToWorldMatrix);
		Transform val3 = ((Component)original).transform;
		while ((Object)(object)val3 != (Object)null && (Object)(object)val3 != (Object)(object)((Component)this).transform)
		{
			val3.localScale = Vector3.one;
			val3 = val3.parent;
		}
		if ((Object)(object)val3 != (Object)(object)((Component)this).transform)
		{
			throw new InvalidOperationException("Backpack renderer is outside its visual root.");
		}
		((Component)this).transform.localScale = Vector3.one;
		SkinnedMeshRenderer val4 = (SkinnedMeshRenderer)(object)((imported is SkinnedMeshRenderer) ? imported : null);
		Mesh source = ((val4 != null) ? val4.sharedMesh : ((Component)imported).GetComponent<MeshFilter>().sharedMesh);
		Matrix4x4 conversion = ((Component)original).transform.worldToLocalMatrix * val2 * val;
		_shippedMesh = BackpackMeshConversion.Convert(source, conversion, "Utgarde" + biome + "Original");
		SkinnedMeshRenderer val5 = (SkinnedMeshRenderer)(object)((original is SkinnedMeshRenderer) ? original : null);
		if (val5 != null)
		{
			SkinnedMeshRenderer val6 = (SkinnedMeshRenderer)(object)((imported is SkinnedMeshRenderer) ? imported : null);
			if (val6 != null)
			{
				Matrix4x4 val7 = ((Component)this).transform.localToWorldMatrix * Matrix4x4.Scale(Vector3.one * _attachmentScale) * ((Component)this).transform.worldToLocalMatrix;
				Matrix4x4[] bindposes = _shippedMesh.bindposes;
				for (int i = 0; i < 53; i++)
				{
					Transform val8 = val6.bones[i];
					bindposes[i] = val8.worldToLocalMatrix * val7 * val8.localToWorldMatrix * bindposes[i];
				}
				_shippedMesh.bindposes = bindposes;
				Transform rootBone = ((SkinnedMeshRenderer)(((object)((settingsSource is SkinnedMeshRenderer) ? settingsSource : null)) ?? ((object)val5))).rootBone;
				_rootBoneName = (((Object)(object)rootBone != (Object)null) ? ((Object)rootBone).name : null);
				val5.sharedMesh = _shippedMesh;
				val5.bones = val6.bones;
				goto IL_0248;
			}
		}
		((Component)original).GetComponent<MeshFilter>().sharedMesh = _shippedMesh;
		goto IL_0248;
		IL_0248:
		original.sharedMaterials = imported.sharedMaterials;
		RestoreSettings();
		if ((Object)(object)settingsSource != (Object)null)
		{
			MaterialPropertyBlock val9 = new MaterialPropertyBlock();
			settingsSource.GetPropertyBlock(val9);
			original.SetPropertyBlock(val9);
			for (int j = 0; j < original.sharedMaterials.Length; j++)
			{
				settingsSource.GetPropertyBlock(val9, Mathf.Min(j, settingsSource.sharedMaterials.Length - 1));
				original.SetPropertyBlock(val9, j);
			}
		}
		original.enabled = true;
		Refresh();
	}

	internal void SetCapeCloth(BackpackCapeCloth cloth)
	{
		_capeCloth = cloth;
	}

	internal void SetMotionPadding(float padding)
	{
		_motionPadding = padding;
		Refresh();
	}

	internal void ScaleAttachment()
	{
		//IL_0006: 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)
		((Component)this).transform.localScale = Vector3.one * _attachmentScale;
		Refresh();
	}

	private void OnEnable()
	{
		_pending = true;
	}

	private void LateUpdate()
	{
		if ((Object)(object)_renderer == (Object)null)
		{
			return;
		}
		if (_pending)
		{
			_pending = false;
			try
			{
				ApplyInstance();
				return;
			}
			catch (Exception ex)
			{
				ManualLogSource logger = _logger;
				if (logger != null)
				{
					logger.LogError((object)("Post-spawn backpack material apply failed: " + ex));
				}
				return;
			}
		}
		Renderer renderer = _renderer;
		SkinnedMeshRenderer val = (SkinnedMeshRenderer)(object)((renderer is SkinnedMeshRenderer) ? renderer : null);
		Transform val2 = (Transform)(((Object)(object)val != (Object)null) ? ((object)((IEnumerable<Transform>)val.bones).FirstOrDefault((Func<Transform, bool>)((Transform bone) => (Object)(object)bone != (Object)null && ((Object)bone).name == "Spine2"))) : ((object)((Component)this).transform));
		if ((Object)(object)_capeCloth != (Object)null && (_capeCloth.NeedsRebind() || (Object)(object)_renderer.probeAnchor != (Object)(object)val2))
		{
			_pending = true;
			ApplyInstance();
		}
		else if ((Object)(object)_renderer.probeAnchor != (Object)(object)val2)
		{
			Refresh();
		}
	}

	private void OnDestroy()
	{
		ReleaseInstanceMaterials();
	}

	internal void ApplyInstance()
	{
		if ((Object)(object)_renderer == (Object)null)
		{
			throw new InvalidOperationException("Backpack renderer has not been initialized.");
		}
		if ((Object)(object)_capeCloth != (Object)null && !_capeCloth.PrepareMeshChange())
		{
			_pending = true;
			return;
		}
		((Component)this).GetComponent<BackpackSway>()?.EnsureBinding();
		_pending = false;
		RestoreSettings();
		Mesh shippedMesh = _shippedMesh;
		Renderer renderer = _renderer;
		SkinnedMeshRenderer val = (SkinnedMeshRenderer)(object)((renderer is SkinnedMeshRenderer) ? renderer : null);
		if (val != null)
		{
			val.sharedMesh = shippedMesh;
		}
		else
		{
			((Component)_renderer).GetComponent<MeshFilter>().sharedMesh = shippedMesh;
		}
		Material[] array = null;
		try
		{
			array = (Material[])(object)new Material[_legacyMaterials.Length];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = SingleSided(_legacyMaterials[i]);
			}
			_renderer.sharedMaterials = array;
			ReleaseInstanceMaterials();
			_instanceMaterials = array;
			array = null;
		}
		finally
		{
			if (array != null)
			{
				Material[] array2 = array;
				foreach (Material val2 in array2)
				{
					if ((Object)(object)val2 != (Object)null)
					{
						Object.Destroy((Object)(object)val2);
					}
				}
			}
		}
		_renderer.enabled = true;
		Refresh();
		_capeCloth?.RequestBuild();
	}

	private Material SingleSided(Material material)
	{
		return PieceMaterial(material);
	}

	internal static Material PieceMaterial(Material material)
	{
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		//IL_003b: Expected O, but got Unknown
		//IL_007a: Unknown result type (might be due to invalid IL or missing references)
		//IL_007f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0095: Unknown result type (might be due to invalid IL or missing references)
		//IL_009d: Expected O, but got Unknown
		//IL_0156: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e8: Expected I4, but got Unknown
		//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
		//IL_011c: Unknown result type (might be due to invalid IL or missing references)
		//IL_012a: Unknown result type (might be due to invalid IL or missing references)
		//IL_022f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0234: Unknown result type (might be due to invalid IL or missing references)
		//IL_0236: Unknown result type (might be due to invalid IL or missing references)
		//IL_0239: Invalid comparison between Unknown and I4
		//IL_023b: Unknown result type (might be due to invalid IL or missing references)
		//IL_023e: Invalid comparison between Unknown and I4
		//IL_0240: Unknown result type (might be due to invalid IL or missing references)
		//IL_0243: Invalid comparison between Unknown and I4
		//IL_0254: Unknown result type (might be due to invalid IL or missing references)
		//IL_0257: Invalid comparison between Unknown and I4
		//IL_0260: Unknown result type (might be due to invalid IL or missing references)
		//IL_0259: Unknown result type (might be due to invalid IL or missing references)
		//IL_026c: Unknown result type (might be due to invalid IL or missing references)
		//IL_026f: Invalid comparison between Unknown and I4
		if (((Object)material.shader).name == "Utgarde/FurCutout")
		{
			return new Material(material)
			{
				name = ((Object)material).name + "_SingleSided",
				enableInstancing = false
			};
		}
		Shader val = ((IEnumerable<Shader>)Resources.FindObjectsOfTypeAll<Shader>()).FirstOrDefault((Func<Shader, bool>)((Shader shader) => ((Object)shader).name == "Custom/Piece" && shader.isSupported));
		if ((Object)(object)val == (Object)null)
		{
			throw new InvalidOperationException("Vanilla backpack Custom/Piece shader is unavailable after spawn.");
		}
		Material val2 = new Material(val)
		{
			name = ((Object)material).name + "_SingleSided",
			enableInstancing = false
		};
		for (int num = 0; num < val.GetPropertyCount(); num++)
		{
			string propertyName = val.GetPropertyName(num);
			if (material.HasProperty(propertyName) && val2.HasProperty(propertyName))
			{
				ShaderPropertyType propertyType = val.GetPropertyType(num);
				switch ((int)propertyType)
				{
				case 0:
					val2.SetColor(propertyName, material.GetColor(propertyName));
					break;
				case 1:
					val2.SetVector(propertyName, material.GetVector(propertyName));
					break;
				case 4:
					val2.SetTexture(propertyName, material.GetTexture(propertyName));
					val2.SetTextureScale(propertyName, material.GetTextureScale(propertyName));
					val2.SetTextureOffset(propertyName, material.GetTextureOffset(propertyName));
					break;
				case 2:
				case 3:
					val2.SetFloat(propertyName, material.GetFloat(propertyName));
					break;
				}
			}
		}
		val2.globalIlluminationFlags = material.globalIlluminationFlags;
		val2.renderQueue = 2000;
		val2.SetOverrideTag("RenderType", "Opaque");
		if (val2.HasProperty("_Cull"))
		{
			val2.SetFloat("_Cull", 2f);
		}
		if (val2.HasProperty("_TwoSidedNormals"))
		{
			val2.SetFloat("_TwoSidedNormals", 0f);
		}
		if (val2.HasProperty("_Cutoff"))
		{
			val2.SetFloat("_Cutoff", 0f);
		}
		string[] array = val2.shaderKeywords.ToArray();
		foreach (string text in array)
		{
			if (DisplacementFeature(text))
			{
				val2.DisableKeyword(text);
			}
		}
		for (int num3 = 0; num3 < val.GetPropertyCount(); num3++)
		{
			string propertyName2 = val.GetPropertyName(num3);
			if (DisplacementFeature(propertyName2) && val2.HasProperty(propertyName2))
			{
				ShaderPropertyType propertyType2 = val.GetPropertyType(num3);
				if ((int)propertyType2 == 2 || (int)propertyType2 == 3 || (int)propertyType2 == 5)
				{
					val2.SetFloat(propertyName2, 0f);
				}
				else if ((int)propertyType2 == 1 || (int)propertyType2 == 0)
				{
					val2.SetVector(propertyName2, Vector4.zero);
				}
				else if ((int)propertyType2 == 4)
				{
					val2.SetTexture(propertyName2, (Texture)null);
				}
			}
		}
		return val2;
	}

	private static bool DisplacementFeature(string property)
	{
		return new string[8] { "wind", "vertex", "snow", "moss", "triplanar", "ripple", "valuenoise", "addrain" }.Any((string part) => property.IndexOf(part, StringComparison.OrdinalIgnoreCase) >= 0);
	}

	private void ReleaseInstanceMaterials()
	{
		if (_instanceMaterials != null)
		{
			Material[] instanceMaterials = _instanceMaterials;
			for (int i = 0; i < instanceMaterials.Length; i++)
			{
				Object.Destroy((Object)(object)instanceMaterials[i]);
			}
			_instanceMaterials = null;
		}
	}

	private static int[] CaptureSettings(Renderer renderer)
	{
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_0017: Expected I4, but got Unknown
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: Expected I4, but got Unknown
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Expected I4, but got Unknown
		//IL_0038: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Expected I4, but got Unknown
		//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
		SkinnedMeshRenderer val = (SkinnedMeshRenderer)(object)((renderer is SkinnedMeshRenderer) ? renderer : null);
		return new int[14]
		{
			(int)renderer.lightProbeUsage,
			(int)renderer.reflectionProbeUsage,
			(int)renderer.shadowCastingMode,
			renderer.receiveShadows ? 1 : 0,
			(int)renderer.motionVectorGenerationMode,
			((Object)(object)val != (Object)null && val.skinnedMotionVectors) ? 1 : 0,
			renderer.allowOcclusionWhenDynamic ? 1 : 0,
			(int)renderer.renderingLayerMask,
			renderer.sortingLayerID,
			renderer.sortingOrder,
			renderer.rendererPriority,
			((Component)renderer).gameObject.layer,
			((Object)(object)val != (Object)null) ? ((int)val.quality) : 0,
			((Object)(object)val != (Object)null && val.updateWhenOffscreen) ? 1 : 0
		};
	}

	private void RestoreSettings()
	{
		_renderer.lightProbeUsage = (LightProbeUsage)_settings[0];
		_renderer.reflectionProbeUsage = (ReflectionProbeUsage)_settings[1];
		_renderer.shadowCastingMode = (ShadowCastingMode)_settings[2];
		_renderer.receiveShadows = _settings[3] != 0;
		_renderer.motionVectorGenerationMode = (MotionVectorGenerationMode)_settings[4];
		_renderer.allowOcclusionWhenDynamic = _settings[6] != 0;
		_renderer.renderingLayerMask = (uint)_settings[7];
		_renderer.sortingLayerID = _settings[8];
		_renderer.sortingOrder = _settings[9];
		_renderer.rendererPriority = _settings[10];
		((Component)_renderer).gameObject.layer = _settings[11];
		_renderer.lightProbeProxyVolumeOverride = _proxyVolume;
		Renderer renderer = _renderer;
		SkinnedMeshRenderer val = (SkinnedMeshRenderer)(object)((renderer is SkinnedMeshRenderer) ? renderer : null);
		if (val != null)
		{
			val.skinnedMotionVectors = _settings[5] != 0;
			val.quality = (SkinQuality)_settings[12];
			val.updateWhenOffscreen = _settings[13] != 0;
		}
	}

	private void Refresh()
	{
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_010f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0115: Expected O, but got Unknown
		//IL_013e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0131: Unknown result type (might be due to invalid IL or missing references)
		//IL_0143: Unknown result type (might be due to invalid IL or missing references)
		//IL_014a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0151: Unknown result type (might be due to invalid IL or missing references)
		//IL_0156: Unknown result type (might be due to invalid IL or missing references)
		//IL_015b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0160: Unknown result type (might be due to invalid IL or missing references)
		//IL_0165: Unknown result type (might be due to invalid IL or missing references)
		//IL_016f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0206: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_019a: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ee: 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)
		_stateWrites++;
		Renderer renderer = _renderer;
		SkinnedMeshRenderer val = (SkinnedMeshRenderer)(object)((renderer is SkinnedMeshRenderer) ? renderer : null);
		if (val == null)
		{
			_renderer.probeAnchor = ((Component)this).transform;
			_renderer.localBounds = ((Component)_renderer).GetComponent<MeshFilter>().sharedMesh.bounds;
			return;
		}
		((Component)this).GetComponent<BackpackSway>()?.EnsureBinding();
		if (val.bones.Length != val.sharedMesh.bindposes.Length || val.bones.Any((Transform bone) => (Object)(object)bone == (Object)null))
		{
			throw new InvalidOperationException("Backpack skin is missing its canonical bones.");
		}
		if (!string.IsNullOrEmpty(_rootBoneName))
		{
			val.rootBone = val.bones.First((Transform bone) => ((Object)bone).name == _rootBoneName);
		}
		((Renderer)val).probeAnchor = val.bones.First((Transform bone) => ((Object)bone).name == "Spine2");
		val.updateWhenOffscreen = false;
		Mesh val2 = new Mesh();
		try
		{
			val.BakeMesh(val2, true);
			Matrix4x4 val3 = (((Object)(object)val.rootBone != (Object)null) ? val.rootBone.worldToLocalMatrix : ((Component)val).transform.worldToLocalMatrix);
			Bounds localBounds = BackpackMeshConversion.BoundsInSpace(val2.vertices, val3 * ((Component)val).transform.localToWorldMatrix);
			((Bounds)(ref localBounds)).Expand(((Bounds)(ref localBounds)).size * 0.05f);
			if (_motionPadding > 0f)
			{
				Vector3 val4 = (((Object)(object)val.rootBone != (Object)null) ? val.rootBone.lossyScale : ((Component)val).transform.lossyScale);
				((Bounds)(ref localBounds)).Expand(new Vector3(2f * _motionPadding / Mathf.Abs(val4.x), 2f * _motionPadding / Mathf.Abs(val4.y), 2f * _motionPadding / Mathf.Abs(val4.z)));
			}
			((Renderer)val).localBounds = localBounds;
		}
		finally
		{
			Object.DestroyImmediate((Object)(object)val2);
		}
	}
}
internal sealed class BackpackSpec
{
	internal string PrefabName;

	internal string NameToken;

	internal string DescriptionToken;

	internal string ConfigSection;

	internal BackpackBiomes Biome;

	internal int CarryBonus;

	internal Vector2[] SizeByQuality;

	internal DamageModPair[] DamageModifiers;

	internal Color Tint;

	internal string Station;

	internal int StationLevel;

	internal int MaxStationLevel;

	internal RecipeIngredient[] Recipe;

	internal RecipeIngredient[] Upgrade;

	internal RecipeIngredient[] Upgrader;

	internal DropTarget[] Drops;
}
internal static class Backpacks
{
	private const float WeightMultiplier = 0.5f;

	private const int ArmorPerLevel = 1;

	private const float SpeedMod = -0.15f;

	private const float MobDropChance = 0.002f;

	private const float BossDropChance = 0.08f;

	internal static readonly BackpackSpec Ashlands = new BackpackSpec
	{
		PrefabName = "BackpackAshlands",
		NameToken = "item_utgarde_backpack_ashlands",
		DescriptionToken = "item_utgarde_backpack_ashlands_description",
		ConfigSection = "Backpack: Ashlands Backpack",
		Biome = (BackpackBiomes)64,
		CarryBonus = 40,
		SizeByQuality = (Vector2[])(object)new Vector2[4]
		{
			new Vector2(6f, 4f),
			new Vector2(7f, 4f),
			new Vector2(8f, 4f),
			new Vector2(8f, 5f)
		},
		DamageModifiers = (DamageModPair[])(object)new DamageModPair[1]
		{
			new DamageModPair
			{
				m_type = (DamageType)32,
				m_modifier = (DamageModifier)1
			}
		},
		Tint = new Color(1f, 0.55f, 0.45f),
		Station = "blackforge",
		StationLevel = 3,
		MaxStationLevel = 4,
		Recipe = (RecipeIngredient[])(object)new RecipeIngredient[3]
		{
			new RecipeIngredient("CapeAsh", 1),
			new RecipeIngredient("AskHide", 5),
			new RecipeIngredient("FlametalNew", 10)
		},
		Upgrade = (RecipeIngredient[])(object)new RecipeIngredient[3]
		{
			new RecipeIngredient("AskHide", 4),
			new RecipeIngredient("FlametalNew", 2),
			new RecipeIngredient("CharredBone", 5)
		},
		Upgrader = (RecipeIngredient[])(object)new RecipeIngredient[1]
		{
			new RecipeIngredient("Upgrader6Armor", 1)
		},
		Drops = (DropTarget[])(object)new DropTarget[4]
		{
			new DropTarget("Charred_Melee", 0.002f, 1, (int?)null),
			new DropTarget("Charred_Archer", 0.002f, 1, (int?)null),
			new DropTarget("Charred_Mage", 0.002f, 1, (int?)null),
			new DropTarget("Fader", 0.08f, 1, (int?)null)
		}
	};

	internal static readonly BackpackSpec DeepNorth = new BackpackSpec
	{
		PrefabName = "BackpackDeepNorth",
		NameToken = "item_utgarde_backpack_deepnorth",
		DescriptionToken = "item_utgarde_backpack_deepnorth_description",
		ConfigSection = "Backpack: Deep North Backpack",
		Biome = (BackpackBiomes)128,
		CarryBonus = 50,
		SizeByQuality = (Vector2[])(object)new Vector2[4]
		{
			new Vector2(7f, 4f),
			new Vector2(8f, 4f),
			new Vector2(8f, 5f),
			new Vector2(8f, 6f)
		},
		DamageModifiers = (DamageModPair[])(object)new DamageModPair[1]
		{
			new DamageModPair
			{
				m_type = (DamageType)64,
				m_modifier = (DamageModifier)5
			}
		},
		Tint = new Color(0.6f, 0.8f, 1f),
		Station = "blackforge",
		StationLevel = 4,
		MaxStationLevel = 5,
		Recipe = (RecipeIngredient[])(object)new RecipeIngredient[3]
		{
			new RecipeIngredient("CapeDeepNorth", 1),
			new RecipeIngredient("MooseHide", 5),
			new RecipeIngredient("Gold", 10)
		},
		Upgrade = (RecipeIngredient[])(object)new RecipeIngredient[3]
		{
			new RecipeIngredient("MooseHide", 4),
			new RecipeIngredient("Gold", 2),
			new RecipeIngredient("SealHide", 5)
		},
		Upgrader = (RecipeIngredient[])(object)new RecipeIngredient[1]
		{
			new RecipeIngredient("Upgrader7Armor", 1)
		},
		Drops = (DropTarget[])(object)new DropTarget[4]
		{
			new DropTarget("JotunWarrior", 0.002f, 1, (int?)null),
			new DropTarget("JotunWarriorDualWield", 0.002f, 1, (int?)null),
			new DropTarget("JotunWitch", 0.002f, 1, (int?)null),
			new DropTarget("FrozenKing_p3", 0.08f, 1, (int?)null)
		}
	};

	internal static BackpackDefinition BuildDefinition(BackpackSpec spec, GameObject prefab)
	{
		//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_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0053: Unknown result type (might be due to invalid IL or missing references)
		//IL_0058: Unknown result type (might be due to invalid IL or missing references)
		//IL_0064: Unknown result type (might be due to invalid IL or missing references)
		//IL_006f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0076: Unknown result type (might be due to invalid IL or missing references)
		//IL_0081: Unknown result type (might be due to invalid IL or missing references)
		//IL_0088: Unknown result type (might be due to invalid IL or missing references)
		//IL_0094: Expected O, but got Unknown
		//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
		BackpackDefinition val = new BackpackDefinition(prefab)
		{
			ItemName = "$" + spec.NameToken,
			ConfigSection = spec.ConfigSection,
			CraftingTable = spec.Station,
			StationLevel = spec.StationLevel,
			MaxRequiredStationLevel = spec.MaxStationLevel,
			BackpackBiome = spec.Biome,
			CarryBonus = spec.CarryBonus,
			WeightMultiplier = 0.5f,
			ArmorPerLevel = 1,
			SpeedMod = -0.15f,
			ScaleSpeedModByQuality = true,
			BackpackSizeByQuality = new Dictionary<int, Vector2>()
		};
		for (int i = 0; i < spec.SizeByQuality.Length; i++)
		{
			val.BackpackSizeByQuality.Add(i + 1, spec.SizeByQuality[i]);
		}
		val.RecipeIngredients.AddRange(spec.Recipe);
		val.UpgradeIngredients.AddRange(spec.Upgrade);
		val.UpgraderIngredients.AddRange(spec.Upgrader);
		val.DropsFrom.AddRange(spec.Drops);
		return val;
	}
}
public sealed class BackpackSway : MonoBehaviour
{
	internal static bool EnableSway = true;

	internal const float LanternStiffness = 15f;

	internal const float ItemStiffness = 35f;

	internal const float LanternDamping = 3f;

	internal const float ItemDamping = 4.5f;

	internal const float LanternDrive = 2.4f;

	internal const float ItemDrive = 3.2f;

	[SerializeField]
	private SkinnedMeshRenderer _renderer;

	[SerializeField]
	private Transform[] _ownedBones;

	[SerializeField]
	private Vector3[] _restPositions;

	[SerializeField]
	private Quaternion[] _restRotations;

	[SerializeField]
	private Vector3[] _restScales;

	[SerializeField]
	private Vector3[] _hangingDirections;

	[SerializeField]
	private Vector3[] _lateralAxes;

	[SerializeField]
	private Vector3[] _outwardAxes;

	[SerializeField]
	private float[] _lengths;

	private Transform _spine;

	private bool _pending;

	private bool _sampleReady;

	private Quaternion _previousSpineRotation;

	private Vector3[] _previousPositions = (Vector3[])(object)new Vector3[2];

	private Vector3[] _previousVelocities = (Vector3[])(object)new Vector3[2];

	private Vector3[] _filteredAccelerations = (Vector3[])(object)new Vector3[2];

	private Vector2[] _angles = (Vector2[])(object)new Vector2[2];

	private Vector2[] _velocities = (Vector2[])(object)new Vector2[2];

	internal static void Configure(ConfigFile config)
	{
		EnableSway = config.Bind<bool>("Motion", "EnableSway", true, "Enable sway on hanging items. Takes effect after restart.").Value;
	}

	internal static string[] BoneNames(string biome)
	{
		if (biome == "Ashlands")
		{
			return new string[2] { "AshlandsLanternSway", "AshlandsBombSway" };
		}
		if (biome == "DeepNorth")
		{
			return new string[2] { "DeepNorthLanternSway", "DeepNorthChargeSway" };
		}
		throw new InvalidOperationException("Unknown sway biome: " + biome);
	}

	internal void Initialize(SkinnedMeshRenderer renderer, string biome)
	{
		//IL_0156: Unknown result type (might be due to invalid IL or missing references)
		//IL_017d: Unknown result type (might be due to invalid IL or missing references)
		//IL_018a: 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_01a1: 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_01ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_020e: Unknown result type (might be due to invalid IL or missing references)
		//IL_021b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0220: Unknown result type (might be due to invalid IL or missing references)
		//IL_0225: Unknown result type (might be due to invalid IL or missing references)
		//IL_022a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0266: Unknown result type (might be due to invalid IL or missing references)
		//IL_026b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0273: Unknown result type (might be due to invalid IL or missing references)
		//IL_0280: Unknown result type (might be due to invalid IL or missing references)
		//IL_0285: Unknown result type (might be due to invalid IL or missing references)
		//IL_028a: Unknown result type (might be due to invalid IL or missing references)
		//IL_029c: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_02db: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f7: Unknown result type (might be due to invalid IL or missing references)
		//IL_02fc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0301: Unknown result type (might be due to invalid IL or missing references)
		//IL_0305: Unknown result type (might be due to invalid IL or missing references)
		//IL_030a: Unknown result type (might be due to invalid IL or missing references)
		_renderer = renderer;
		Transform[] bones = renderer.bones;
		if (bones.Length != 55 || renderer.sharedMesh.bindposes.Length != 55)
		{
			throw new InvalidOperationException("Sway needs a 55-slot body.");
		}
		int num = Array.FindIndex(bones, (Transform bone) => (Object)(object)bone != (Object)null && ((Object)bone).name == "Spine2");
		Matrix4x4[] bindposes = renderer.sharedMesh.bindposes;
		_ownedBones = (Transform[])(object)new Transform[2];
		_restPositions = (Vector3[])(object)new Vector3[2];
		_restRotations = (Quaternion[])(object)new Quaternion[2];
		_restScales = (Vector3[])(object)new Vector3[2];
		_hangingDirections = (Vector3[])(object)new Vector3[2];
		_lateralAxes = (Vector3[])(object)new Vector3[2];
		_outwardAxes = (Vector3[])(object)new Vector3[2];
		_lengths = ((!(biome == "Ashlands")) ? new float[2] { 0.18f, 0.145f } : new float[2] { 0.20989175f, 0.09975549f });
		for (int num2 = 0; num2 < _lengths.Length; num2++)
		{
			_lengths[num2] *= 0.85f;
		}
		Vector3[] vertices = renderer.sharedMesh.vertices;
		BoneWeight[] boneWeights = renderer.sharedMesh.boneWeights;
		for (int num3 = 0; num3 < 2; num3++)
		{
			int num4 = 53 + num3;
			Transform transform = new GameObject(BoneNames(biome)[num3]).transform;
			transform.SetParent(((Component)this).transform, false);
			_ownedBones[num3] = transform;
			Matrix4x4 val = bindposes[num] * ((Matrix4x4)(ref bindposes[num4])).inverse;
			_restPositions[num3] = Vector4.op_Implicit(((Matrix4x4)(ref val)).GetColumn(3));
			_restRotations[num3] = ((Matrix4x4)(ref val)).rotation;
			_restScales[num3] = ((Matrix4x4)(ref val)).lossyScale;
			Vector3 val2 = Vector3.zero;
			int num5 = 0;
			for (int num6 = 0; num6 < vertices.Length; num6++)
			{
				if (((BoneWeight)(ref boneWeights[num6])).boneIndex0 == num4 && !(((BoneWeight)(ref boneWeights[num6])).weight0 < 0.999f))
				{
					val2 += ((Matrix4x4)(ref bindposes[num4])).MultiplyPoint3x4(vertices[num6]);
					num5++;
				}
			}
			if (num5 == 0 || ((Vector3)(ref val2)).sqrMagnitude < 1E-06f)
			{
				throw new InvalidOperationException("Sway item has no rigid moving vertices.");
			}
			_hangingDirections[num3] = ((Vector3)(ref val2)).normalized;
			Quaternion val3 = bones[num].rotation * _restRotations[num3];
			Vector3[] lateralAxes = _lateralAxes;
			int num7 = num3;
			Vector3 val4 = Vector3.Cross(_hangingDirections[num3], Quaternion.Inverse(val3) * ((Component)this).transform.right);
			lateralAxes[num7] = ((Vector3)(ref val4)).normalized;
			Vector3[] outwardAxes = _outwardAxes;
			int num8 = num3;
			val4 = Vector3.Cross(_hangingDirections[num3], Quaternion.Inverse(val3) * -((Component)this).transform.forward);
			outwardAxes[num8] = ((Vector3)(ref val4)).normalized;
		}
		Bind();
	}

	private void OnEnable()
	{
		_pending = true;
		ResetMotion();
	}

	private void OnDisable()
	{
		_pending = true;
		ResetMotion();
	}

	private void Update()
	{
		EnsureBinding();
	}

	internal void EnsureBinding()
	{
		if (!((Object)(object)_renderer == (Object)null) && _ownedBones != null)
		{
			Transform[] bones = _renderer.bones;
			if (_pending || bones.Length != 55 || (Object)(object)bones[53] != (Object)(object)_ownedBones[0] || (Object)(object)bones[54] != (Object)(object)_ownedBones[1] || (Object)(object)_spine == (Object)null || (Object)(object)bones.Take(53).FirstOrDefault((Func<Transform, bool>)((Transform bone) => (Object)(object)bone != (Object)null && ((Object)bone).name == "Spine2")) != (Object)(object)_spine || _ownedBones.Any((Transform bone) => (Object)(object)bone.parent != (Object)(object)_spine))
			{
				Bind();
			}
		}
	}

	private void Bind()
	{
		//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00de: Unknown result type (might be due to invalid IL or missing references)
		Transform[] bones = _renderer.bones;
		if ((bones.Length != 53 && bones.Length != 55) || bones.Take(53).Any((Transform bone) => (Object)(object)bone == (Object)null))
		{
			throw new InvalidOperationException("Sway attachment lost canonical bones.");
		}
		_spine = bones.Take(53).Single((Transform bone) => ((Object)bone).name == "Spine2");
		for (int num = 0; num < 2; num++)
		{
			_ownedBones[num].SetParent(_spine, false);
			_ownedBones[num].localPosition = _restPositions[num];
			_ownedBones[num].localRotation = _restRotations[num];
			_ownedBones[num].localScale = _restScales[num];
		}
		_renderer.bones = bones.Take(53).Concat(_ownedBones).ToArray();
		_pending = false;
		ResetMotion();
	}

	private void ResetMotion()
	{
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0076: Unknown result type (might be due to invalid IL or missing references)
		_sampleReady = false;
		for (int i = 0; i < 2; i++)
		{
			_angles[i] = Vector2.zero;
			_velocities[i] = Vector2.zero;
			_previousVelocities[i] = Vector3.zero;
			_filteredAccelerations[i] = Vector3.zero;
			if (_ownedBones != null && (Object)(object)_ownedBones[i] != (Object)null)
			{
				_ownedBones[i].localRotation = _restRotations[i];
			}
		}
	}

	private void LateUpdate()
	{
		if ((Object)(object)_spine != (Object)null && _ownedBones != null)
		{
			Step(Time.deltaTime);
		}
	}

	internal void Step(float deltaTime)
	{
		//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_0067: Unknown result type (might be due to invalid IL or missing references)
		//IL_0072: Unknown result type (might be due to invalid IL or missing references)
		//IL_00df: Unknown result type (might be due to invalid IL or missing references)
		//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fb: 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_010e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0113: Unknown result type (might be due to invalid IL or missing references)
		//IL_0118: 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_0125: Unknown result type (might be due to invalid IL or missing references)
		//IL_012a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0130: Unknown result type (might be due to invalid IL or missing references)
		//IL_0135: Unknown result type (might be due to invalid IL or missing references)
		//IL_013a: Unknown result type (might be due to invalid IL or missing references)
		//IL_014a: Unknown result type (might be due to invalid IL or missing references)
		//IL_014f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0156: Unknown result type (might be due to invalid IL or missing references)
		//IL_015c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0161: 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_0179: 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_0190: Unknown result type (might be due to invalid IL or missing references)
		//IL_0195: Unknown result type (might be due to invalid IL or missing references)
		//IL_0347: Unknown result type (might be due to invalid IL or missing references)
		//IL_034c: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_0238: Unknown result type (might be due to invalid IL or missing references)
		//IL_0241: Unknown result type (might be due to invalid IL or missing references)
		//IL_0269: Unknown result type (might be due to invalid IL or missing references)
		//IL_0272: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_02bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_02cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_0301: Unknown result type (might be due to invalid IL or missing references)
		//IL_0306: Unknown result type (might be due to invalid IL or missing references)
		//IL_030b: Unknown result type (might be due to invalid IL or missing references)
		//IL_031e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0323: Unknown result type (might be due to invalid IL or missing references)
		//IL_032f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0330: Unknown result type (might be due to invalid IL or missing references)
		if (!EnableSway || deltaTime <= 0f || deltaTime > 0.25f || float.IsNaN(deltaTime) || float.IsInfinity(deltaTime))
		{
			ResetMotion();
			return;
		}
		Vector3[] array = _ownedBones.Select((Transform bone) => bone.position).ToArray();
		if (!_sampleReady || Quaternion.Angle(_previousSpineRotation, _spine.rotation) > 90f || array.Where((Vector3 position, int index) => Vector3.Distance(position, _previousPositions[index]) > 2f).Any())
		{
			ResetMotion();
			_previousPositions = array;
			_previousSpineRotation = _spine.rotation;
			_sampleReady = true;
			return;
		}
		float num = 1f - Mathf.Exp((0f - deltaTime) / 0.08f);
		for (int num2 = 0; num2 < 2; num2++)
		{
			Vector3 val = (array[num2] - _previousPositions[num2]) / deltaTime;
			Vector3 val2 = Quaternion.Inverse(_spine.rotation * _restRotations[num2]) * ((val - _previousVelocities[num2]) / deltaTime);
			_filteredAccelerations[num2] = Vector3.Lerp(_filteredAccelerations[num2], Vector3.ClampMagnitude(val2, 12f), num);
			Vector3 val3 = Vector3.Cross(_hangingDirections[num2], -_filteredAccelerations[num2]) / _lengths[num2];
			float num3 = ((num2 == 0) ? 0.6f : 0.8f);
			float stiffness = ((num2 == 0) ? 15f : 35f);
			float damping = ((num2 == 0) ? 3f : 4.5f);
			val3 *= ((num2 == 0) ? 2.4f : 3.2f) * 0.85f;
			float angle = _angles[num2].x;
			float velocity = _velocities[num2].x;
			float angle2 = _angles[num2].y;
			float velocity2 = _velocities[num2].y;
			Spring(ref angle, ref velocity, Vector3.Dot(val3, _lateralAxes[num2]), stiffness, damping, deltaTime, -25f * num3, 25f * num3);
			Spring(ref angle2, ref velocity2, Vector3.Dot(val3, _outwardAxes[num2]), stiffness, damping, deltaTime, -3f * num3, 30f * num3);
			_angles[num2] = new Vector2(angle, angle2);
			_velocities[num2] = new Vector2(velocity, velocity2);
			_ownedBones[num2].localRotation = _restRotations[num2] * Quaternion.AngleAxis(angle * 57.29578f, _lateralAxes[num2]) * Quaternion.AngleAxis(angle2 * 57.29578f, _outwardAxes[num2]);
			_previousPositions[num2] = array[num2];
			_previousVelocities[num2] = val;
		}
		_previousSpineRotation = _spine.rotation;
	}

	internal static void Spring(ref float angle, ref float velocity, float drive, float stiffness, float damping, float deltaTime, float minimumDegrees, float maximumDegrees)
	{
		float num = drive / stiffness;
		float num2 = angle - num;
		float num3 = damping * 0.5f;
		float num4 = stiffness - num3 * num3;
		float num5 = velocity;
		if (Mathf.Abs(num4) < 0.0001f)
		{
			float num6 = Mathf.Exp((0f - num3) * deltaTime);
			float num7 = num5 + num3 * num2;
			angle = num + num6 * (num2 + num7 * deltaTime);
			velocity = num6 * (num5 - num3 * num7 * deltaTime);
		}
		else if (num4 > 0f)
		{
			float num8 = Mathf.Sqrt(num4);
			float num9 = Mathf.Exp((0f - num3) * deltaTime);
			float num10 = Mathf.Cos(num8 * deltaTime);
			float num11 = Mathf.Sin(num8 * deltaTime);
			angle = num + num9 * (num2 * num10 + (num5 + num3 * num2) / num8 * num11);
			velocity = num9 * (num5 * num10 - (num3 * num5 + stiffness * num2) / num8 * num11);
		}
		else
		{
			float num12 = Mathf.Sqrt(0f - num4);
			float num13 = 0f - num3 + num12;
			float num14 = 0f - num3 - num12;
			float num15 = (num5 - num14 * num2) / (num13 - num14) * Mathf.Exp(num13 * deltaTime);
			float num16 = (num13 * num2 - num5) / (num13 - num14) * Mathf.Exp(num14 * deltaTime);
			angle = num + num15 + num16;
			velocity = num13 * num15 + num14 * num16;
		}
		float num17 = Mathf.Clamp(angle, minimumDegrees * ((float)Math.PI / 180f), maximumDegrees * ((float)Math.PI / 180f));
		if (num17 != angle)
		{
			if (Mathf.Sign(velocity) == Mathf.Sign(angle - num17))
			{
				velocity = 0f;
			}
			angle = num17;
		}
		if (Mathf.Abs(angle) < 0.0017453292f && Mathf.Abs(velocity) < (float)Math.PI / 360f)
		{
			angle = 0f;
			velocity = 0f;
		}
	}

	private void OnDestroy()
	{
		if (_ownedBones == null)
		{
			return;
		}
		Transform[] ownedBones = _ownedBones;
		foreach (Transform val in ownedBones)
		{
			if ((Object)(object)val != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)val).gameObject);
			}
		}
	}
}
internal sealed class BackpackVisuals
{
	internal const string BundleResource = "UtgardeBackpacks.Assets.utgarde_backpacks";

	private readonly ManualLogSource _logger;

	private AssetBundle _bundle;

	private Dictionary<string, Material> _materialTemplates;

	private Shader _textureShader;

	private AssetBundle _plainsBundle;

	internal BackpackVisuals(ManualLogSource logger)
	{
		_logger = logger;
		BackpackRenderer.SetLogger(logger);
		BackpackCapeCloth.SetLogger(logger);
	}

	internal bool Apply(GameObject clone, string biome)
	{
		//IL_0283: Unknown result type (might be due to invalid IL or missing references)
		//IL_0288: Unknown result type (might be due to invalid IL or missing references)
		//IL_034d: Unknown result type (might be due to invalid IL or missing references)
		//IL_03c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_03cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0420: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			if (biome != "Ashlands" && biome != "DeepNorth")
			{
				throw new InvalidOperationException("Unsupported backpack biome: " + biome);
			}
			Transform val = RequireChild(clone, "attach_skin");
			Transform val2 = RequireChild(clone, "log");
			Transform obj = LoadVisual("Utgarde" + biome + "Worn", "attach_skin");
			Transform val3 = LoadVisual("Utgarde" + biome + "Log", "log");
			Renderer[] componentsInChildren = ((Component)val).GetComponentsInChildren<Renderer>(true);
			Renderer[] componentsInChildren2 = ((Component)val2).GetComponentsInChildren<Renderer>(true);
			SkinnedMeshRenderer sourceSkin = componentsInChildren.OfType<SkinnedMeshRenderer>().FirstOrDefault();
			if ((Object)(object)sourceSkin == (Object)null || sourceSkin.bones.Length == 0)
			{
				throw new InvalidOperationException("Mistlands has no skinned renderer with bones.");
			}
			if (componentsInChildren.OfType<SkinnedMeshRenderer>().Any((SkinnedMeshRenderer renderer) => !renderer.bones.Select((Transform bone) => ((Object)bone).name).SequenceEqual(sourceSkin.bones.Select((Transform bone) => ((Object)bone).name))))
			{
				throw new InvalidOperationException("Mistlands renderers use different bone orders.");
			}
			MeshRenderer sourceLog = componentsInChildren2.OfType<MeshRenderer>().FirstOrDefault((Func<MeshRenderer, bool>)((MeshRenderer renderer) => ((Renderer)renderer).enabled));
			if ((Object)(object)sourceLog == (Object)null)
			{
				throw new InvalidOperationException("Mistlands has no dropped mesh renderer.");
			}
			Material source = RequireMaterial(componentsInChildren);
			Material source2 = RequireMaterial(componentsInChildren2);
			GameObject val4 = Object.Instantiate<GameObject>(((Component)obj).gameObject, val, false);
			GameObject val5 = Object.Instantiate<GameObject>(((Component)val3).gameObject, val2, false);
			((Object)val4).name = "Utgarde" + biome + "Worn";
			((Object)val5).name = "Utgarde" + biome + "Log";
			Renderer[] componentsInChildren3 = val4.GetComponentsInChildren<Renderer>(true);
			Renderer[] componentsInChildren4 = val5.GetComponentsInChildren<Renderer>(true);
			SkinnedMeshRenderer[] array = componentsInChildren3.OfType<SkinnedMeshRenderer>().ToArray();
			int num = ((!(biome == "DeepNorth")) ? 1 : 2);
			if (array.Length != num || componentsInChildren3.Length != num || componentsInChildren4.Length != 1 || !(componentsInChildren4[0] is MeshRenderer))
			{
				throw new InvalidOperationException("Bundle has unexpected visual renderers.");
			}
			SkinnedMeshRenderer val6 = array.Single((SkinnedMeshRenderer renderer) => ((Object)renderer).name == biome.ToLowerInvariant() + "_backpack");
			SkinnedMeshRenderer val7 = ((biome == "DeepNorth") ? array.Single((SkinnedMeshRenderer renderer) => ((Object)renderer).name == "deepnorth_cape") : null);
			Matrix4x4 localToWorldMatrix = val.localToWorldMatrix;
			RemapBones(val6, sourceSkin, biome, sway: true);
			if ((Object)(object)val7 != (Object)null)
			{
				RemapBones(val7, sourceSkin, biome, sway: false);
			}
			LoadTextures();
			Shader textureShader = _textureShader;
			if (((Object)textureShader).name != "Standard" || !textureShader.isSupported)
			{
				throw new InvalidOperationException("No supported Mistlands Standard shader is available.");
			}
			Material[] legacyMaterials = ReplaceMaterials((IEnumerable<Renderer>)(object)new Renderer[1] { (Renderer)val6 }, source, textureShader, "attach_skin", biome);
			Material[] legacyMaterials2 = ReplaceMaterials(componentsInChildren4, source2, textureShader, "log", biome);
			BackpackRenderer backpackRenderer = ((Component)val).gameObject.AddComponent<BackpackRenderer>();
			backpackRenderer.Initialize((Renderer)(object)sourceSkin, (Renderer)(object)val6, biome, legacyMaterials, textureShader, null, localToWorldMatrix);
			((Component)val).gameObject.AddComponent<BackpackSway>().Initialize(sourceSkin, biome);
			backpackRenderer.SetMotionPadding(0.15f);
			List<Renderer> list = new List<Renderer> { (Renderer)(object)sourceSkin };
			if ((Object)(object)val7 != (Object)null)
			{
				Material[] legacyMaterials3 = ReplaceMaterials((IEnumerable<Renderer>)(object)new Renderer[1] { (Renderer)val7 }, source, textureShader, "cape", biome);
				GameObject val8 = new GameObject("deepnorth_cape");
				val8.transform.SetParent(((Component)sourceSkin).transform.parent, false);
				SkinnedMeshRenderer val9 = val8.AddComponent<SkinnedMeshRenderer>();
				val9.rootBone = sourceSkin.rootBone;
				BackpackRenderer backpackRenderer2 = ((Component)val).gameObject.AddComponent<BackpackRenderer>();
				backpackRenderer2.Initialize((Renderer)(object)val9, (Renderer)(object)val7, biome, legacyMaterials3, textureShader, (Renderer)(object)sourceSkin, localToWorldMatrix);
				backpackRenderer2.SetMotionPadding(0.4f);
				BackpackCapeCloth backpackCapeCloth = ((Component)val).gameObject.AddComponent<BackpackCapeCloth>();
				backpackCapeCloth.Initialize(val9, sourceSkin);
				backpackRenderer2.SetCapeCloth(backpackCapeCloth);
				list.Add((Renderer)(object)val9);
			}
			((Component)val2).gameObject.AddComponent<BackpackRenderer>().Initialize((Renderer)(object)sourceLog, componentsInChildren4[0], biome, legacyMaterials2, textureShader);
			BackpackRenderer[] componentsInChildren5 = clone.GetComponentsInChildren<BackpackRenderer>(true);
			for (int num2 = 0; num2 < componentsInChildren5.Length; num2++)
			{
				componentsInChildren5[num2].ScaleAttachment();
			}
			ReplaceLodReferences(clone, componentsInChildren, componentsInChildren2, list.ToArray(), (Renderer[])(object)new Renderer[1] { (Renderer)sourceLog });
			RemoveVisualComponents(componentsInChildren.Where((Renderer renderer) => (Object)(object)renderer != (Object)(object)sourceSkin).ToArray());
			RemoveVisualComponents(componentsInChildren2.Where((Renderer renderer) => (Object)(object)renderer != (Object)(object)sourceLog).ToArray());
			Object.DestroyImmediate((Object)(object)val4);
			Object.DestroyImmediate((Object)(object)val5);
			_logger.LogInfo((object)$"Replaced {biome} worn and dropped visuals; kept {clone.GetComponentsInChildren<Collider>(true).Length} colliders.");
			return true;
		}
		catch (Exception arg)
		{
			_logger.LogError((object)$"{biome} visual replacement failed: {arg}");
			return false;
		}
	}

	private Transform LoadVisual(string prefabName, string childName)
	{
		if ((Object)(object)_bundle == (Object)null)
		{
			using (Stream stream = typeof(BackpackVisuals).Assembly.GetManifestResourceStream("UtgardeBackpacks.Assets.utgarde_backpacks"))
			{
				if (stream == null)
				{
					throw new InvalidOperationException("Missing embedded bundle: UtgardeBackpacks.Assets.utgarde_backpacks");
				}
				using MemoryStream memoryStream = new MemoryStream();
				stream.CopyTo(memoryStream);
				_bundle = AssetBundle.LoadFromMemory(memoryStream.ToArray());
			}
			if ((Object)(object)_bundle == (Object)null)
			{
				throw new InvalidOperationException("Could not load embedded backpack bundle.");
			}
			_logger.LogInfo((object)"Loaded embedded asset bundle utgarde_backpacks.");
		}
		return RequireChild(_bundle.LoadAsset<GameObject>(prefabName), childName);
	}

	private void LoadTextures()
	{
		if (_materialTemplates != null)
		{
			return;
		}
		AssetBundle val;
		using (Stream stream = typeof(BackpackVisuals).Assembly.GetManifestResourceStream("UtgardeBackpacks.Assets.utgarde_textures"))
		{
			using MemoryStream memoryStream = new MemoryStream();
			if (stream == null)
			{
				throw new InvalidOperationException("Missing embedded texture bundle: UtgardeBackpacks.Assets.utgarde_textures");
			}
			stream.CopyTo(memoryStream);
			val = AssetBundle.LoadFromMemory(memoryStream.ToArray());
		}
		if ((Object)(object)val == (Object)null)
		{
			throw new InvalidOperationException("Could not load reworked texture bundle.");
		}
		try
		{
			Material[] array = (from material in val.LoadAllAssets<Material>()
				where !((Object)material).name.StartsWith("VariantControl")
				select material).ToArray();
			if (array.Length == 0 || array.Any((Material material) => (Object)(object)material.shader == (Object)null || (((Object)material.shader).name != "Standard" && ((Object)material.shader).name != "Utgarde/FurCutout") || !material.shader.isSupported || !material.HasProperty("_MainTex") || (Object)(object)material.GetTexture("_MainTex") == (Object)null))
			{
				throw new InvalidOperationException("Reworked material templates are incomplete.");
			}
			_materialTemplates = array.ToDictionary<Material, string>((Material material) => ((Object)material).name, StringComparer.Ordinal);
			_textureShader = array.First((Material material) => ((Object)material.shader).name == "Standard").shader;
			val.Unload(false);
		}
		catch
		{
			val.Unload(true);
			throw;
		}
	}

	private static Transform RequireChild(GameObject root, string name)
	{
		Transform obj = (((Object)(object)root != (Object)null) ? root.transform.Find(name) : null);
		if ((Object)(object)obj == (Object)null)
		{
			throw new InvalidOperationException("Prefab is missing " + name