Decompiled source of GFL2 Florence v1.0.0

plugins/FlorenceSuit.dll

Decompiled 6 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Configuration;
using GameNetcodeStuff;
using HarmonyLib;
using ModelReplacement;
using ModelReplacement.AvatarBodyUpdater;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;

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

public static class FlorenceAssets
{
	public const string ResourceName = "FlorenceSuit.florencesuits";

	private static AssetBundle bundle;

	private static Stream resourceStream;

	public static AssetBundle Load()
	{
		if (Object.op_Implicit((Object)(object)bundle))
		{
			return bundle;
		}
		Stream manifestResourceStream = typeof(FlorenceAssets).Assembly.GetManifestResourceStream("FlorenceSuit.florencesuits");
		if (manifestResourceStream == null)
		{
			throw new InvalidOperationException("The Florence model resource is missing from FlorenceSuit.dll.");
		}
		try
		{
			if (!manifestResourceStream.CanRead || !manifestResourceStream.CanSeek)
			{
				throw new InvalidOperationException("The Florence model resource must be readable and seekable.");
			}
			AssetBundle obj = AssetBundle.LoadFromStream(manifestResourceStream);
			if (!Object.op_Implicit((Object)(object)obj))
			{
				throw new InvalidOperationException("The embedded Florence model bundle could not be loaded.");
			}
			resourceStream = manifestResourceStream;
			bundle = obj;
			return bundle;
		}
		catch
		{
			manifestResourceStream.Dispose();
			throw;
		}
	}
}
[DefaultExecutionOrder(325)]
public class FlorenceChestCorrectives : MonoBehaviour
{
	private Transform[] breast;

	private Vector3[] rest;

	private Vector3[] travel;

	private SkinnedMeshRenderer[] cloth;

	private int[][] indices;

	private float[][] previous;

	private bool ready;

	public static string ShapeName(int side, int axis, int sign)
	{
		return "FlorenceChest_" + ((side == 0) ? "L" : "R") + "_" + "XYZ"[axis] + ((sign == 0) ? "_Pos" : "_Neg");
	}

	private void Awake()
	{
		Initialize();
	}

	public bool Initialize()
	{
		//IL_0108: Unknown result type (might be due to invalid IL or missing references)
		//IL_010d: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_012e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0133: Unknown result type (might be due to invalid IL or missing references)
		//IL_0141: 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)
		if (ready)
		{
			return true;
		}
		breast = (Transform[])(object)new Transform[2];
		rest = (Vector3[])(object)new Vector3[2];
		Transform[] componentsInChildren = ((Component)this).GetComponentsInChildren<Transform>(true);
		foreach (Transform val in componentsInChildren)
		{
			if (((Object)val).name == "DEF-breast.L")
			{
				breast[0] = val;
			}
			else if (((Object)val).name == "DEF-breast.R")
			{
				breast[1] = val;
			}
		}
		if (!Object.op_Implicit((Object)(object)breast[0]) || !Object.op_Implicit((Object)(object)breast[1]))
		{
			return false;
		}
		Mesh val2 = null;
		MeshFilter[] componentsInChildren2 = ((Component)this).GetComponentsInChildren<MeshFilter>(true);
		foreach (MeshFilter val3 in componentsInChildren2)
		{
			if (((Object)val3).name == "FlorenceChestCalibration")
			{
				val2 = val3.sharedMesh;
				break;
			}
		}
		if (!Object.op_Implicit((Object)(object)val2) || val2.vertexCount != 4)
		{
			return false;
		}
		Vector3[] vertices = val2.vertices;
		travel = (Vector3[])(object)new Vector3[2]
		{
			vertices[2],
			vertices[3]
		};
		rest[0] = vertices[0];
		rest[1] = vertices[1];
		List<SkinnedMeshRenderer> list = new List<SkinnedMeshRenderer>();
		List<int[]> list2 = new List<int[]>();
		SkinnedMeshRenderer[] componentsInChildren3 = ((Component)this).GetComponentsInChildren<SkinnedMeshRenderer>(true);
		foreach (SkinnedMeshRenderer val4 in componentsInChildren3)
		{
			if (!Object.op_Implicit((Object)(object)val4.sharedMesh) || val4.sharedMesh.GetBlendShapeIndex(ShapeName(0, 0, 0)) < 0)
			{
				continue;
			}
			int[] array = new int[12];
			for (int j = 0; j < 2; j++)
			{
				for (int k = 0; k < 3; k++)
				{
					for (int l = 0; l < 2; l++)
					{
						int num = j * 6 + k * 2 + l;
						array[num] = val4.sharedMesh.GetBlendShapeIndex(ShapeName(j, k, l));
						if (array[num] < 0)
						{
							return false;
						}
					}
				}
			}
			list.Add(val4);
			list2.Add(array);
		}
		cloth = list.ToArray();
		indices = list2.ToArray();
		previous = new float[cloth.Length][];
		for (int m = 0; m < cloth.Length; m++)
		{
			previous[m] = new float[12];
			for (int n = 0; n < 12; n++)
			{
				previous[m][n] = -1f;
			}
		}
		ready = cloth.Length != 0;
		return ready;
	}

	public void Apply()
	{
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		if (!ready && !Initialize())
		{
			return;
		}
		for (int i = 0; i < 2; i++)
		{
			if (!Object.op_Implicit((Object)(object)breast[i]))
			{
				continue;
			}
			Vector3 val = breast[i].localPosition - rest[i];
			for (int j = 0; j < 3; j++)
			{
				for (int k = 0; k < 2; k++)
				{
					int num = i * 6 + j * 2 + k;
					float num2 = Mathf.Clamp(((Vector3)(ref val))[j] * (float)((k == 0) ? 1 : (-1)) / ((Vector3)(ref travel[i]))[j] * 100f, 0f, 100f);
					if (num2 < 0.001f)
					{
						num2 = 0f;
					}
					for (int l = 0; l < cloth.Length; l++)
					{
						if (Object.op_Implicit((Object)(object)cloth[l]) && Mathf.Abs(previous[l][num] - num2) > 0.0001f)
						{
							cloth[l].SetBlendShapeWeight(indices[l][num], num2);
							previous[l][num] = num2;
						}
					}
				}
			}
		}
	}

	private void LateUpdate()
	{
		Apply();
	}

	private void OnDisable()
	{
		if (!ready)
		{
			return;
		}
		for (int i = 0; i < cloth.Length; i++)
		{
			if (Object.op_Implicit((Object)(object)cloth[i]))
			{
				for (int j = 0; j < 12; j++)
				{
					cloth[i].SetBlendShapeWeight(indices[i][j], 0f);
					previous[i][j] = -1f;
				}
			}
		}
	}
}
public class FlorenceFootAlignment : MonoBehaviour
{
	private Transform hip;

	private Transform leftSole;

	private Transform rightSole;

	private Transform playerLeft;

	private Transform playerRight;

	private Vector3 leftReference;

	private Vector3 rightReference;

	private SkinnedMeshRenderer source;

	private bool ready;

	public float LastCorrection { get; private set; }

	public void Align(SkinnedMeshRenderer player)
	{
		//IL_01de: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f9: 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_021f: 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_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_01c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
		if (!Object.op_Implicit((Object)(object)player))
		{
			return;
		}
		if (!ready || (Object)(object)source != (Object)(object)player)
		{
			source = player;
			Animator component = ((Component)this).GetComponent<Animator>();
			if (!Object.op_Implicit((Object)(object)component) || !component.isHuman)
			{
				return;
			}
			hip = component.GetBoneTransform((HumanBodyBones)0);
			Transform[] componentsInChildren = ((Component)this).GetComponentsInChildren<Transform>(true);
			leftSole = ((IEnumerable<Transform>)componentsInChildren).FirstOrDefault((Func<Transform, bool>)((Transform t) => ((Object)t).name == "FlorenceSole.L"));
			rightSole = ((IEnumerable<Transform>)componentsInChildren).FirstOrDefault((Func<Transform, bool>)((Transform t) => ((Object)t).name == "FlorenceSole.R"));
			Transform val = ((IEnumerable<Transform>)componentsInChildren).FirstOrDefault((Func<Transform, bool>)((Transform t) => ((Object)t).name == "EmployeeSoleReference.L"));
			Transform val2 = ((IEnumerable<Transform>)componentsInChildren).FirstOrDefault((Func<Transform, bool>)((Transform t) => ((Object)t).name == "EmployeeSoleReference.R"));
			playerLeft = ((IEnumerable<Transform>)player.bones).FirstOrDefault((Func<Transform, bool>)((Transform t) => ((Object)t).name == "foot.L"));
			playerRight = ((IEnumerable<Transform>)player.bones).FirstOrDefault((Func<Transform, bool>)((Transform t) => ((Object)t).name == "foot.R"));
			ready = Object.op_Implicit((Object)(object)hip) && Object.op_Implicit((Object)(object)leftSole) && Object.op_Implicit((Object)(object)rightSole) && Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val2) && Object.op_Implicit((Object)(object)playerLeft) && Object.op_Implicit((Object)(object)playerRight);
			if (!ready)
			{
				return;
			}
			leftReference = val.localPosition;
			rightReference = val2.localPosition;
		}
		float num = Mathf.Min(playerLeft.TransformPoint(leftReference).y, playerRight.TransformPoint(rightReference).y);
		float num2 = Mathf.Min(leftSole.position.y, rightSole.position.y);
		LastCorrection = num - num2;
		if (!float.IsNaN(LastCorrection) && !float.IsInfinity(LastCorrection))
		{
			Transform obj = hip;
			obj.position += Vector3.up * LastCorrection;
		}
	}
}
public static class FlorenceFootAlignmentPatch
{
	public static void Install(Harmony h)
	{
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Expected O, but got Unknown
		h.Patch((MethodBase)AccessTools.Method(typeof(AvatarUpdater), "UpdateModel", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(FlorenceFootAlignmentPatch), "AfterPose", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
	}

	private static void AfterPose(GameObject ___replacement, SkinnedMeshRenderer ___playerModelRenderer)
	{
		if (Object.op_Implicit((Object)(object)___replacement) && ((Object)___replacement).name.StartsWith("Florence_", StringComparison.Ordinal))
		{
			FlorenceFootAlignment florenceFootAlignment = ___replacement.GetComponent<FlorenceFootAlignment>();
			if (!Object.op_Implicit((Object)(object)florenceFootAlignment))
			{
				florenceFootAlignment = ___replacement.AddComponent<FlorenceFootAlignment>();
			}
			florenceFootAlignment.Align(___playerModelRenderer);
		}
	}
}
[DefaultExecutionOrder(350)]
public class FlorenceRigidBadge : MonoBehaviour
{
	private SkinnedMeshRenderer anchors;

	private MeshFilter anchorData;

	private Transform badge;

	private Transform restFrame;

	private Vector3[] vertices;

	private BoneWeight[] weights;

	private Matrix4x4[] binds;

	private Vector3 offset;

	private Quaternion rotation;

	private bool initialized;

	private Vector3[] clearanceVertices;

	private Vector3[] cardPoints;

	private BoneWeight[] clearanceWeights;

	private Matrix4x4[] clearanceBinds;

	private Vector2[] clearanceBary;

	private Transform[] skinBones;

	private Matrix4x4[] skinMatrices;

	private Matrix4x4[] clearanceMatrices;

	private int[] usedBones;

	public int CachedBoneCount
	{
		get
		{
			if (usedBones != null)
			{
				return usedBones.Length;
			}
			return 0;
		}
	}

	public int ClearanceSampleCount
	{
		get
		{
			if (clearanceVertices != null)
			{
				return clearanceVertices.Length / 3;
			}
			return 0;
		}
	}

	public float MinimumCardClearance { get; private set; }

	public float ClearancePush { get; private set; }

	private void Start()
	{
		Initialize();
	}

	public bool Initialize()
	{
		//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0108: Unknown result type (might be due to invalid IL or missing references)
		//IL_010d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0244: Unknown result type (might be due to invalid IL or missing references)
		//IL_0249: Unknown result type (might be due to invalid IL or missing references)
		if (initialized)
		{
			return true;
		}
		anchors = ((IEnumerable<SkinnedMeshRenderer>)((Component)this).GetComponentsInChildren<SkinnedMeshRenderer>(true)).FirstOrDefault((Func<SkinnedMeshRenderer, bool>)((SkinnedMeshRenderer r) => ((Object)r).name.Contains("_Jacket")));
		anchorData = ((IEnumerable<MeshFilter>)((Component)this).GetComponentsInChildren<MeshFilter>(true)).FirstOrDefault((Func<MeshFilter, bool>)((MeshFilter r) => ((Object)r).name == "FlorenceBadgeAnchors"));
		badge = ((IEnumerable<Transform>)((Component)this).GetComponentsInChildren<Transform>(true)).FirstOrDefault((Func<Transform, bool>)((Transform t) => ((Object)t).name == "FlorenceBadgeRigid"));
		if (!Object.op_Implicit((Object)(object)anchors) || !Object.op_Implicit((Object)(object)badge) || !Object.op_Implicit((Object)(object)anchorData) || !Object.op_Implicit((Object)(object)anchorData.sharedMesh))
		{
			((Behaviour)this).enabled = false;
			return false;
		}
		restFrame = badge.parent;
		offset = badge.localPosition;
		rotation = badge.localRotation;
		vertices = anchorData.sharedMesh.vertices;
		weights = anchorData.sharedMesh.boneWeights;
		binds = anchorData.sharedMesh.bindposes;
		MeshFilter val = ((IEnumerable<MeshFilter>)((Component)this).GetComponentsInChildren<MeshFilter>(true)).FirstOrDefault((Func<MeshFilter, bool>)((MeshFilter r) => ((Object)r).name == "FlorenceBadgeClearance"));
		if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val.sharedMesh))
		{
			Mesh sharedMesh = val.sharedMesh;
			clearanceVertices = sharedMesh.vertices;
			clearanceWeights = sharedMesh.boneWeights;
			clearanceBinds = sharedMesh.bindposes;
			cardPoints = sharedMesh.normals;
			clearanceBary = sharedMesh.uv;
		}
		skinBones = anchors.bones;
		skinMatrices = (Matrix4x4[])(object)new Matrix4x4[binds.Length];
		clearanceMatrices = (Matrix4x4[])(object)((clearanceBinds == null) ? null : new Matrix4x4[clearanceBinds.Length]);
		HashSet<int> hashSet = new HashSet<int>();
		foreach (BoneWeight item in weights.Concat((IEnumerable<BoneWeight>)(((object)clearanceWeights) ?? ((object)new BoneWeight[0]))))
		{
			BoneWeight current = item;
			if (((BoneWeight)(ref current)).weight0 > 0f)
			{
				hashSet.Add(((BoneWeight)(ref current)).boneIndex0);
			}
			if (((BoneWeight)(ref current)).weight1 > 0f)
			{
				hashSet.Add(((BoneWeight)(ref current)).boneIndex1);
			}
			if (((BoneWeight)(ref current)).weight2 > 0f)
			{
				hashSet.Add(((BoneWeight)(ref current)).boneIndex2);
			}
			if (((BoneWeight)(ref current)).weight3 > 0f)
			{
				hashSet.Add(((BoneWeight)(ref current)).boneIndex3);
			}
		}
		usedBones = hashSet.ToArray();
		initialized = vertices.Length == 3 && weights.Length == 3;
		if (!initialized)
		{
			((Behaviour)this).enabled = false;
		}
		return initialized;
	}

	private void UpdateMatrices()
	{
		//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_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: 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)
		int[] array = usedBones;
		foreach (int num in array)
		{
			Matrix4x4 localToWorldMatrix = skinBones[num].localToWorldMatrix;
			skinMatrices[num] = localToWorldMatrix * binds[num];
			if (clearanceMatrices != null)
			{
				clearanceMatrices[num] = localToWorldMatrix * clearanceBinds[num];
			}
		}
	}

	private static Vector3 Skin(Vector3 p, BoneWeight w, Matrix4x4[] matrices)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_0014: 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)
		//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_0039: 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_0056: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		//IL_008a: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0097: Unknown result type (might be due to invalid IL or missing references)
		//IL_009c: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00be: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cb: 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_00d5: Unknown result type (might be due to invalid IL or missing references)
		Vector3 val = Vector3.zero;
		if (((BoneWeight)(ref w)).weight0 > 0f)
		{
			val += ((Matrix4x4)(ref matrices[((BoneWeight)(ref w)).boneIndex0])).MultiplyPoint3x4(p) * ((BoneWeight)(ref w)).weight0;
		}
		if (((BoneWeight)(ref w)).weight1 > 0f)
		{
			val += ((Matrix4x4)(ref matrices[((BoneWeight)(ref w)).boneIndex1])).MultiplyPoint3x4(p) * ((BoneWeight)(ref w)).weight1;
		}
		if (((BoneWeight)(ref w)).weight2 > 0f)
		{
			val += ((Matrix4x4)(ref matrices[((BoneWeight)(ref w)).boneIndex2])).MultiplyPoint3x4(p) * ((BoneWeight)(ref w)).weight2;
		}
		if (((BoneWeight)(ref w)).weight3 > 0f)
		{
			val += ((Matrix4x4)(ref matrices[((BoneWeight)(ref w)).boneIndex3])).MultiplyPoint3x4(p) * ((BoneWeight)(ref w)).weight3;
		}
		return val;
	}

	private Vector3 Point(int i)
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		return Skin(vertices[i], weights[i], skinMatrices);
	}

	private Vector3 ClearancePoint(int i)
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		return Skin(clearanceVertices[i], clearanceWeights[i], clearanceMatrices);
	}

	public void Apply()
	{
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: 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_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: 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_003a: 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_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0071: Unknown result type (might be due to invalid IL or missing references)
		//IL_0078: Unknown result type (might be due to invalid IL or missing references)
		//IL_0079: Unknown result type (might be due to invalid IL or missing references)
		//IL_007b: 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_008b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0090: Unknown result type (might be due to invalid IL or missing references)
		//IL_0095: Unknown result type (might be due to invalid IL or missing references)
		//IL_009a: Unknown result type (might be due to invalid IL or missing references)
		//IL_009c: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_0107: Unknown result type (might be due to invalid IL or missing references)
		//IL_010c: 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_0116: Unknown result type (might be due to invalid IL or missing references)
		//IL_0136: Unknown result type (might be due to invalid IL or missing references)
		//IL_013b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0127: Unknown result type (might be due to invalid IL or missing references)
		//IL_0129: Unknown result type (might be due to invalid IL or missing references)
		//IL_012e: Unknown result type (might be due to invalid IL or missing references)
		//IL_014d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0152: Unknown result type (might be due to invalid IL or missing references)
		//IL_0157: 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_0163: Unknown result type (might be due to invalid IL or missing references)
		//IL_016d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0172: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0188: Unknown result type (might be due to invalid IL or missing references)
		//IL_0192: Unknown result type (might be due to invalid IL or missing references)
		//IL_019a: 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_01a7: 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_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_01c9: 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)
		//IL_01d0: 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_0233: 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_0240: Unknown result type (might be due to invalid IL or missing references)
		//IL_0245: Unknown result type (might be due to invalid IL or missing references)
		if (!initialized && !Initialize())
		{
			return;
		}
		UpdateMatrices();
		Vector3 val = Point(0);
		Vector3 val2 = Point(1) - val;
		Vector3 val3 = Point(2) - val;
		Vector3 val4 = Vector3.Cross(val2, val3);
		if (((Vector3)(ref val4)).sqrMagnitude < 1E-12f || ((Vector3)(ref val3)).sqrMagnitude < 1E-12f)
		{
			return;
		}
		Quaternion val5 = Quaternion.LookRotation(((Vector3)(ref val4)).normalized, ((Vector3)(ref val3)).normalized);
		badge.SetPositionAndRotation(val + val5 * Vector3.Scale(offset, restFrame.lossyScale), val5 * rotation);
		MinimumCardClearance = float.PositiveInfinity;
		ClearancePush = 0f;
		if (clearanceVertices != null && clearanceVertices.Length % 3 == 0 && cardPoints.Length == clearanceVertices.Length && clearanceBary.Length == clearanceVertices.Length)
		{
			Vector3 val6 = ((Vector3)(ref val4)).normalized;
			if (Vector3.Dot(val6, ((Component)this).transform.forward) < 0f)
			{
				val6 = -val6;
			}
			Matrix4x4 localToWorldMatrix = badge.localToWorldMatrix;
			for (int i = 0; i < clearanceVertices.Length; i += 3)
			{
				Vector2 val7 = clearanceBary[i];
				Vector3 val8 = ClearancePoint(i) * val7.x + ClearancePoint(i + 1) * val7.y + ClearancePoint(i + 2) * (1f - val7.x - val7.y);
				MinimumCardClearance = Mathf.Min(MinimumCardClearance, Vector3.Dot(((Matrix4x4)(ref localToWorldMatrix)).MultiplyPoint3x4(cardPoints[i]) - val8, val6));
			}
			float num = 0.0015f * Mathf.Abs(((Component)this).transform.lossyScale.x);
			ClearancePush = Mathf.Max(0f, num - MinimumCardClearance);
			Transform obj = badge;
			obj.position += val6 * ClearancePush;
			MinimumCardClearance += ClearancePush;
		}
	}

	private void LateUpdate()
	{
		Apply();
	}
}
[DefaultExecutionOrder(300)]
public class FlorenceSecondaryMotion : MonoBehaviour
{
	private Transform[] bones;

	private Vector3[] rest;

	private Vector3[] positions;

	private Vector3[] velocities;

	private float limit;

	public float PeakDisplacement { get; private set; }

	private void Start()
	{
		Initialize();
	}

	public void Initialize()
	{
		//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
		if (bones == null)
		{
			bones = (from t in ((Component)this).GetComponentsInChildren<Transform>()
				where ((Object)t).name == "DEF-breast.L" || ((Object)t).name == "DEF-breast.R" || ((Object)t).name == "DEF-ass.L" || ((Object)t).name == "DEF-ass.R"
				select t).ToArray();
			rest = bones.Select((Transform t) => t.localPosition).ToArray();
			positions = bones.Select((Transform t) => t.position).ToArray();
			velocities = (Vector3[])(object)new Vector3[bones.Length];
			SkinnedMeshRenderer val = ((IEnumerable<SkinnedMeshRenderer>)((Component)this).GetComponentsInChildren<SkinnedMeshRenderer>()).FirstOrDefault((Func<SkinnedMeshRenderer, bool>)((SkinnedMeshRenderer r) => ((Object)r).name.Contains("_Body")));
			float num;
			if (!Object.op_Implicit((Object)(object)val))
			{
				num = 1.33f;
			}
			else
			{
				Bounds bounds = ((Renderer)val).bounds;
				num = ((Bounds)(ref bounds)).size.y;
			}
			limit = num * 0.012f;
		}
	}

	private void LateUpdate()
	{
		Step(Time.deltaTime);
	}

	public void Step(float elapsed)
	{
		//IL_0056: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		//IL_0061: 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_0081: Unknown result type (might be due to invalid IL or missing references)
		//IL_0082: Unknown result type (might be due to invalid IL or missing references)
		//IL_008e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0093: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cd: 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_00da: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e4: 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_00ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_0104: Unknown result type (might be due to invalid IL or missing references)
		//IL_0109: 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_011d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0122: Unknown result type (might be due to invalid IL or missing references)
		//IL_0126: Unknown result type (might be due to invalid IL or missing references)
		//IL_012b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0130: 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_014e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0155: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_017a: 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_0180: Unknown result type (might be due to invalid IL or missing references)
		//IL_018b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0190: 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_019a: Unknown result type (might be due to invalid IL or missing references)
		//IL_019c: 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_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_01d8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d9: 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)
		if (bones == null)
		{
			return;
		}
		float num = Mathf.Min(elapsed, 0.033f);
		if (num <= 0f)
		{
			return;
		}
		for (int i = 0; i < bones.Length; i++)
		{
			Transform val = bones[i];
			if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val.parent))
			{
				Vector3 val2 = val.parent.TransformPoint(rest[i]);
				if (Vector3.Distance(val2, positions[i]) > 1.5f)
				{
					positions[i] = val2;
					velocities[i] = Vector3.zero;
				}
				bool flag = ((Object)val).name.StartsWith("DEF-ass.");
				int num2 = Mathf.Max(1, Mathf.CeilToInt(num / 0.008f));
				float num3 = num / (float)num2;
				for (int j = 0; j < num2; j++)
				{
					Vector3 val3 = (val2 - positions[i]) * 12f * 12f - 14.88f * velocities[i];
					ref Vector3 reference = ref velocities[i];
					reference += val3 * num3;
					ref Vector3 reference2 = ref positions[i];
					reference2 += velocities[i] * num3;
				}
				Vector3 val4 = Vector3.ClampMagnitude(positions[i] - val2, limit);
				positions[i] = val2 + val4;
				Vector3 val5 = val4 * (flag ? 0.85f : 1f);
				PeakDisplacement = Mathf.Max(PeakDisplacement, ((Vector3)(ref val5)).magnitude);
				val.position = val2 + val5;
			}
		}
	}

	private void OnDisable()
	{
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		if (bones == null)
		{
			return;
		}
		for (int i = 0; i < bones.Length; i++)
		{
			if (Object.op_Implicit((Object)(object)bones[i]))
			{
				bones[i].localPosition = rest[i];
			}
		}
	}
}
public sealed class FlorenceSpeechGrin
{
	private float grin;

	private float holdUntil = float.NegativeInfinity;

	public float Update(bool speaking, float now, float deltaTime, float effectWeight)
	{
		if (speaking)
		{
			holdUntil = now + 0.12f;
			grin = 0f;
		}
		else
		{
			grin = Mathf.MoveTowards(grin, (now < holdUntil) ? 0f : Mathf.Clamp01(effectWeight), Mathf.Max(0f, deltaTime) * 6f);
		}
		return grin;
	}

	public void Reset()
	{
		grin = 0f;
		holdUntil = float.NegativeInfinity;
	}
}
[BepInPlugin("local.florence.suits", "GFL2 Florence", "1.0.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class Plugin : BaseUnityPlugin
{
	internal static AssetBundle Bundle;

	internal static ConfigEntry<bool> Eyes;

	internal static ConfigEntry<bool> Mouth;

	internal static ConfigEntry<bool> Blink;

	internal static ConfigEntry<float> VoiceGain;

	internal static ConfigEntry<Key> SmileKey;

	internal static ConfigEntry<Key> PinkKey;

	internal static ConfigEntry<float> SmileStrength;

	internal static readonly Dictionary<ulong, bool> Smiles = new Dictionary<ulong, bool>();

	internal static readonly Dictionary<ulong, bool> PinkEffects = new Dictionary<ulong, bool>();

	private NetworkManager smileManager;

	private float nextSmileBroadcast;

	private bool smileOn;

	private bool pinkOn;

	private const string SmileMessage = "local.florence.suits/smile/v1";

	private Harmony suitHarmony;

	private void Awake()
	{
		//IL_0139: Unknown result type (might be due to invalid IL or missing references)
		//IL_0143: Expected O, but got Unknown
		Eyes = ((BaseUnityPlugin)this).Config.Bind<bool>("Face", "EyeTracking", true, "Eyes follow the player's look direction.");
		Mouth = ((BaseUnityPlugin)this).Config.Bind<bool>("Face", "SpeechMouth", true, "Animate the mouth from transmitted voice amplitude.");
		Blink = ((BaseUnityPlugin)this).Config.Bind<bool>("Face", "Blinking", true, "Periodically blink.");
		VoiceGain = ((BaseUnityPlugin)this).Config.Bind<float>("Face", "VoiceGain", 18f, "Mouth sensitivity; increase if movement is too small.");
		SmileKey = ((BaseUnityPlugin)this).Config.Bind<Key>("Expression", "SmileToggleKey", (Key)101, "Toggle your Florence smile independently of speech.");
		PinkKey = ((BaseUnityPlugin)this).Config.Bind<Key>("Expression", "PinkEyesGrinToggleKey", (Key)102, "Toggle glowing pink eyes and the toothy grin. Starts off.");
		SmileStrength = ((BaseUnityPlugin)this).Config.Bind<float>("Expression", "SmileStrength", 70f, "Smile expression strength, 0 to 100. Smiling starts off.");
		Bundle = FlorenceAssets.Load();
		if (!Object.op_Implicit((Object)(object)Bundle))
		{
			throw new Exception("Florence asset bundle is missing or incompatible.");
		}
		ModelReplacementAPI.RegisterSuitModelReplacement("Florence", typeof(DefaultSuit));
		ModelReplacementAPI.RegisterSuitModelReplacement("Florence Marvelous Yam Pastry", typeof(MarvelousYamPastrySuit));
		suitHarmony = new Harmony("local.florence.suits");
		FlorenceSuitAvailability.Install(suitHarmony);
		FlorenceFootAlignmentPatch.Install(suitHarmony);
		((BaseUnityPlugin)this).Logger.LogInfo((object)"Registered both Florence suits with hair/body physics and animated faces.");
	}

	private void OnDestroy()
	{
		Harmony obj = suitHarmony;
		if (obj != null)
		{
			obj.UnpatchSelf();
		}
	}

	private void Update()
	{
		//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bf: Expected O, but got Unknown
		//IL_0116: 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_0127: 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)
		NetworkManager singleton = NetworkManager.Singleton;
		if (!Object.op_Implicit((Object)(object)singleton) || !singleton.IsListening)
		{
			if (Object.op_Implicit((Object)(object)smileManager))
			{
				CustomMessagingManager customMessagingManager = smileManager.CustomMessagingManager;
				if (customMessagingManager != null)
				{
					customMessagingManager.UnregisterNamedMessageHandler("local.florence.suits/smile/v1");
				}
			}
			smileManager = null;
			Smiles.Clear();
			PinkEffects.Clear();
			smileOn = (pinkOn = false);
			return;
		}
		if ((Object)(object)singleton != (Object)(object)smileManager)
		{
			smileManager = singleton;
			Smiles.Clear();
			PinkEffects.Clear();
			smileOn = (pinkOn = false);
			singleton.CustomMessagingManager.RegisterNamedMessageHandler("local.florence.suits/smile/v1", new HandleNamedMessageDelegate(ReceiveSmile));
		}
		PlayerControllerB val = (Object.op_Implicit((Object)(object)StartOfRound.Instance) ? StartOfRound.Instance.localPlayerController : null);
		if (Object.op_Implicit((Object)(object)val) && val.isPlayerControlled && !val.isPlayerDead && !val.inTerminalMenu && Keyboard.current != null)
		{
			bool flag = false;
			if ((int)SmileKey.Value != 0 && ((ButtonControl)Keyboard.current[SmileKey.Value]).wasPressedThisFrame)
			{
				smileOn = !smileOn;
				flag = true;
			}
			if ((int)PinkKey.Value != 0 && ((ButtonControl)Keyboard.current[PinkKey.Value]).wasPressedThisFrame)
			{
				pinkOn = !pinkOn;
				flag = true;
			}
			if (flag)
			{
				Smiles[singleton.LocalClientId] = smileOn;
				PinkEffects[singleton.LocalClientId] = pinkOn;
				SendExpression(singleton.LocalClientId, smileOn, pinkOn);
				nextSmileBroadcast = Time.unscaledTime + 3f;
			}
		}
		if (Time.unscaledTime >= nextSmileBroadcast)
		{
			nextSmileBroadcast = Time.unscaledTime + 3f;
			if (smileOn || pinkOn)
			{
				SendExpression(singleton.LocalClientId, smileOn, pinkOn);
			}
		}
	}

	private unsafe void SendExpression(ulong owner, bool smile, bool pink)
	{
		//IL_002c: 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_004f: 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: 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_00e1: 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)
		if (!Object.op_Implicit((Object)(object)smileManager) || !smileManager.IsListening)
		{
			return;
		}
		FastBufferWriter val = default(FastBufferWriter);
		((FastBufferWriter)(ref val))..ctor(10, (Allocator)2, -1);
		try
		{
			((FastBufferWriter)(ref val)).WriteValueSafe<ulong>(ref owner, default(ForPrimitives));
			byte b = (byte)((smile ? 1 : 0) | (pink ? 2 : 0));
			((FastBufferWriter)(ref val)).WriteValueSafe<byte>(ref b, default(ForPrimitives));
			b = 2;
			((FastBufferWriter)(ref val)).WriteValueSafe<byte>(ref b, default(ForPrimitives));
			if (smileManager.IsServer)
			{
				ulong[] array = smileManager.ConnectedClientsIds.Where((ulong id) => id != 0).ToArray();
				if (array.Length != 0)
				{
					smileManager.CustomMessagingManager.SendNamedMessage("local.florence.suits/smile/v1", (IReadOnlyList<ulong>)array, val, (NetworkDelivery)3);
				}
			}
			else
			{
				smileManager.CustomMessagingManager.SendNamedMessage("local.florence.suits/smile/v1", 0uL, val, (NetworkDelivery)3);
			}
		}
		finally
		{
			((IDisposable)(*(FastBufferWriter*)(&val))/*cast due to .constrained prefix*/).Dispose();
		}
	}

	private void ReceiveSmile(ulong sender, FastBufferReader reader)
	{
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: 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_0037: 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_0049: Unknown result type (might be due to invalid IL or missing references)
		if (!((FastBufferReader)(ref reader)).TryBeginRead(10) || !Object.op_Implicit((Object)(object)smileManager))
		{
			return;
		}
		ulong num = default(ulong);
		((FastBufferReader)(ref reader)).ReadValueSafe<ulong>(ref num, default(ForPrimitives));
		byte b = default(byte);
		((FastBufferReader)(ref reader)).ReadValueSafe<byte>(ref b, default(ForPrimitives));
		byte b2 = default(byte);
		((FastBufferReader)(ref reader)).ReadValueSafe<byte>(ref b2, default(ForPrimitives));
		if (b2 != 2 || b > 3)
		{
			return;
		}
		if (smileManager.IsServer)
		{
			if (sender != 0L && num == sender)
			{
				Smiles[num] = (b & 1) != 0;
				PinkEffects[num] = (b & 2) != 0;
				SendExpression(num, (b & 1) != 0, (b & 2) != 0);
			}
		}
		else if (sender == 0L)
		{
			Smiles[num] = (b & 1) != 0;
			PinkEffects[num] = (b & 2) != 0;
		}
	}
}
public static class FlorenceExpression
{
	private static readonly int Glow = Shader.PropertyToID("_FlorencePinkGlow");

	public static void Apply(SkinnedMeshRenderer face, float amount)
	{
		Apply(face, amount, amount);
	}

	public static void Apply(SkinnedMeshRenderer face, float amount, float grin)
	{
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0065: Expected O, but got Unknown
		amount = Mathf.Clamp01(amount);
		grin = Mathf.Clamp01(grin);
		Set(face, "mouth_teeth_smile", grin * 100f);
		Set(face, "mouth_happy", grin * -20f);
		Set(face, "eyes_serious", amount * 35f);
		Set(face, "eyes_lower_lid_up", amount * 20f);
		Material[] sharedMaterials = ((Renderer)face).sharedMaterials;
		MaterialPropertyBlock val = new MaterialPropertyBlock();
		for (int i = 0; i < sharedMaterials.Length; i++)
		{
			if (Object.op_Implicit((Object)(object)sharedMaterials[i]) && sharedMaterials[i].HasProperty("_FlorenceEyeMode") && sharedMaterials[i].GetFloat("_FlorenceEyeMode") > 0.5f)
			{
				((Renderer)face).GetPropertyBlock(val, i);
				val.SetFloat(Glow, amount);
				((Renderer)face).SetPropertyBlock(val, i);
				val.Clear();
			}
		}
	}

	private static void Set(SkinnedMeshRenderer face, string name, float amount)
	{
		int blendShapeIndex = face.sharedMesh.GetBlendShapeIndex(name);
		if (blendShapeIndex >= 0)
		{
			face.SetBlendShapeWeight(blendShapeIndex, amount);
		}
	}
}
public abstract class FlorenceBody : BodyReplacementBase
{
	protected abstract string AssetName { get; }

	protected override GameObject LoadAssetsAndReturnModel()
	{
		return Plugin.Bundle.LoadAsset<GameObject>(AssetName);
	}

	protected override void AddModelScripts()
	{
		base.replacementModel.AddComponent<FlorenceFace>().Player = ((BodyReplacementBase)this).controller;
		base.replacementModel.AddComponent<FlorenceSecondaryMotion>();
		if (AssetName == "Florence_Default")
		{
			base.replacementModel.AddComponent<FlorenceChestCorrectives>();
			base.replacementModel.AddComponent<FlorenceRigidBadge>();
		}
	}
}
public class DefaultSuit : FlorenceBody
{
	protected override string AssetName => "Florence_Default";
}
public class MarvelousYamPastrySuit : FlorenceBody
{
	protected override string AssetName => "Florence_YamPastry";
}
[DefaultExecutionOrder(250)]
public class FlorenceFace : MonoBehaviour
{
	public PlayerControllerB Player;

	private SkinnedMeshRenderer face;

	private Transform head;

	private float openness;

	private float x;

	private float y;

	private float nextBlink;

	private float blinkStarted = -10f;

	private int mouth = -1;

	private int round = -1;

	private int smile = -1;

	private int up = -1;

	private int down = -1;

	private int left = -1;

	private int right = -1;

	private int blink = -1;

	private float smileWeight;

	private float pinkWeight;

	private object voice;

	private object comms;

	private float nextResolve;

	private readonly FlorenceSpeechGrin speechGrin = new FlorenceSpeechGrin();

	private const BindingFlags Flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;

	private static object Read(object o, string name)
	{
		if (o == null)
		{
			return null;
		}
		Type type = o.GetType();
		object obj = type.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(o);
		if (obj == null)
		{
			PropertyInfo? property = type.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if ((object)property == null)
			{
				return null;
			}
			obj = property.GetValue(o, null);
		}
		return obj;
	}

	private int Key(string name)
	{
		for (int i = 0; i < face.sharedMesh.blendShapeCount; i++)
		{
			string blendShapeName = face.sharedMesh.GetBlendShapeName(i);
			if (blendShapeName == name || blendShapeName.EndsWith("." + name) || blendShapeName.EndsWith("_" + name))
			{
				return i;
			}
		}
		return -1;
	}

	private void Start()
	{
		face = ((IEnumerable<SkinnedMeshRenderer>)((Component)this).GetComponentsInChildren<SkinnedMeshRenderer>()).FirstOrDefault((Func<SkinnedMeshRenderer, bool>)((SkinnedMeshRenderer r) => Object.op_Implicit((Object)(object)r.sharedMesh) && r.sharedMesh.blendShapeCount > 0 && (((Object)r).name.StartsWith("Face") || ((Object)r).name.Contains("_Face"))));
		if (!Object.op_Implicit((Object)(object)face))
		{
			((Behaviour)this).enabled = false;
			return;
		}
		head = ((IEnumerable<Transform>)((Component)this).GetComponentsInChildren<Transform>()).FirstOrDefault((Func<Transform, bool>)((Transform t) => ((Object)t).name == "DEF-spine.006"));
		mouth = Key("speech_open");
		round = Key("speech_round");
		smile = Key("mouth_smile");
		up = Key("eyes_look_up");
		down = Key("eyes_look_down");
		left = Key("eyes_look_left");
		right = Key("eyes_look_right");
		blink = Key("blink");
		nextBlink = Time.time + Random.Range(2f, 5f);
	}

	private void OnDisable()
	{
		speechGrin.Reset();
		if (Object.op_Implicit((Object)(object)face))
		{
			Weight(mouth, 0f);
			Weight(round, 0f);
			Weight(smile, 0f);
			FlorenceExpression.Apply(face, 0f);
		}
	}

	private void ResolveVoice()
	{
		voice = Read(Player, "voicePlayerState");
		if (voice != null)
		{
			return;
		}
		Type type = (from a in AppDomain.CurrentDomain.GetAssemblies()
			select a.GetType("Dissonance.DissonanceComms", throwOnError: false)).FirstOrDefault((Type t) => t != null);
		if (type == null)
		{
			return;
		}
		if (comms == null)
		{
			comms = Object.FindObjectOfType(type);
		}
		if (comms != null)
		{
			string text = Read(Player, "voicePlayerName") as string;
			if (((NetworkBehaviour)Player).IsOwner)
			{
				text = Read(comms, "LocalPlayerName") as string;
			}
			if (!string.IsNullOrEmpty(text))
			{
				voice = type.GetMethod("FindPlayer", new Type[1] { typeof(string) })?.Invoke(comms, new object[1] { text });
			}
		}
	}

	private void Weight(int key, float weight)
	{
		if (key >= 0)
		{
			face.SetBlendShapeWeight(key, Mathf.Clamp(weight, 0f, 100f));
		}
	}

	private void LateUpdate()
	{
		//IL_0316: Unknown result type (might be due to invalid IL or missing references)
		//IL_0321: Unknown result type (might be due to invalid IL or missing references)
		//IL_0352: Unknown result type (might be due to invalid IL or missing references)
		//IL_035d: Unknown result type (might be due to invalid IL or missing references)
		if (!Object.op_Implicit((Object)(object)Player) || !Object.op_Implicit((Object)(object)face))
		{
			return;
		}
		float num = 0f;
		bool flag = false;
		if (Plugin.Mouth.Value && !Player.isPlayerDead)
		{
			if (Time.time >= nextResolve)
			{
				ResolveVoice();
				nextResolve = Time.time + 1f;
			}
			bool flag2 = default(bool);
			int num2;
			if (voice != null)
			{
				object obj = Read(voice, "IsSpeaking");
				if (obj is bool)
				{
					flag2 = (bool)obj;
					num2 = 1;
				}
				else
				{
					num2 = 0;
				}
			}
			else
			{
				num2 = 0;
			}
			flag = (byte)((uint)num2 & (flag2 ? 1u : 0u)) != 0;
			if (flag && Read(voice, "Amplitude") is float num3)
			{
				num = Mathf.Clamp01(num3 * Plugin.VoiceGain.Value);
			}
		}
		openness = Mathf.Lerp(openness, num, 1f - Mathf.Exp((0f - Time.deltaTime) * ((num > openness) ? 24f : 12f)));
		float num4 = 1f - Mathf.SmoothStep(0f, 1f, Mathf.InverseLerp(0.15f, 0.75f, openness));
		bool value;
		bool flag3 = Plugin.PinkEffects.TryGetValue(((NetworkBehaviour)Player).OwnerClientId, out value) && value && !Player.isPlayerDead;
		pinkWeight = Mathf.MoveTowards(pinkWeight, (float)(flag3 ? 1 : 0), Time.deltaTime * 6f);
		float num5 = speechGrin.Update(flag, Time.time, Time.deltaTime, pinkWeight);
		Weight(mouth, (1f - num5) * openness * (1f - num4) * 85f);
		Weight(round, (1f - num5) * openness * num4 * 85f);
		bool value2;
		bool flag4 = Plugin.Smiles.TryGetValue(((NetworkBehaviour)Player).OwnerClientId, out value2) && value2 && !Player.isPlayerDead;
		smileWeight = Mathf.Lerp(smileWeight, flag4 ? Mathf.Clamp(Plugin.SmileStrength.Value, 0f, 100f) : 0f, 1f - Mathf.Exp((0f - Time.deltaTime) * 10f));
		Weight(smile, (1f - pinkWeight) * smileWeight * (1f - 0.65f * openness));
		FlorenceExpression.Apply(face, pinkWeight, num5);
		float num6 = 0f;
		float num7 = 0f;
		if (Plugin.Eyes.Value && Object.op_Implicit((Object)(object)head) && Object.op_Implicit((Object)(object)Player.gameplayCamera) && !Player.isPlayerDead)
		{
			num6 = Mathf.Clamp(Vector3.Dot(((Component)Player.gameplayCamera).transform.forward, ((Component)this).transform.right) * 2f, -1f, 1f);
			num7 = Mathf.Clamp(Vector3.Dot(((Component)Player.gameplayCamera).transform.forward, ((Component)this).transform.up) * 2f, -1f, 1f);
		}
		x = Mathf.Lerp(x, num6, 1f - Mathf.Exp((0f - Time.deltaTime) * 12f));
		y = Mathf.Lerp(y, num7, 1f - Mathf.Exp((0f - Time.deltaTime) * 12f));
		Weight(left, Mathf.Max(0f, 0f - x) * 70f);
		Weight(right, Mathf.Max(0f, x) * 70f);
		Weight(up, Mathf.Max(0f, y) * 70f);
		Weight(down, Mathf.Max(0f, 0f - y) * 70f);
		if (Time.time >= nextBlink)
		{
			blinkStarted = Time.time;
			nextBlink = Time.time + Random.Range(2.5f, 6f);
		}
		float num8 = Time.time - blinkStarted;
		Weight(blink, (Plugin.Blink.Value && num8 < 0.18f) ? (Mathf.Sin(num8 / 0.18f * (float)Math.PI) * 100f) : 0f);
	}
}
public static class FlorenceSuitAvailability
{
	public static readonly string[] Names = new string[2] { "Florence", "Florence Marvelous Yam Pastry" };

	public static void Install(Harmony harmony)
	{
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_0016: Expected O, but got Unknown
		HarmonyMethod val = new HarmonyMethod(typeof(FlorenceSuitAvailability), "BeforeStart", (Type[])null);
		val.priority = 200;
		val.after = new string[1] { "x753.More_Suits" };
		val.before = new string[3] { "com.github.darmuh.suitsTerminal", "darmuh.suitsTerminal", "TooManySuits" };
		HarmonyMethod val2 = val;
		harmony.Patch((MethodBase)AccessTools.Method(typeof(StartOfRound), "Start", (Type[])null, (Type[])null), val2, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
	}

	private static void BeforeStart(StartOfRound __instance)
	{
		try
		{
			Debug.Log((object)("[GFL2 Florence] Suit list ready: two Florence suits available; added " + Ensure(__instance.unlockablesList.unlockables) + " missing variants."));
		}
		catch (Exception ex)
		{
			Debug.LogError((object)("[GFL2 Florence] Could not add suits to the game list: " + ex));
		}
	}

	public static int Ensure(List<UnlockableItem> suits)
	{
		//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00be: 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)
		//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fd: Expected O, but got Unknown
		//IL_0107: 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_0110: Unknown result type (might be due to invalid IL or missing references)
		//IL_0112: Unknown result type (might be due to invalid IL or missing references)
		//IL_0119: Unknown result type (might be due to invalid IL or missing references)
		//IL_011b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0122: Unknown result type (might be due to invalid IL or missing references)
		//IL_0124: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0156: Unknown result type (might be due to invalid IL or missing references)
		//IL_0163: Expected O, but got Unknown
		//IL_0186: Unknown result type (might be due to invalid IL or missing references)
		//IL_018b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0192: Unknown result type (might be due to invalid IL or missing references)
		//IL_0197: Unknown result type (might be due to invalid IL or missing references)
		if (suits == null)
		{
			throw new ArgumentNullException("suits");
		}
		string[] array = Names.Where((string name) => !suits.Any((UnlockableItem s) => s != null && string.Equals(s.unlockableName, name, StringComparison.OrdinalIgnoreCase))).ToArray();
		if (array.Length == 0)
		{
			return 0;
		}
		UnlockableItem val = ((IEnumerable<UnlockableItem>)suits).FirstOrDefault((Func<UnlockableItem, bool>)((UnlockableItem s) => s != null && (Object)(object)s.suitMaterial != (Object)null && s.alreadyUnlocked && s.unlockableType != 753));
		if (val == null)
		{
			throw new InvalidOperationException("The default unlocked suit material is unavailable.");
		}
		string text = JsonUtility.ToJson((object)val);
		string[] array2 = array;
		foreach (string text2 in array2)
		{
			UnlockableItem val2 = JsonUtility.FromJson<UnlockableItem>(text);
			Color val3 = (text2.Contains("Yam Pastry") ? new Color(0.42f, 0.8f, 0.9f, 1f) : new Color(0.35f, 0.7f, 0.82f, 1f));
			Texture2D val4 = new Texture2D(2, 2, (TextureFormat)4, false)
			{
				name = text2 + " suit texture"
			};
			val4.SetPixels((Color[])(object)new Color[4] { val3, val3, val3, val3 });
			val4.Apply(false, true);
			val2.suitMaterial = new Material(val.suitMaterial)
			{
				name = text2 + " suit material",
				mainTexture = (Texture)(object)val4
			};
			val2.unlockableName = text2;
			val2.alreadyUnlocked = true;
			val2.hasBeenUnlockedByPlayer = true;
			val2.hasBeenMoved = false;
			val2.placedPosition = Vector3.zero;
			val2.placedRotation = Vector3.zero;
			int num2 = suits.FindIndex((UnlockableItem s) => s != null && s.unlockableType == 753);
			if (num2 >= 0)
			{
				suits[num2] = val2;
			}
			else
			{
				suits.Add(val2);
			}
		}
		return array.Length;
	}
}