Decompiled source of Drifter Skin Pack v0.1.0

BepInEx/plugins/DrifterHappyCamper/Eclipse.Drifter.E1.HappyCamper.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security.Cryptography;
using System.Text;
using BepInEx;
using EntityStates;
using EntityStates.Drifter;
using HG.Reflection;
using On.EntityStates.Drifter;
using R2API;
using R2API.Utils;
using RoR2;
using RoR2.UI.MainMenu;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Rendering;
using UnityEngine.ResourceManagement.AsyncOperations;

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

[BepInPlugin("eclipseplaytest.drifter.e1", "Drifter - Happy Camper (Playtest)", "0.1.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public sealed class HappyCamper : BaseUnityPlugin
{
	[Serializable]
	public class FileEntry
	{
		public string file;

		public string sha256;

		public int fileBytes;
	}

	[Serializable]
	public class Part : FileEntry
	{
		public string id;

		public string texture;

		public bool isBag;

		public int vertices;

		public int triangles;
	}

	[Serializable]
	public class Motion
	{
		public string id;

		public float[] anchor;

		public float[] center;

		public float[] normal;

		public float[] weights;

		public int[] slots;

		public float damping;

		public float stiffness;

		public float maxAngleDegrees;
	}

	[Serializable]
	public class Manifest
	{
		public int schema;

		public string skinId;

		public string revision;

		public string sourceGLBSha256;

		public string[] boneNames;

		public string[] bonePaths;

		public Part[] parts;

		public FileEntry[] textures;

		public Motion[] motion;
	}

	public const string Guid = "eclipseplaytest.drifter.e1";

	public const string Version = "0.1.0";

	public const string SkinId = "EclipsePlaytestDrifterE1HappyCamper";

	public static HappyCamper Instance;

	internal Manifest Data;

	internal SkinDef Skin;

	internal readonly Dictionary<string, Mesh> Meshes = new Dictionary<string, Mesh>();

	internal Material Fur;

	internal Material Gear;

	internal Matrix4x4[] BodyBinds;

	internal Matrix4x4[] BagBinds;

	internal bool Ready;

	private string folder;

	private float deadline;

	private GameObject model;

	private GameObject display;

	private readonly List<AsyncOperationHandle> assets = new List<AsyncOperationHandle>();

	private void Awake()
	{
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0077: Expected O, but got Unknown
		Instance = this;
		folder = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
		SystemInitializerInjector.InjectDependency(typeof(SkinCatalog), typeof(HappyCamper));
		RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(SyncDisplay));
		MainMenuController.OnMainMenuInitialised += SyncDisplay;
		DeathState.OnEnter += new hook_OnEnter(Death);
	}

	[SystemInitializer(new Type[]
	{
		typeof(BodyCatalog),
		typeof(SurvivorCatalog)
	})]
	private static IEnumerator Init()
	{
		if (!Object.op_Implicit((Object)(object)Instance))
		{
			yield break;
		}
		Instance.deadline = Time.realtimeSinceStartup + 60f;
		IEnumerator r = Instance.Register();
		try
		{
			while (true)
			{
				bool flag;
				try
				{
					flag = r.MoveNext();
				}
				catch (Exception ex)
				{
					((BaseUnityPlugin)Instance).Logger.LogError((object)("DRIFTER_E1_REGISTRATION_FAILED " + ex));
					break;
				}
				if (flag)
				{
					yield return r.Current;
					continue;
				}
				break;
			}
		}
		finally
		{
			IDisposable disposable = r as IDisposable;
			if (disposable != null)
			{
				disposable.Dispose();
			}
		}
	}

	private void Check()
	{
		if (Time.realtimeSinceStartup > deadline)
		{
			throw new TimeoutException("Happy Camper asset loading timed out");
		}
	}

	internal static SkinnedMeshRenderer Exact(GameObject m, string path)
	{
		Transform val = m.transform.Find(path);
		if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)((Component)val).GetComponent<SkinnedMeshRenderer>()))
		{
			throw new InvalidOperationException("Missing native Drifter renderer " + path);
		}
		return ((Component)val).GetComponent<SkinnedMeshRenderer>();
	}

	internal static string Relative(Transform root, Transform child)
	{
		if (!Object.op_Implicit((Object)(object)child) || !child.IsChildOf(root))
		{
			throw new InvalidDataException("Bone outside actor");
		}
		List<string> list = new List<string>();
		while ((Object)(object)child != (Object)(object)root)
		{
			list.Insert(0, ((Object)child).name);
			child = child.parent;
		}
		return string.Join("/", list);
	}

	internal void Validate(GameObject m, SkinnedMeshRenderer r)
	{
		if (r.bones.Length != 120)
		{
			throw new InvalidDataException("Drifter needs 120 native bones");
		}
		for (int i = 0; i < 120; i++)
		{
			if (!Object.op_Implicit((Object)(object)r.bones[i]) || ((Object)r.bones[i]).name != Data.boneNames[i] || Relative(m.transform, r.bones[i]) != Data.bonePaths[i])
			{
				throw new InvalidDataException("Native Drifter bone contract changed at " + i);
			}
		}
	}

	private byte[] Read(FileEntry e)
	{
		if (e == null || string.IsNullOrEmpty(e.file) || Path.GetFileName(e.file) != e.file || e.file.Contains("..") || e.sha256 == null || e.sha256.Length != 64 || e.fileBytes < 1 || e.fileBytes > 67108864)
		{
			throw new InvalidDataException("Invalid camper asset entry");
		}
		string text = Path.Combine(folder, e.file);
		if (new FileInfo(text).Length != e.fileBytes)
		{
			throw new InvalidDataException("Asset length mismatch " + e.file);
		}
		byte[] array = File.ReadAllBytes(text);
		using SHA256 sHA = SHA256.Create();
		if (BitConverter.ToString(sHA.ComputeHash(array)).Replace("-", "").ToLowerInvariant() != e.sha256)
		{
			throw new InvalidDataException("Asset hash mismatch " + e.file);
		}
		return array;
	}

	private Texture2D Texture(string file)
	{
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: Expected O, but got Unknown
		//IL_0071: Expected O, but got Unknown
		FileEntry e = Data.textures.Single((FileEntry t) => t.file == file);
		Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false, false)
		{
			name = file,
			filterMode = (FilterMode)1,
			wrapMode = (TextureWrapMode)1,
			anisoLevel = 4
		};
		if (!ImageConversion.LoadImage(val, Read(e), false))
		{
			throw new InvalidDataException("Texture decode failed");
		}
		return val;
	}

	private Material Material(Material source, Texture2D texture, bool fur)
	{
		//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: Expected O, but got Unknown
		//IL_004c: 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)
		Material val = new Material(source)
		{
			name = (fur ? "HappyCamperFur" : "HappyCamperEquipment")
		};
		val.SetTexture("_MainTex", (Texture)(object)texture);
		val.SetColor("_Color", (Color)(fur ? new Color(0.66f, 0.87f, 1f, 1f) : Color.white));
		val.SetFloat("_NormalStrength", 0f);
		val.SetFloat("_Smoothness", fur ? 0.06f : 0.18f);
		val.SetFloat("_SpecularStrength", fur ? 0.06f : 0.2f);
		val.SetFloat("_SpecularExponent", 8f);
		val.SetFloat("_EmPower", 0f);
		val.SetTexture("_EmTex", (Texture)(object)Texture2D.blackTexture);
		string[] array = new string[3] { "FLOWMAP", "FORCE_SPEC", "LIMBREMOVAL" };
		foreach (string text in array)
		{
			val.DisableKeyword(text);
		}
		val.SetFloat("_FlowmapOn", 0f);
		val.SetFloat("_ForceSpecOn", 0f);
		val.SetFloat("_LimbRemovalOn", 0f);
		return val;
	}

	private IEnumerator Register()
	{
		string text = Path.Combine(folder, "camper-assets.json");
		if (new FileInfo(text).Length > 1048576)
		{
			throw new InvalidDataException("Manifest too large");
		}
		Data = JsonUtility.FromJson<Manifest>(File.ReadAllText(text));
		if (Data == null || Data.schema != 1 || Data.skinId != "EclipsePlaytestDrifterE1HappyCamper" || Data.boneNames == null || Data.boneNames.Length != 120 || Data.bonePaths == null || Data.bonePaths.Length != 120 || Data.parts == null || Data.parts.Length != 23 || Data.motion == null || Data.motion.Length != 19)
		{
			throw new InvalidDataException("Invalid camper manifest");
		}
		if (Data.parts.Select((Part p) => p.id).Distinct().Count() != Data.parts.Length)
		{
			throw new InvalidDataException("Duplicate part ID");
		}
		GameObject body = BodyCatalog.FindBodyPrefab("DrifterBody");
		if (!Object.op_Implicit((Object)(object)body))
		{
			throw new InvalidOperationException("DrifterBody missing");
		}
		model = ((Component)body.GetComponent<ModelLocator>().modelTransform).gameObject;
		ModelSkinController ctrl = model.GetComponent<ModelSkinController>();
		if (!Object.op_Implicit((Object)(object)ctrl) || ctrl.skins.Length == 0)
		{
			throw new InvalidOperationException("Drifter skins missing");
		}
		if (ctrl.skins.Any((SkinDef val8) => Object.op_Implicit((Object)(object)val8) && ((Object)val8).name == "EclipsePlaytestDrifterE1HappyCamper"))
		{
			yield break;
		}
		SurvivorDef val = SurvivorCatalog.allSurvivorDefs.Single((SurvivorDef val8) => Object.op_Implicit((Object)(object)val8) && (Object)(object)val8.bodyPrefab == (Object)(object)body);
		if (!Object.op_Implicit((Object)(object)val.displayPrefab))
		{
			throw new InvalidOperationException("Drifter display missing");
		}
		display = ((Component)val.displayPrefab.GetComponentInChildren<CharacterModel>(true)).gameObject;
		SkinDef baseSkin = ctrl.skins[0];
		SkinDefParams bp = baseSkin.skinDefParams;
		if (!Object.op_Implicit((Object)(object)bp) && baseSkin.skinDefParamsAddress != null && ((AssetReference)baseSkin.skinDefParamsAddress).RuntimeKeyIsValid())
		{
			AsyncOperationHandle<SkinDefParams> h = Addressables.LoadAssetAsync<SkinDefParams>(((AssetReference)baseSkin.skinDefParamsAddress).RuntimeKey);
			assets.Add(AsyncOperationHandle<SkinDefParams>.op_Implicit(h));
			while (!h.IsDone)
			{
				Check();
				yield return null;
			}
			bp = h.Result;
		}
		if (!Object.op_Implicit((Object)(object)bp))
		{
			throw new InvalidOperationException("Default Drifter skin parameters unavailable");
		}
		List<RendererInfo> infos = new List<RendererInfo>();
		List<MeshReplacement> replacements = new List<MeshReplacement>();
		string[] array = new string[2] { "body", "bag" };
		foreach (string id in array)
		{
			SkinnedMeshRenderer r = Exact(model, (id == "body") ? "meshDrifter" : "meshBag");
			Validate(model, r);
			Validate(display, Exact(display, (id == "body") ? "meshDrifter" : "meshBag"));
			Mesh reference = r.sharedMesh;
			if (!Object.op_Implicit((Object)(object)reference))
			{
				MeshReplacement val2 = bp.meshReplacements.Single((MeshReplacement p) => (Object)(object)p.renderer == (Object)(object)r);
				reference = val2.mesh;
				if (!Object.op_Implicit((Object)(object)reference) && val2.meshAddress != null && ((AssetReference)val2.meshAddress).RuntimeKeyIsValid())
				{
					AsyncOperationHandle<Mesh> h2 = Addressables.LoadAssetAsync<Mesh>(((AssetReference)val2.meshAddress).RuntimeKey);
					assets.Add(AsyncOperationHandle<Mesh>.op_Implicit(h2));
					while (!h2.IsDone)
					{
						Check();
						yield return null;
					}
					reference = h2.Result;
				}
			}
			if (!Object.op_Implicit((Object)(object)reference) || reference.bindposes.Length != 120)
			{
				throw new InvalidDataException("Missing native binds " + id);
			}
			if (id == "body")
			{
				BodyBinds = reference.bindposes;
			}
			else
			{
				BagBinds = reference.bindposes;
			}
			RendererInfo info = bp.rendererInfos.Single((RendererInfo i) => (Object)(object)i.renderer == (Object)(object)r);
			Material val3 = info.defaultMaterial;
			if (!Object.op_Implicit((Object)(object)val3) && info.defaultMaterialAddress != null && ((AssetReference)info.defaultMaterialAddress).RuntimeKeyIsValid())
			{
				AsyncOperationHandle<Material> h3 = Addressables.LoadAssetAsync<Material>(((AssetReference)info.defaultMaterialAddress).RuntimeKey);
				assets.Add(AsyncOperationHandle<Material>.op_Implicit(h3));
				while (!h3.IsDone)
				{
					Check();
					yield return null;
				}
				val3 = h3.Result;
			}
			if (!Object.op_Implicit((Object)(object)val3))
			{
				val3 = ((Renderer)r).sharedMaterial;
			}
			if (!Object.op_Implicit((Object)(object)val3) || !Object.op_Implicit((Object)(object)val3.shader))
			{
				throw new InvalidDataException("Native material unavailable");
			}
			Material val4 = Material(val3, Texture((id == "body") ? "camper-fur.png" : "camper-gear.png"), id == "body");
			if (id == "body")
			{
				Fur = val4;
			}
			else
			{
				Gear = val4;
			}
			Part part = Data.parts.Single((Part p) => p.id == id);
			Mesh val5 = CamperPayload.Read(Read(part), Data.boneNames, reference.bindposes, part.isBag);
			((Object)val5).name = "HappyCamper_" + id;
			Meshes.Add(id, val5);
			info.defaultMaterial = val4;
			info.defaultMaterialAddress = new AssetReferenceT<Material>("");
			infos.Add(info);
			replacements.Add(new MeshReplacement
			{
				renderer = (Renderer)(object)r,
				mesh = val5,
				meshAddress = new AssetReferenceT<Mesh>("")
			});
		}
		foreach (Part item in Data.parts.Where((Part p) => p.id != "body" && p.id != "bag"))
		{
			Mesh val6 = CamperPayload.Read(Read(item), Data.boneNames, item.isBag ? BagBinds : BodyBinds, item.isBag);
			((Object)val6).name = "HappyCamper_" + item.id;
			Meshes.Add(item.id, val6);
		}
		if (Data.motion.Select((Motion motion2) => motion2.id).Distinct().Count() != 19)
		{
			throw new InvalidDataException("Duplicate motion ID");
		}
		Motion[] motion = Data.motion;
		foreach (Motion s in motion)
		{
			if (!Data.parts.Any((Part p) => p.id == s.id) || new string[4] { "body", "bag", "body-gear", "death-bag" }.Contains(s.id))
			{
				throw new InvalidDataException("Unknown dynamic part");
			}
			CamperPresentation.ValidateMotion(s);
		}
		SkinDefParams val7 = ScriptableObject.CreateInstance<SkinDefParams>();
		val7.rendererInfos = infos.ToArray();
		val7.meshReplacements = replacements.ToArray();
		Skin = ScriptableObject.CreateInstance<SkinDef>();
		((Object)Skin).name = "EclipsePlaytestDrifterE1HappyCamper";
		Skin.nameToken = "ECLIPSE_PLAYTEST_DRIFTER_E1_HAPPY_CAMPER";
		LanguageAPI.Add(Skin.nameToken, "Happy Camper (Playtest)");
		Skin.rootObject = model;
		Skin.baseSkins = (SkinDef[])(object)new SkinDef[1] { baseSkin };
		Skin.skinDefParams = val7;
		Skin.unlockableDef = null;
		Skin.icon = baseSkin.icon;
		Prepare(model);
		Prepare(display);
		ctrl.skins = ctrl.skins.Concat((IEnumerable<SkinDef>)(object)new SkinDef[1] { Skin }).ToArray();
		Ready = true;
		SyncDisplay();
		((BaseUnityPlugin)this).Logger.LogInfo((object)("DRIFTER_E1_REGISTERED " + Data.revision + "; native animator/120 bones/Cleanup unchanged; gameplay untested"));
	}

	private void Prepare(GameObject root)
	{
		(root.GetComponent<CamperPresentation>() ?? root.AddComponent<CamperPresentation>()).Configure(Exact(root, "meshDrifter"), Exact(root, "meshBag"));
	}

	private void SyncDisplay()
	{
		if (Ready && Object.op_Implicit((Object)(object)model) && Object.op_Implicit((Object)(object)display))
		{
			(display.GetComponent<ModelSkinController>() ?? display.AddComponent<ModelSkinController>()).skins = (SkinDef[])model.GetComponent<ModelSkinController>().skins.Clone();
		}
	}

	private void Death(orig_OnEnter orig, DeathState self)
	{
		ModelLocator val = (Object.op_Implicit((Object)(object)((EntityState)self).outer) ? ((Component)((EntityState)self).outer).GetComponent<ModelLocator>() : null);
		Transform val2 = (Object.op_Implicit((Object)(object)val) ? val.modelTransform : null);
		CamperPresentation camperPresentation = (Object.op_Implicit((Object)(object)val2) ? ((Component)val2).GetComponent<CamperPresentation>() : null);
		Mesh previous = null;
		if (Object.op_Implicit((Object)(object)camperPresentation))
		{
			previous = camperPresentation.BeginDeath();
		}
		try
		{
			orig.Invoke(self);
		}
		finally
		{
			if (Object.op_Implicit((Object)(object)camperPresentation))
			{
				camperPresentation.EndDeath(previous);
			}
		}
	}

	private void OnDestroy()
	{
		//IL_0038: Unknown result type (might be due to invalid IL or missing references)
		//IL_0042: Expected O, but got Unknown
		RoR2Application.onLoad = (Action)Delegate.Remove(RoR2Application.onLoad, new Action(SyncDisplay));
		MainMenuController.OnMainMenuInitialised -= SyncDisplay;
		DeathState.OnEnter -= new hook_OnEnter(Death);
		if ((Object)(object)Instance == (Object)(object)this)
		{
			Instance = null;
		}
	}
}
internal static class CamperPayload
{
	internal static bool Finite(float f)
	{
		return CamperMeshData.Finite(f);
	}

	internal static Mesh Read(byte[] bytes, string[] names, Matrix4x4[] binds, bool bag)
	{
		//IL_0079: Unknown result type (might be due to invalid IL or missing references)
		//IL_007e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00db: 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_016f: 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_0187: Unknown result type (might be due to invalid IL or missing references)
		//IL_0199: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a0: 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_01af: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01da: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e1: Expected O, but got Unknown
		if (binds == null || binds.Length != 120)
		{
			throw new InvalidDataException("Native bind count");
		}
		CamperMeshData camperMeshData = CamperMeshData.Read(bytes, names, bag);
		int vertexCount = camperMeshData.VertexCount;
		Vector3[] array = (Vector3[])(object)new Vector3[vertexCount];
		Vector3[] array2 = (Vector3[])(object)new Vector3[vertexCount];
		Vector2[] array3 = (Vector2[])(object)new Vector2[vertexCount];
		BoneWeight[] array4 = (BoneWeight[])(object)new BoneWeight[vertexCount];
		for (int i = 0; i < vertexCount; i++)
		{
			int num = i * 8;
			int num2 = i * 4;
			array[i] = new Vector3(camperMeshData.Values[num], camperMeshData.Values[num + 1], camperMeshData.Values[num + 2]);
			array2[i] = new Vector3(camperMeshData.Values[num + 3], camperMeshData.Values[num + 4], camperMeshData.Values[num + 5]);
			array3[i] = new Vector2(camperMeshData.Values[num + 6], camperMeshData.Values[num + 7]);
			int num3 = i;
			BoneWeight val = default(BoneWeight);
			((BoneWeight)(ref val)).boneIndex0 = camperMeshData.Bones[num2];
			((BoneWeight)(ref val)).boneIndex1 = camperMeshData.Bones[num2 + 1];
			((BoneWeight)(ref val)).boneIndex2 = camperMeshData.Bones[num2 + 2];
			((BoneWeight)(ref val)).boneIndex3 = camperMeshData.Bones[num2 + 3];
			((BoneWeight)(ref val)).weight0 = camperMeshData.Weights[num2];
			((BoneWeight)(ref val)).weight1 = camperMeshData.Weights[num2 + 1];
			((BoneWeight)(ref val)).weight2 = camperMeshData.Weights[num2 + 2];
			((BoneWeight)(ref val)).weight3 = camperMeshData.Weights[num2 + 3];
			array4[num3] = val;
		}
		Mesh val2 = new Mesh
		{
			indexFormat = (IndexFormat)(vertexCount > 65535),
			vertices = array,
			normals = array2,
			uv = array3,
			boneWeights = array4,
			bindposes = (Matrix4x4[])binds.Clone(),
			triangles = camperMeshData.Indices
		};
		val2.RecalculateBounds();
		val2.RecalculateTangents();
		return val2;
	}
}
public sealed class CamperPresentation : MonoBehaviour
{
	private sealed class Dynamic
	{
		public HappyCamper.Motion Spec;

		public bool Bag;

		public Mesh Mesh;

		public MeshRenderer Renderer;

		public Vector3[] Source;

		public Vector3[] Normals;

		public Vector3[] Points;

		public Vector3[] OutNormals;

		public BoneWeight[] Weights;

		public BoneWeight[] UniqueWeights;

		public int[] WeightMap;

		public Matrix4x4[] Blends;

		public Vector3[] NormalX;

		public Vector3[] NormalY;

		public Vector3[] NormalZ;

		public Pendulum Solver = new Pendulum();

		public Vector3 PreviousFrameAnchor;

		public bool FrameReady;
	}

	[SerializeField]
	private SkinnedMeshRenderer body;

	[SerializeField]
	private SkinnedMeshRenderer bag;

	private ModelSkinController controller;

	private CharacterModel character;

	private bool subscribed;

	private bool acquired;

	private bool dying;

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

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

	private readonly List<Dynamic> dynamics = new List<Dynamic>();

	private Matrix4x4[] bodyWorld = (Matrix4x4[])(object)new Matrix4x4[120];

	private Matrix4x4[] bagWorld = (Matrix4x4[])(object)new Matrix4x4[120];

	private Bounds bodyBounds;

	private Bounds bagBounds;

	private bool bodyOffscreen;

	private bool bagOffscreen;

	private readonly Bounds expanded = new Bounds(new Vector3(0f, 1f, 0f), new Vector3(8f, 8f, 8f));

	internal void Configure(SkinnedMeshRenderer b, SkinnedMeshRenderer g)
	{
		body = b;
		bag = g;
	}

	private void OnEnable()
	{
		Subscribe();
	}

	private void Subscribe()
	{
		if (!subscribed)
		{
			controller = ((Component)this).GetComponent<ModelSkinController>();
			character = ((Component)this).GetComponent<CharacterModel>();
			if (Object.op_Implicit((Object)(object)controller))
			{
				controller.onSkinApplied += Applied;
				subscribed = true;
			}
		}
	}

	private void Applied(int index)
	{
		Release();
	}

	private bool Own()
	{
		HappyCamper instance = HappyCamper.Instance;
		if (!Object.op_Implicit((Object)(object)instance) || !instance.Ready || !Object.op_Implicit((Object)(object)controller) || !Object.op_Implicit((Object)(object)body) || !Object.op_Implicit((Object)(object)bag) || !((Component)body).transform.IsChildOf(((Component)this).transform) || !((Component)bag).transform.IsChildOf(((Component)this).transform))
		{
			return false;
		}
		int currentSkinIndex = controller.currentSkinIndex;
		if (currentSkinIndex >= 0 && currentSkinIndex < controller.skins.Length && (Object)(object)controller.skins[currentSkinIndex] == (Object)(object)instance.Skin && (Object)(object)body.sharedMesh == (Object)(object)instance.Meshes["body"])
		{
			return (Object)(object)bag.sharedMesh == (Object)(object)instance.Meshes["bag"];
		}
		return false;
	}

	internal static void ValidateMotion(HappyCamper.Motion s)
	{
		//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c2: 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 (s.anchor != null && s.anchor.Length == 3 && s.center != null && s.center.Length == 3 && s.normal != null && s.normal.Length == 3 && s.slots != null && s.weights != null && s.slots.Length == s.weights.Length && s.slots.Length >= 1 && s.slots.Length <= 4 && !s.slots.Any((int i) => i < 0 || i >= 118) && !s.weights.Any((float w) => !CamperPayload.Finite(w) || w < 0f) && !(Math.Abs(s.weights.Sum() - 1f) > 0.0001f) && !(s.maxAngleDegrees < 0f) && !(s.maxAngleDegrees > 45f) && CamperPayload.Finite(s.damping) && CamperPayload.Finite(s.stiffness) && CamperPayload.Finite(s.maxAngleDegrees) && !(s.damping < 0f) && !(s.damping > 30f) && !(s.stiffness < 0f) && !(s.stiffness > 30f))
		{
			Vector3 val = V(s.normal);
			if (!(((Vector3)(ref val)).sqrMagnitude < 0.5f))
			{
				val = V(s.center);
				if (!((Vector3)(ref val)).Equals(V(s.anchor)) && !s.anchor.Concat(s.center).Concat(s.normal).Any((float f) => !CamperPayload.Finite(f)))
				{
					return;
				}
			}
		}
		throw new InvalidDataException("Invalid cosmetic motion " + s.id);
	}

	private GameObject Child(string name, Transform parent)
	{
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Expected O, but got Unknown
		GameObject val = new GameObject("HappyCamper_" + name);
		val.layer = ((Component)this).gameObject.layer;
		val.transform.SetParent(parent, false);
		objects.Add(val);
		return val;
	}

	private void AddInfo(Renderer r)
	{
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_006e: Unknown result type (might be due to invalid IL or missing references)
		HappyCamper instance = HappyCamper.Instance;
		owned.Add(r);
		RendererInfo val = character.baseRendererInfos.First((RendererInfo i) => (Object)(object)i.renderer == (Object)(object)body);
		val.renderer = r;
		val.defaultMaterial = instance.Gear;
		val.ignoreOverlays = false;
		val.hideOnDeath = false;
		character.baseRendererInfos = character.baseRendererInfos.Concat((IEnumerable<RendererInfo>)(object)new RendererInfo[1] { val }).ToArray();
		character.forceUpdate = true;
	}

	private void Acquire()
	{
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_005a: Unknown result type (might be due to invalid IL or missing references)
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0093: Unknown result type (might be due to invalid IL or missing references)
		//IL_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		//IL_009f: 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_0147: 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_0301: 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_033a: Unknown result type (might be due to invalid IL or missing references)
		HappyCamper instance = HappyCamper.Instance;
		instance.Validate(((Component)this).gameObject, body);
		instance.Validate(((Component)this).gameObject, bag);
		if (!Object.op_Implicit((Object)(object)character))
		{
			throw new InvalidOperationException("CharacterModel missing");
		}
		bodyBounds = ((Renderer)body).localBounds;
		bagBounds = ((Renderer)bag).localBounds;
		bodyOffscreen = body.updateWhenOffscreen;
		bagOffscreen = bag.updateWhenOffscreen;
		SkinnedMeshRenderer obj = body;
		Bounds localBounds = (((Renderer)bag).localBounds = expanded);
		((Renderer)obj).localBounds = localBounds;
		SkinnedMeshRenderer obj2 = body;
		bool updateWhenOffscreen = (bag.updateWhenOffscreen = true);
		obj2.updateWhenOffscreen = updateWhenOffscreen;
		acquired = true;
		dying = false;
		SkinnedMeshRenderer val2 = Child("body-gear", ((Component)body).transform).AddComponent<SkinnedMeshRenderer>();
		val2.sharedMesh = instance.Meshes["body-gear"];
		val2.bones = body.bones;
		val2.rootBone = body.rootBone;
		((Renderer)val2).sharedMaterial = instance.Gear;
		((Renderer)val2).localBounds = expanded;
		val2.updateWhenOffscreen = true;
		((Renderer)val2).shadowCastingMode = ((Renderer)body).shadowCastingMode;
		((Renderer)val2).receiveShadows = ((Renderer)body).receiveShadows;
		AddInfo((Renderer)(object)val2);
		HappyCamper.Motion[] motion = instance.Data.motion;
		foreach (HappyCamper.Motion spec in motion)
		{
			HappyCamper.Part part = instance.Data.parts.Single((HappyCamper.Part a) => a.id == spec.id);
			Mesh val3 = instance.Meshes[spec.id];
			GameObject obj3 = Child(spec.id, ((Component)this).transform);
			MeshFilter val4 = obj3.AddComponent<MeshFilter>();
			MeshRenderer val5 = obj3.AddComponent<MeshRenderer>();
			Mesh val6 = Object.Instantiate<Mesh>(val3);
			((Object)val6).name = ((Object)val3).name + "_actor";
			val6.MarkDynamic();
			val4.sharedMesh = val6;
			((Renderer)val5).sharedMaterial = instance.Gear;
			((Renderer)val5).shadowCastingMode = ((Renderer)body).shadowCastingMode;
			((Renderer)val5).receiveShadows = ((Renderer)body).receiveShadows;
			Dynamic dynamic = new Dynamic
			{
				Spec = spec,
				Bag = part.isBag,
				Mesh = val6,
				Renderer = val5,
				Source = val3.vertices,
				Normals = val3.normals,
				Weights = val3.boneWeights,
				Points = (Vector3[])(object)new Vector3[val3.vertexCount],
				OutNormals = (Vector3[])(object)new Vector3[val3.vertexCount]
			};
			Dictionary<BoneWeight, int> dictionary = new Dictionary<BoneWeight, int>();
			List<BoneWeight> list = new List<BoneWeight>();
			dynamic.WeightMap = new int[dynamic.Weights.Length];
			for (int num = 0; num < dynamic.Weights.Length; num++)
			{
				if (!dictionary.TryGetValue(dynamic.Weights[num], out var value))
				{
					value = list.Count;
					dictionary.Add(dynamic.Weights[num], value);
					list.Add(dynamic.Weights[num]);
				}
				dynamic.WeightMap[num] = value;
			}
			dynamic.UniqueWeights = list.ToArray();
			dynamic.Blends = (Matrix4x4[])(object)new Matrix4x4[list.Count];
			dynamic.NormalX = (Vector3[])(object)new Vector3[list.Count];
			dynamic.NormalY = (Vector3[])(object)new Vector3[list.Count];
			dynamic.NormalZ = (Vector3[])(object)new Vector3[list.Count];
			dynamics.Add(dynamic);
			AddInfo((Renderer)(object)val5);
		}
	}

	private void Release()
	{
		//IL_0135: Unknown result type (might be due to invalid IL or missing references)
		//IL_013b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0189: 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_014e: 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)
		if (!acquired && owned.Count == 0)
		{
			return;
		}
		if (Object.op_Implicit((Object)(object)character))
		{
			HashSet<Renderer> refs = new HashSet<Renderer>(owned);
			character.baseRendererInfos = character.baseRendererInfos.Where((RendererInfo i) => !refs.Contains(i.renderer)).ToArray();
			character.forceUpdate = true;
		}
		foreach (Dynamic dynamic in dynamics)
		{
			if (Object.op_Implicit((Object)(object)dynamic.Mesh))
			{
				Object.Destroy((Object)(object)dynamic.Mesh);
			}
		}
		foreach (GameObject @object in objects)
		{
			if (Object.op_Implicit((Object)(object)@object))
			{
				@object.SetActive(false);
				Object.Destroy((Object)(object)@object);
			}
		}
		dynamics.Clear();
		objects.Clear();
		owned.Clear();
		if (Object.op_Implicit((Object)(object)body))
		{
			if (((Renderer)body).localBounds == expanded)
			{
				((Renderer)body).localBounds = bodyBounds;
			}
			if (body.updateWhenOffscreen)
			{
				body.updateWhenOffscreen = bodyOffscreen;
			}
		}
		if (Object.op_Implicit((Object)(object)bag))
		{
			if (((Renderer)bag).localBounds == expanded)
			{
				((Renderer)bag).localBounds = bagBounds;
			}
			if (bag.updateWhenOffscreen)
			{
				bag.updateWhenOffscreen = bagOffscreen;
			}
		}
		acquired = false;
		dying = false;
	}

	private static Vector3 V(float[] a)
	{
		//IL_0009: Unknown result type (might be due to invalid IL or missing references)
		return new Vector3(a[0], a[1], a[2]);
	}

	private static Matrix4x4 Frame(HappyCamper.Motion spec, Matrix4x4[] matrices)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_005c: Unknown result type (might be due to invalid IL or missing references)
		Matrix4x4 result = default(Matrix4x4);
		for (int i = 0; i < spec.slots.Length; i++)
		{
			for (int j = 0; j < 16; j++)
			{
				int num = j;
				((Matrix4x4)(ref result))[num] = ((Matrix4x4)(ref result))[num] + ((Matrix4x4)(ref matrices[spec.slots[i]]))[j] * spec.weights[i];
			}
		}
		return result;
	}

	private static Vector3 Skin(Vector3 v, BoneWeight w, Matrix4x4[] m, bool normal)
	{
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_005c: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		//IL_0069: Unknown result type (might be due to invalid IL or missing references)
		//IL_006e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: Unknown result type (might be due to invalid IL or missing references)
		//IL_0084: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
		return (normal ? ((Matrix4x4)(ref m[((BoneWeight)(ref w)).boneIndex0])).MultiplyVector(v) : ((Matrix4x4)(ref m[((BoneWeight)(ref w)).boneIndex0])).MultiplyPoint3x4(v)) * ((BoneWeight)(ref w)).weight0 + (normal ? ((Matrix4x4)(ref m[((BoneWeight)(ref w)).boneIndex1])).MultiplyVector(v) : ((Matrix4x4)(ref m[((BoneWeight)(ref w)).boneIndex1])).MultiplyPoint3x4(v)) * ((BoneWeight)(ref w)).weight1 + (normal ? ((Matrix4x4)(ref m[((BoneWeight)(ref w)).boneIndex2])).MultiplyVector(v) : ((Matrix4x4)(ref m[((BoneWeight)(ref w)).boneIndex2])).MultiplyPoint3x4(v)) * ((BoneWeight)(ref w)).weight2 + (normal ? ((Matrix4x4)(ref m[((BoneWeight)(ref w)).boneIndex3])).MultiplyVector(v) : ((Matrix4x4)(ref m[((BoneWeight)(ref w)).boneIndex3])).MultiplyPoint3x4(v)) * ((BoneWeight)(ref w)).weight3;
	}

	private void LateUpdate()
	{
		//IL_0077: Unknown result type (might be due to invalid IL or missing references)
		//IL_0084: Unknown result type (might be due to invalid IL or missing references)
		//IL_0089: Unknown result type (might be due to invalid IL or missing references)
		//IL_008e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c0: 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_011a: Unknown result type (might be due to invalid IL or missing references)
		//IL_011f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0123: Unknown result type (might be due to invalid IL or missing references)
		//IL_0128: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01db: Unknown result type (might be due to invalid IL or missing references)
		//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f0: 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_0205: Unknown result type (might be due to invalid IL or missing references)
		//IL_020a: Unknown result type (might be due to invalid IL or missing references)
		//IL_020f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0211: Unknown result type (might be due to invalid IL or missing references)
		//IL_0216: Unknown result type (might be due to invalid IL or missing references)
		//IL_0260: 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_0269: Unknown result type (might be due to invalid IL or missing references)
		//IL_026d: 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_0276: Unknown result type (might be due to invalid IL or missing references)
		//IL_027b: Unknown result type (might be due to invalid IL or missing references)
		//IL_028b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0290: Unknown result type (might be due to invalid IL or missing references)
		//IL_0295: Unknown result type (might be due to invalid IL or missing references)
		//IL_0299: Unknown result type (might be due to invalid IL or missing references)
		//IL_029e: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d8: Unknown result type (might be due to invalid IL or missing references)
		//IL_02da: 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_0349: Unknown result type (might be due to invalid IL or missing references)
		//IL_0356: Unknown result type (might be due to invalid IL or missing references)
		//IL_035f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0364: Unknown result type (might be due to invalid IL or missing references)
		//IL_0369: Unknown result type (might be due to invalid IL or missing references)
		//IL_037c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0381: Unknown result type (might be due to invalid IL or missing references)
		//IL_0385: Unknown result type (might be due to invalid IL or missing references)
		//IL_030f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0314: Unknown result type (might be due to invalid IL or missing references)
		//IL_031d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0322: Unknown result type (might be due to invalid IL or missing references)
		//IL_0324: Unknown result type (might be due to invalid IL or missing references)
		//IL_042b: Unknown result type (might be due to invalid IL or missing references)
		//IL_042d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0435: Unknown result type (might be due to invalid IL or missing references)
		//IL_043a: Unknown result type (might be due to invalid IL or missing references)
		//IL_043f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0444: Unknown result type (might be due to invalid IL or missing references)
		//IL_0449: Unknown result type (might be due to invalid IL or missing references)
		//IL_044e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0453: Unknown result type (might be due to invalid IL or missing references)
		//IL_0458: Unknown result type (might be due to invalid IL or missing references)
		//IL_045d: Unknown result type (might be due to invalid IL or missing references)
		//IL_045f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0461: Unknown result type (might be due to invalid IL or missing references)
		//IL_0463: Unknown result type (might be due to invalid IL or missing references)
		//IL_0465: Unknown result type (might be due to invalid IL or missing references)
		//IL_054c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0551: Unknown result type (might be due to invalid IL or missing references)
		//IL_0556: Unknown result type (might be due to invalid IL or missing references)
		//IL_0561: Unknown result type (might be due to invalid IL or missing references)
		//IL_0579: Unknown result type (might be due to invalid IL or missing references)
		//IL_0587: Unknown result type (might be due to invalid IL or missing references)
		//IL_059f: Unknown result type (might be due to invalid IL or missing references)
		//IL_05a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_05b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_05ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_05cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_05d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_05e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_05e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_05e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_05e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_05e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_05ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_05f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_05f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_05fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_060d: Unknown result type (might be due to invalid IL or missing references)
		//IL_060f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0611: Unknown result type (might be due to invalid IL or missing references)
		//IL_0616: Unknown result type (might be due to invalid IL or missing references)
		//IL_061b: Unknown result type (might be due to invalid IL or missing references)
		//IL_061f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0624: Unknown result type (might be due to invalid IL or missing references)
		//IL_04e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_04e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_04f4: Unknown result type (might be due to invalid IL or missing references)
		//IL_04f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_0504: Unknown result type (might be due to invalid IL or missing references)
		//IL_0506: Unknown result type (might be due to invalid IL or missing references)
		//IL_0488: Unknown result type (might be due to invalid IL or missing references)
		//IL_048a: Unknown result type (might be due to invalid IL or missing references)
		//IL_048c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0493: Unknown result type (might be due to invalid IL or missing references)
		//IL_0498: Unknown result type (might be due to invalid IL or missing references)
		//IL_04a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_04a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_04aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_04b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_04b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_04c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_04c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_04c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_04cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_04d4: Unknown result type (might be due to invalid IL or missing references)
		Subscribe();
		if (!Own())
		{
			Release();
			return;
		}
		if (!acquired)
		{
			try
			{
				Acquire();
			}
			catch (Exception ex)
			{
				Release();
				Debug.LogError((object)("HAPPY_CAMPER_COSMETICS " + ex));
				((Behaviour)this).enabled = false;
				return;
			}
		}
		HappyCamper instance = HappyCamper.Instance;
		for (int i = 0; i < 120; i++)
		{
			bodyWorld[i] = body.bones[i].localToWorldMatrix * instance.BodyBinds[i];
			bagWorld[i] = bag.bones[i].localToWorldMatrix * instance.BagBinds[i];
		}
		owned[0].enabled = ((Renderer)body).enabled && ((Component)body).gameObject.activeInHierarchy;
		float deltaTime = Time.deltaTime;
		Matrix4x4 worldToLocalMatrix = ((Component)this).transform.worldToLocalMatrix;
		Matrix4x4 val = ((Component)this).transform.localToWorldMatrix;
		Matrix4x4 transpose = ((Matrix4x4)(ref val)).transpose;
		foreach (Dynamic dynamic in dynamics)
		{
			bool flag = ((Renderer)(dynamic.Bag ? bag : body)).enabled && ((Component)(dynamic.Bag ? bag : body)).gameObject.activeInHierarchy;
			((Renderer)dynamic.Renderer).enabled = flag;
			if (!flag)
			{
				dynamic.FrameReady = false;
				dynamic.Solver.Ready = false;
				continue;
			}
			Matrix4x4[] array = (dynamic.Bag ? bagWorld : bodyWorld);
			Matrix4x4 val2 = Frame(dynamic.Spec, array);
			Vector3 val3 = ((Matrix4x4)(ref val2)).MultiplyPoint3x4(V(dynamic.Spec.anchor));
			Vector3 val4 = ((Matrix4x4)(ref val2)).MultiplyPoint3x4(V(dynamic.Spec.center)) - val3;
			float magnitude = ((Vector3)(ref val4)).magnitude;
			if (magnitude < 1E-05f || !CamperPayload.Finite(magnitude) || Mathf.Abs(((Matrix4x4)(ref val2)).determinant) < 1E-12f)
			{
				((Renderer)dynamic.Renderer).enabled = false;
				dynamic.FrameReady = false;
				continue;
			}
			Vector3 val5 = val4 / magnitude;
			val = ((Matrix4x4)(ref val2)).inverse;
			val = ((Matrix4x4)(ref val)).transpose;
			Vector3 val6 = ((Matrix4x4)(ref val)).MultiplyVector(V(dynamic.Spec.normal));
			Vector3 normalized = ((Vector3)(ref val6)).normalized;
			if (!dynamic.FrameReady || deltaTime > 0.15f || Vector3.Distance(val3, dynamic.PreviousFrameAnchor) > 1.5f || dying)
			{
				dynamic.Solver.Reset(val3, val5);
			}
			else if (deltaTime > 0f)
			{
				int num = Mathf.Clamp(Mathf.CeilToInt(deltaTime * 120f), 1, 12);
				for (int j = 1; j <= num; j++)
				{
					dynamic.Solver.Step(Vector3.Lerp(dynamic.PreviousFrameAnchor, val3, (float)j / (float)num), val5, normalized, magnitude, deltaTime / (float)num, dynamic.Spec);
				}
			}
			dynamic.PreviousFrameAnchor = val3;
			dynamic.FrameReady = true;
			Quaternion val7 = Quaternion.FromToRotation(val5, dynamic.Solver.Direction);
			for (int k = 0; k < dynamic.UniqueWeights.Length; k++)
			{
				BoneWeight val8 = dynamic.UniqueWeights[k];
				Matrix4x4 val9 = default(Matrix4x4);
				for (int l = 0; l < 16; l++)
				{
					((Matrix4x4)(ref val9))[l] = ((Matrix4x4)(ref array[((BoneWeight)(ref val8)).boneIndex0]))[l] * ((BoneWeight)(ref val8)).weight0 + ((Matrix4x4)(ref array[((BoneWeight)(ref val8)).boneIndex1]))[l] * ((BoneWeight)(ref val8)).weight1 + ((Matrix4x4)(ref array[((BoneWeight)(ref val8)).boneIndex2]))[l] * ((BoneWeight)(ref val8)).weight2 + ((Matrix4x4)(ref array[((BoneWeight)(ref val8)).boneIndex3]))[l] * ((BoneWeight)(ref val8)).weight3;
				}
				dynamic.Blends[k] = val9;
				Vector3 val10 = Vector4.op_Implicit(((Matrix4x4)(ref val9)).GetColumn(0));
				Vector3 val11 = Vector4.op_Implicit(((Matrix4x4)(ref val9)).GetColumn(1));
				Vector3 val12 = Vector4.op_Implicit(((Matrix4x4)(ref val9)).GetColumn(2));
				float num2 = Vector3.Dot(val10, Vector3.Cross(val11, val12));
				if (Mathf.Abs(num2) > 1E-12f)
				{
					dynamic.NormalX[k] = Vector3.Cross(val11, val12) / num2;
					dynamic.NormalY[k] = Vector3.Cross(val12, val10) / num2;
					dynamic.NormalZ[k] = Vector3.Cross(val10, val11) / num2;
				}
				else
				{
					dynamic.NormalX[k] = val10;
					dynamic.NormalY[k] = val11;
					dynamic.NormalZ[k] = val12;
				}
			}
			for (int m = 0; m < dynamic.Source.Length; m++)
			{
				int num3 = dynamic.WeightMap[m];
				Vector3 val13 = ((Matrix4x4)(ref dynamic.Blends[num3])).MultiplyPoint3x4(dynamic.Source[m]);
				Vector3 val14 = dynamic.NormalX[num3] * dynamic.Normals[m].x + dynamic.NormalY[num3] * dynamic.Normals[m].y + dynamic.NormalZ[num3] * dynamic.Normals[m].z;
				dynamic.Points[m] = ((Matrix4x4)(ref worldToLocalMatrix)).MultiplyPoint3x4(val3 + val7 * (val13 - val3));
				Vector3[] outNormals = dynamic.OutNormals;
				int num4 = m;
				val6 = ((Matrix4x4)(ref transpose)).MultiplyVector(val7 * val14);
				outNormals[num4] = ((Vector3)(ref val6)).normalized;
			}
			dynamic.Mesh.vertices = dynamic.Points;
			dynamic.Mesh.normals = dynamic.OutNormals;
			dynamic.Mesh.RecalculateBounds();
		}
	}

	internal Mesh BeginDeath()
	{
		if (!Own())
		{
			return null;
		}
		dying = true;
		foreach (Dynamic dynamic in dynamics)
		{
			if (dynamic.Bag)
			{
				((Renderer)dynamic.Renderer).enabled = false;
			}
		}
		Mesh sharedMesh = bag.sharedMesh;
		bag.sharedMesh = HappyCamper.Instance.Meshes["death-bag"];
		return sharedMesh;
	}

	internal void EndDeath(Mesh previous)
	{
		HappyCamper instance = HappyCamper.Instance;
		if (Object.op_Implicit((Object)(object)previous) && Object.op_Implicit((Object)(object)bag) && Object.op_Implicit((Object)(object)instance) && (Object)(object)bag.sharedMesh == (Object)(object)instance.Meshes["death-bag"])
		{
			bag.sharedMesh = previous;
		}
	}

	private void OnDisable()
	{
		Release();
		if (subscribed && Object.op_Implicit((Object)(object)controller))
		{
			controller.onSkinApplied -= Applied;
		}
		subscribed = false;
	}

	private void OnDestroy()
	{
		OnDisable();
	}
}
internal sealed class Pendulum
{
	internal Vector3 Direction;

	internal Vector3 Velocity;

	internal Vector3 Previous;

	internal Vector3 AnchorVelocity;

	internal bool Ready;

	internal void Reset(Vector3 anchor, Vector3 basis)
	{
		//IL_0003: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_000f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		Direction = ((Vector3)(ref basis)).normalized;
		Velocity = (AnchorVelocity = Vector3.zero);
		Previous = anchor;
		Ready = true;
	}

	internal void Step(Vector3 anchor, Vector3 basis, Vector3 normal, float length, float dt, HappyCamper.Motion spec)
	{
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: 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_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: 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_004b: Unknown result type (might be due to invalid IL or missing references)
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0064: Unknown result type (might be due to invalid IL or missing references)
		//IL_0065: Unknown result type (might be due to invalid IL or missing references)
		//IL_0076: Unknown result type (might be due to invalid IL or missing references)
		//IL_007b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: Unknown result type (might be due to invalid IL or missing references)
		//IL_0009: Unknown result type (might be due to invalid IL or missing references)
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b3: 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_00bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fa: 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_0106: Unknown result type (might be due to invalid IL or missing references)
		//IL_010c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0116: Unknown result type (might be due to invalid IL or missing references)
		//IL_011b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0120: Unknown result type (might be due to invalid IL or missing references)
		//IL_0127: 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_0134: Unknown result type (might be due to invalid IL or missing references)
		//IL_0139: Unknown result type (might be due to invalid IL or missing references)
		//IL_013e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0142: Unknown result type (might be due to invalid IL or missing references)
		//IL_0147: Unknown result type (might be due to invalid IL or missing references)
		//IL_014c: Unknown result type (might be due to invalid IL or missing references)
		//IL_014e: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_01be: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0162: 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_017b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0180: 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_0190: 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_019f: Unknown result type (might be due to invalid IL or missing references)
		//IL_029b: 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_02a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ad: 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)
		//IL_02bc: 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_01cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0201: 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_020a: Unknown result type (might be due to invalid IL or missing references)
		//IL_020f: 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: Unknown result type (might be due to invalid IL or missing references)
		//IL_023e: Unknown result type (might be due to invalid IL or missing references)
		//IL_025a: Unknown result type (might be due to invalid IL or missing references)
		//IL_025f: 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_026a: Unknown result type (might be due to invalid IL or missing references)
		//IL_026f: Unknown result type (might be due to invalid IL or missing references)
		//IL_021f: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_022e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0233: Unknown result type (might be due to invalid IL or missing references)
		//IL_0282: Unknown result type (might be due to invalid IL or missing references)
		//IL_0287: 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_028f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0294: Unknown result type (might be due to invalid IL or missing references)
		if (!Ready)
		{
			Reset(anchor, basis);
		}
		Vector3 val = (anchor - Previous) / dt;
		Vector3 val2 = Vector3.ClampMagnitude((val - AnchorVelocity) / dt, 35f);
		Previous = anchor;
		AnchorVelocity = val;
		Vector3 val3 = (new Vector3(0f, -9.81f, 0f) - val2) / Mathf.Max(length, 0.08f) + basis * spec.stiffness * (float)(spec.id.StartsWith("bow-loop") ? 20 : 8);
		val3 -= Direction * Vector3.Dot(val3, Direction);
		Velocity = (Velocity + val3 * dt) * Mathf.Exp((0f - spec.damping) * dt);
		Velocity -= Direction * Vector3.Dot(Velocity, Direction);
		Vector3 val4 = Direction + Velocity * dt;
		Direction = ((Vector3)(ref val4)).normalized;
		if (Vector3.Angle(basis, Direction) > spec.maxAngleDegrees)
		{
			val4 = Vector3.RotateTowards(basis, Direction, spec.maxAngleDegrees * ((float)Math.PI / 180f), 0f);
			Direction = ((Vector3)(ref val4)).normalized;
			Velocity *= 0.25f;
		}
		float num = -0.005f / Mathf.Max(length, 0.08f);
		if (Vector3.Dot(Direction - basis, normal) < num)
		{
			float num2 = Mathf.Clamp(Vector3.Dot(basis, normal) + num, -1f, 1f);
			val4 = Direction - normal * Vector3.Dot(Direction, normal);
			Vector3 normalized = ((Vector3)(ref val4)).normalized;
			if (((Vector3)(ref normalized)).sqrMagnitude < 0.1f)
			{
				val4 = Vector3.Cross(normal, Vector3.up);
				normalized = ((Vector3)(ref val4)).normalized;
			}
			Direction = normal * num2 + normalized * Mathf.Sqrt(Mathf.Max(0f, 1f - num2 * num2));
			float num3 = Vector3.Dot(Velocity, normal);
			if (num3 < 0f)
			{
				Velocity -= normal * num3;
			}
		}
		Velocity -= Direction * Vector3.Dot(Velocity, Direction);
	}
}
internal sealed class CamperMeshData
{
	public int VertexCount;

	public float[] Values;

	public float[] Weights;

	public int[] Bones;

	public int[] Indices;

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

	private static float F(BinaryReader r)
	{
		float num = r.ReadSingle();
		if (!Finite(num))
		{
			throw new InvalidDataException("Nonfinite mesh value");
		}
		return num;
	}

	public static CamperMeshData Read(byte[] bytes, string[] names, bool bag)
	{
		using BinaryReader binaryReader = new BinaryReader(new MemoryStream(bytes, writable: false));
		if (new string(binaryReader.ReadChars(4)) != "PWE1")
		{
			throw new InvalidDataException("Mesh magic");
		}
		int num = binaryReader.ReadInt32();
		int num2 = binaryReader.ReadInt32();
		int num3 = binaryReader.ReadInt32();
		if (num < 3 || num > 300000 || num2 < 3 || num2 > 1800000 || num2 % 3 != 0 || num3 != 120 || names == null || names.Length != 120)
		{
			throw new InvalidDataException("Mesh dimensions");
		}
		for (int i = 0; i < num3; i++)
		{
			int num4 = binaryReader.ReadInt32();
			if (num4 < 1 || num4 > 128)
			{
				throw new InvalidDataException("Bone string");
			}
			byte[] array = binaryReader.ReadBytes(num4);
			if (array.Length != num4 || Encoding.UTF8.GetString(array) != names[i])
			{
				throw new InvalidDataException("Bone order");
			}
		}
		if (binaryReader.BaseStream.Length - binaryReader.BaseStream.Position != (long)num * 64L + (long)num2 * 4L)
		{
			throw new InvalidDataException("Mesh byte length");
		}
		CamperMeshData camperMeshData = new CamperMeshData
		{
			VertexCount = num,
			Values = new float[num * 8],
			Bones = new int[num * 4],
			Weights = new float[num * 4],
			Indices = new int[num2]
		};
		for (int j = 0; j < num; j++)
		{
			for (int k = 0; k < 8; k++)
			{
				camperMeshData.Values[j * 8 + k] = F(binaryReader);
			}
			for (int l = 0; l < 4; l++)
			{
				int num5 = binaryReader.ReadInt32();
				if (num5 < 0 || num5 >= 120)
				{
					throw new InvalidDataException("Bone range");
				}
				camperMeshData.Bones[j * 4 + l] = num5;
			}
			float num6 = 0f;
			for (int m = 0; m < 4; m++)
			{
				float num7 = F(binaryReader);
				int num8 = camperMeshData.Bones[j * 4 + m];
				if (num7 < 0f || num7 > 1f || (num7 > 1E-07f && (num8 >= 118 || (bag && (num8 < 77 || num8 > 117)))))
				{
					throw new InvalidDataException("Forbidden weight");
				}
				camperMeshData.Weights[j * 4 + m] = num7;
				num6 += num7;
			}
			float num9 = camperMeshData.Values[j * 8 + 3];
			float num10 = camperMeshData.Values[j * 8 + 4];
			float num11 = camperMeshData.Values[j * 8 + 5];
			if (Math.Abs(num6 - 1f) > 0.0001f || num9 * num9 + num10 * num10 + num11 * num11 < 0.01f)
			{
				throw new InvalidDataException("Normal/weight contract");
			}
		}
		for (int n = 0; n < num2; n++)
		{
			int num12 = binaryReader.ReadInt32();
			if (num12 < 0 || num12 >= num)
			{
				throw new InvalidDataException("Triangle range");
			}
			camperMeshData.Indices[n] = num12;
		}
		if (binaryReader.BaseStream.Position != binaryReader.BaseStream.Length)
		{
			throw new InvalidDataException("Trailing bytes");
		}
		return camperMeshData;
	}
}