Decompiled source of GangBeastsFaces v1.0.0

Mods/GangBeastsFaces.dll

Decompiled 2 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using GBFaces;
using MelonLoader;
using MelonLoader.Preferences;
using UnityEngine;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(FaceMod), "Gang Beasts Faces", "2.0.0", "xksunix", null)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: RefSafetyRules(11)]
namespace GBFaces;

internal class FaceController
{
	internal struct Pose
	{
		public float open;

		public float smile;

		public float angry;

		public float raiseL;

		public float raiseR;

		public float wide;

		public float pucker;

		public float skew;

		public float tongue;

		public float wob;

		public float rate;
	}

	private const int LipSegments = 13;

	private const int BrowSegments = 7;

	private static bool dumped;

	private static Shader cachedShader;

	private static bool shaderSearched;

	public Component Actor;

	public Transform Head;

	public float Laugh;

	private GameObject root;

	private Transform mouth;

	private Transform tongue;

	private Transform teeth;

	private Renderer mouthR;

	private Renderer tongueR;

	private Renderer teethR;

	private readonly Transform[] lipU = (Transform[])(object)new Transform[13];

	private readonly Transform[] lipL = (Transform[])(object)new Transform[13];

	private readonly Renderer[] lipLR = (Renderer[])(object)new Renderer[13];

	private readonly Transform[] browLT = (Transform[])(object)new Transform[7];

	private readonly Transform[] browRT = (Transform[])(object)new Transform[7];

	private float headDiameter = 0.4f;

	private Rigidbody rbL;

	private Rigidbody rbR;

	private Rigidbody rbChest;

	private readonly List<AudioSource> voices = new List<AudioSource>();

	private float punchHold;

	private float hurtHold;

	private Vector3 prevVel;

	private bool hasPrevVel;

	private float seed;

	private string lastState = "";

	private static int stateLogCount;

	private static int hurtLogCount;

	private float open;

	private float smile;

	private float angry;

	private float raiseL;

	private float raiseR;

	private float wide;

	private float pucker;

	private float time;

	private bool wasKnocked;

	private float skew;

	private float tongueOut;

	private float wob;

	private float idleLeft;

	private float idleWait = 2f;

	private float idleT;

	private int idleKind;

	public int Emote = -1;

	public float EmoteLeft;

	private float emoteT;

	private float hurtPower;

	private float sinceLanding = 9f;

	private float airTime;

	private int fitVer = -1;

	private bool hasMap;

	private float[,] hmap;

	private const int HN = 46;

	private const float HCell = 0.04f;

	private float fitCx;

	private float fitCy = 0.41f;

	private float fitCz = 0.05f;

	private float fitR = 0.5f;

	private float mapX0;

	private float mapY0;

	private static int fitLogCount;

	private MemberInfo stateMember;

	private readonly List<MemberInfo> angerFlags = new List<MemberInfo>();

	private readonly List<MemberInfo> strainFlags = new List<MemberInfo>();

	private readonly bool hasActorLogic;

	private static bool membersLogged;

	private static bool audioLogged;

	internal static readonly string[] EmoteNames = new string[16]
	{
		"Grin", "Laugh", "Sad", "Angry", "Surprised", "Kiss", "Tongue out", "Smirk", "Yawn", "Scream",
		"Whistle", "Dizzy", "Evil grin", "Chew", "Wink", "Sob"
	};

	private static readonly int[] IdleSet = new int[9] { 0, 7, 8, 10, 13, 14, 6, 4, 5 };

	private bool visible = true;

	private FaceController(Component actor, Transform head, bool hasActorLogic)
	{
		Actor = actor;
		Head = head;
		this.hasActorLogic = hasActorLogic;
		seed = Random.value * 100f;
		idleWait = 1.5f + Random.value * 3f;
	}

	public static FaceController Create(Component actor, bool isActor, Instance log)
	{
		Transform val = (isActor ? FindHead(actor.transform) : actor.transform);
		if ((Object)(object)val == (Object)null)
		{
			log.Warning("Postac '" + ((Object)actor).name + "' - nie znaleziono kosci glowy (szukam nazwy z 'head').");
			if (!dumped)
			{
				dumped = true;
				Dump(actor.transform, log);
			}
			return null;
		}
		FaceController faceController = new FaceController(actor, val, isActor);
		try
		{
			faceController.Build();
		}
		catch (Exception ex)
		{
			log.Error("Nie udalo sie zbudowac twarzy: " + ex);
			try
			{
				faceController.Destroy();
			}
			catch
			{
			}
			return null;
		}
		try
		{
			faceController.Measure(log);
		}
		catch (Exception ex2)
		{
			log.Warning("Pomiar glowy/rak nie powiodl sie: " + ex2.Message);
		}
		if (isActor)
		{
			try
			{
				faceController.Reflect(log);
			}
			catch (Exception ex3)
			{
				log.Warning("Nie udalo sie odczytac stanu postaci (twarz bedzie statyczna): " + ex3.Message);
			}
		}
		log.Msg("Dodano twarz: " + ((Object)actor).name + " -> " + Path(val));
		if (!dumped)
		{
			dumped = true;
			Dump(val, log);
		}
		return faceController;
	}

	private void Build()
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Expected O, but got Unknown
		//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bc: 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_0108: 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_016e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0193: Unknown result type (might be due to invalid IL or missing references)
		root = new GameObject("GBFace");
		root.transform.SetParent(Head, false);
		root.layer = ((Component)Head).gameObject.layer;
		Color color = default(Color);
		((Color)(ref color))..ctor(0.2f, 0.015f, 0.04f);
		Color color2 = default(Color);
		((Color)(ref color2))..ctor(0.02f, 0.02f, 0.02f);
		Color color3 = default(Color);
		((Color)(ref color3))..ctor(0.97f, 0.96f, 0.9f);
		Color color4 = default(Color);
		((Color)(ref color4))..ctor(0.86f, 0.28f, 0.36f);
		mouth = Prim("Mouth", (PrimitiveType)0, color, 0, out mouthR);
		tongue = Prim("Tongue", (PrimitiveType)0, color4, 1, out tongueR);
		teeth = Prim("Teeth", (PrimitiveType)3, color3, 2, out teethR);
		Renderer rend;
		for (int i = 0; i < 13; i++)
		{
			lipU[i] = Prim("LipU" + i, (PrimitiveType)0, color2, 3, out rend);
			lipL[i] = Prim("LipL" + i, (PrimitiveType)0, color2, 3, out lipLR[i]);
		}
		for (int j = 0; j < 7; j++)
		{
			browLT[j] = Prim("BrowL" + j, (PrimitiveType)0, color2, 3, out rend);
			browRT[j] = Prim("BrowR" + j, (PrimitiveType)0, color2, 3, out rend);
		}
	}

	private Transform Prim(string name, PrimitiveType type, Color color, int order, out Renderer rend)
	{
		//IL_0000: 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)
		GameObject val = GameObject.CreatePrimitive(type);
		((Object)val).name = name;
		Collider component = val.GetComponent<Collider>();
		if ((Object)(object)component != (Object)null)
		{
			Object.DestroyImmediate((Object)(object)component);
		}
		val.transform.SetParent(root.transform, false);
		val.layer = root.layer;
		Renderer val2 = (rend = val.GetComponent<Renderer>());
		if ((Object)(object)val2 != (Object)null)
		{
			val2.shadowCastingMode = (ShadowCastingMode)0;
			val2.receiveShadows = false;
			try
			{
				val2.sortingOrder = order;
			}
			catch
			{
			}
			Colorize(val2, color);
		}
		return val.transform;
	}

	private static void Colorize(Renderer r, Color c)
	{
		//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_009e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a4: Expected O, but got Unknown
		//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
		if (!shaderSearched)
		{
			shaderSearched = true;
			string[] array = new string[4] { "Unlit/Color", "Sprites/Default", "Standard", "Legacy Shaders/Diffuse" };
			for (int i = 0; i < array.Length; i++)
			{
				Shader val = Shader.Find(array[i]);
				if ((Object)(object)val != (Object)null)
				{
					cachedShader = val;
					break;
				}
			}
			MelonLogger.Msg("[Faces] shader twarzy: " + (((Object)(object)cachedShader != (Object)null) ? ((Object)cachedShader).name : "(zaden nie znaleziony - uzywam domyslnego materialu)"));
		}
		if ((Object)(object)cachedShader != (Object)null)
		{
			Material val2 = new Material(cachedShader);
			val2.color = c;
			r.sharedMaterial = val2;
		}
		else
		{
			Material val2 = r.material;
			val2.color = c;
		}
	}

	private static Transform FindByName(Transform start, string name)
	{
		Queue<Transform> queue = new Queue<Transform>();
		queue.Enqueue(start);
		while (queue.Count > 0)
		{
			Transform val = queue.Dequeue();
			if (((Object)val).name == name)
			{
				return val;
			}
			for (int i = 0; i < val.childCount; i++)
			{
				queue.Enqueue(val.GetChild(i));
			}
		}
		return null;
	}

	private void Measure(Instance log)
	{
		//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_001f: 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_002d: 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)
		Collider component = ((Component)Head).GetComponent<Collider>();
		if ((Object)(object)component != (Object)null)
		{
			Bounds bounds = component.bounds;
			Vector3 size = ((Bounds)(ref bounds)).size;
			float num = Mathf.Max(size.x, Mathf.Max(size.y, size.z));
			if (num > 0.05f && num < 3f)
			{
				headDiameter = num;
			}
		}
		if (hasActorLogic)
		{
			Transform transform = Actor.transform;
			Transform val = FindByName(transform, "actor_chest_collider");
			Transform val2 = FindByName(transform, "actor_leftHand_collider");
			Transform val3 = FindByName(transform, "actor_rightHand_collider");
			if ((Object)(object)val != (Object)null)
			{
				rbChest = ((Component)val).GetComponent<Rigidbody>();
			}
			if ((Object)(object)val2 != (Object)null)
			{
				rbL = ((Component)val2).GetComponent<Rigidbody>();
			}
			if ((Object)(object)val3 != (Object)null)
			{
				rbR = ((Component)val3).GetComponent<Rigidbody>();
			}
			log.Msg("Srednica glowy: " + headDiameter.ToString("0.00") + ", rece: " + (((Object)(object)rbL != (Object)null && (Object)(object)rbR != (Object)null) ? "ok" : "brak") + ", klatka: " + (((Object)(object)rbChest != (Object)null) ? "ok" : "brak"));
			FindVoices(transform, log);
			if (FaceMod.AutoFwd < 0 && !FaceMod.PManual.Value)
			{
				Calibrate(transform, log);
			}
		}
	}

	private void FindVoices(Transform top, Instance log)
	{
		try
		{
			Queue<Transform> queue = new Queue<Transform>();
			queue.Enqueue(top);
			int num = 0;
			while (queue.Count > 0 && num < 200)
			{
				Transform val = queue.Dequeue();
				num++;
				if (((Object)val).name.ToLowerInvariant().Contains("voice"))
				{
					AudioSource component = ((Component)val).GetComponent<AudioSource>();
					if ((Object)(object)component != (Object)null)
					{
						voices.Add(component);
					}
				}
				for (int i = 0; i < val.childCount; i++)
				{
					queue.Enqueue(val.GetChild(i));
				}
			}
			log.Msg("Zrodla glosu (AudioSource): " + voices.Count);
			if (audioLogged)
			{
				return;
			}
			audioLogged = true;
			List<string> list = new List<string>();
			Queue<Transform> queue2 = new Queue<Transform>();
			queue2.Enqueue(top);
			int num2 = 0;
			while (queue2.Count > 0 && num2++ < 300)
			{
				Transform val2 = queue2.Dequeue();
				if ((Object)(object)((Component)val2).GetComponent<AudioSource>() != (Object)null)
				{
					list.Add(((Object)val2).name);
				}
				for (int j = 0; j < val2.childCount; j++)
				{
					queue2.Enqueue(val2.GetChild(j));
				}
			}
			log.Msg("Wszystkie AudioSource w postaci: " + ((list.Count > 0) ? string.Join(", ", list.ToArray()) : "(brak)"));
		}
		catch (Exception ex)
		{
			log.Warning("Nie udalo sie znalezc zrodel glosu: " + ex.Message);
		}
	}

	private void Calibrate(Transform top, Instance log)
	{
		//IL_004c: 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)
		//IL_0063: Unknown result type (might be due to invalid IL or missing references)
		//IL_0069: Unknown result type (might be due to invalid IL or missing references)
		//IL_006e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a0: 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_00a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a8: 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_00b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0121: 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)
		Transform val = FindByName(top, "actor_leftArm_collider");
		Transform val2 = FindByName(top, "actor_rightArm_collider");
		Transform val3 = FindByName(top, "actor_hips_collider");
		if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null || (Object)(object)val3 == (Object)null)
		{
			log.Warning("Auto-orientacja: nie znaleziono kosci ramion/bioder.");
			return;
		}
		Vector3 val4 = val2.position - val.position;
		Vector3 val5 = Head.position - val3.position;
		if (((Vector3)(ref val4)).magnitude < 0.01f || ((Vector3)(ref val5)).magnitude < 0.01f)
		{
			return;
		}
		((Vector3)(ref val4)).Normalize();
		((Vector3)(ref val5)).Normalize();
		Vector3 val6 = Vector3.Cross(val4, val5);
		Vector3 normalized = ((Vector3)(ref val6)).normalized;
		int num = 0;
		float num2 = -2f;
		for (int i = 0; i < 6; i++)
		{
			float num3 = Vector3.Dot(Head.TransformDirection(FaceMod.Axes[i]), normalized);
			if (num3 > num2)
			{
				num2 = num3;
				num = i;
			}
		}
		int autoUp = 0;
		float num4 = -2f;
		for (int j = 0; j < 6; j++)
		{
			if (j / 2 != num / 2)
			{
				float num5 = Vector3.Dot(Head.TransformDirection(FaceMod.Axes[j]), val5);
				if (num5 > num4)
				{
					num4 = num5;
					autoUp = j;
				}
			}
		}
		FaceMod.AutoFwd = num;
		FaceMod.AutoUp = autoUp;
		log.Msg("Auto-orientacja twarzy: przod=" + num + " (zgodnosc " + num2.ToString("0.00") + "), gora=" + autoUp + " (zgodnosc " + num4.ToString("0.00") + "). Jesli twarz jest z tylu glowy, nacisnij F6.");
	}

	private void Reflect(Instance log)
	{
		Type type = ((object)Actor).GetType();
		List<string> list = new List<string>();
		FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
		foreach (FieldInfo fieldInfo in fields)
		{
			if (string.Equals(fieldInfo.Name, "actorState", StringComparison.OrdinalIgnoreCase))
			{
				stateMember = fieldInfo;
			}
		}
		PropertyInfo[] properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
		foreach (PropertyInfo propertyInfo in properties)
		{
			if (stateMember == null && propertyInfo.CanRead && propertyInfo.GetIndexParameters().Length == 0 && string.Equals(propertyInfo.Name, "actorState", StringComparison.OrdinalIgnoreCase))
			{
				stateMember = propertyInfo;
			}
		}
		if (stateMember == null)
		{
			properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (PropertyInfo propertyInfo2 in properties)
			{
				if (propertyInfo2.CanRead && propertyInfo2.GetIndexParameters().Length == 0 && propertyInfo2.PropertyType.IsEnum && propertyInfo2.Name.ToLowerInvariant().Contains("state"))
				{
					stateMember = propertyInfo2;
					break;
				}
			}
		}
		if (stateMember == null)
		{
			fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (FieldInfo fieldInfo2 in fields)
			{
				if (fieldInfo2.FieldType.IsEnum && fieldInfo2.Name.ToLowerInvariant().Contains("state"))
				{
					stateMember = fieldInfo2;
					break;
				}
			}
		}
		fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
		foreach (FieldInfo fieldInfo3 in fields)
		{
			if (fieldInfo3.FieldType == typeof(bool))
			{
				ClassifyFlag(fieldInfo3, fieldInfo3.Name);
				list.Add(fieldInfo3.Name);
			}
		}
		properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
		foreach (PropertyInfo propertyInfo3 in properties)
		{
			if (propertyInfo3.PropertyType == typeof(bool) && propertyInfo3.CanRead && propertyInfo3.GetIndexParameters().Length == 0)
			{
				ClassifyFlag(propertyInfo3, propertyInfo3.Name);
				list.Add(propertyInfo3.Name);
			}
		}
		log.Msg("Stan postaci: " + ((stateMember != null) ? stateMember.Name : "(nie znaleziono)") + ", flagi gniewu: " + angerFlags.Count + ", flagi wysilku: " + strainFlags.Count);
		if (membersLogged)
		{
			return;
		}
		membersLogged = true;
		List<string> list2 = new List<string>();
		properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
		foreach (PropertyInfo propertyInfo4 in properties)
		{
			if (propertyInfo4.PropertyType.IsEnum)
			{
				list2.Add(propertyInfo4.Name + ":" + propertyInfo4.PropertyType.Name);
			}
		}
		log.Msg("Czlonki enum: " + string.Join(", ", list2.ToArray()));
		try
		{
			if (stateMember != null)
			{
				Type type2 = ((stateMember is PropertyInfo) ? ((PropertyInfo)stateMember).PropertyType : ((FieldInfo)stateMember).FieldType);
				log.Msg("Wartosci " + type2.Name + ": " + string.Join(", ", Enum.GetNames(type2)));
			}
			List<string> list3 = new List<string>();
			Type[] types = type.Assembly.GetTypes();
			foreach (Type type3 in types)
			{
				string text = type3.Name.ToLowerInvariant();
				if (text.Contains("punch") || text.Contains("grab") || text.Contains("fight") || text.Contains("attack") || text.Contains("hit") || text.Contains("knock") || text.Contains("damage"))
				{
					list3.Add(type3.Name);
				}
				if (list3.Count >= 40)
				{
					break;
				}
			}
			log.Msg("Typy zwiazane z walka: " + string.Join(", ", list3.ToArray()));
			List<string> list4 = new List<string>();
			properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (PropertyInfo propertyInfo5 in properties)
			{
				if (propertyInfo5.PropertyType.Namespace != null && propertyInfo5.PropertyType.Namespace.Contains("Femur"))
				{
					list4.Add(propertyInfo5.Name + ":" + propertyInfo5.PropertyType.Name);
				}
			}
			if (list4.Count > 60)
			{
				list4.RemoveRange(60, list4.Count - 60);
			}
			log.Msg("Skladniki postaci: " + string.Join(", ", list4.ToArray()));
			DumpMembers(type.Assembly, "Grab", log);
			DumpMembers(type.Assembly, "StatusHandeler", log);
		}
		catch (Exception ex)
		{
			log.Warning("Dodatkowy zrzut typow nie powiodl sie: " + ex.Message);
		}
		if (list.Count > 80)
		{
			list.RemoveRange(80, list.Count - 80);
		}
		log.Msg("Czlonki bool: " + string.Join(", ", list.ToArray()));
	}

	private static void DumpMembers(Assembly asm, string typeName, Instance log)
	{
		try
		{
			Type type = null;
			Type[] types = asm.GetTypes();
			foreach (Type type2 in types)
			{
				if (type2.Name == typeName)
				{
					type = type2;
					break;
				}
			}
			if (type == null)
			{
				log.Msg("Czlonki " + typeName + ": (nie znaleziono typu)");
				return;
			}
			List<string> list = new List<string>();
			FieldInfo[] fields = type.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (FieldInfo fieldInfo in fields)
			{
				list.Add(fieldInfo.Name + ":" + fieldInfo.FieldType.Name);
			}
			PropertyInfo[] properties = type.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (PropertyInfo propertyInfo in properties)
			{
				list.Add(propertyInfo.Name + ":" + propertyInfo.PropertyType.Name);
			}
			if (list.Count > 70)
			{
				list.RemoveRange(70, list.Count - 70);
			}
			log.Msg("Czlonki " + typeName + ": " + string.Join(", ", list.ToArray()));
		}
		catch (Exception ex)
		{
			log.Warning("Zrzut " + typeName + " nie powiodl sie: " + ex.Message);
		}
	}

	private void ClassifyFlag(MemberInfo m, string name)
	{
		string text = name.ToLowerInvariant();
		if (text.Contains("punch") || text.Contains("attack") || text.Contains("fight") || text.Contains("kick"))
		{
			angerFlags.Add(m);
		}
		else if (text.Contains("grab") || text.Contains("hold") || text.Contains("carry") || text.Contains("climb"))
		{
			strainFlags.Add(m);
		}
	}

	private static object Read(MemberInfo m, object o)
	{
		try
		{
			FieldInfo fieldInfo = m as FieldInfo;
			if (fieldInfo != null)
			{
				return fieldInfo.GetValue(o);
			}
			PropertyInfo propertyInfo = m as PropertyInfo;
			if (propertyInfo != null)
			{
				return propertyInfo.GetValue(o, null);
			}
		}
		catch
		{
		}
		return null;
	}

	private static bool AnyTrue(List<MemberInfo> list, object o)
	{
		foreach (MemberInfo item in list)
		{
			object obj = Read(item, o);
			if (obj is bool && (bool)obj)
			{
				return true;
			}
		}
		return false;
	}

	public bool IsAlive()
	{
		if ((Object)(object)Actor != (Object)null && (Object)(object)Head != (Object)null)
		{
			return (Object)(object)root != (Object)null;
		}
		return false;
	}

	public void Destroy()
	{
		if ((Object)(object)root != (Object)null)
		{
			Object.Destroy((Object)(object)root);
		}
	}

	private bool IsTalking()
	{
		for (int i = 0; i < voices.Count; i++)
		{
			try
			{
				AudioSource val = voices[i];
				if ((Object)(object)val != (Object)null && val.isPlaying)
				{
					return true;
				}
			}
			catch
			{
			}
		}
		return false;
	}

	internal static void EmotePose(int id, float t, float tm, float sd, ref Pose p)
	{
		float num = Mathf.Abs(Mathf.Sin(tm * 13f + sd));
		switch (id)
		{
		case 0:
			p.smile = 1f;
			p.wide = 1f;
			p.open = 0.22f;
			p.raiseL = 0.3f;
			p.raiseR = 0.3f;
			break;
		case 1:
			p.open = 0.45f + 0.4f * num;
			p.smile = 1f;
			p.wide = 1f;
			p.raiseL = 0.5f;
			p.raiseR = 0.5f;
			p.rate = 24f;
			break;
		case 2:
			p.smile = -1f;
			p.angry = -1f;
			p.raiseL = 0.2f;
			p.raiseR = 0.2f;
			p.open = 0.06f;
			p.wob = 0.3f;
			break;
		case 3:
			p.open = 0.2f;
			p.smile = -0.9f;
			p.angry = 1f;
			p.rate = 22f;
			break;
		case 4:
			p.pucker = 1f;
			p.open = 0.65f;
			p.raiseL = 1f;
			p.raiseR = 1f;
			p.rate = 26f;
			break;
		case 5:
			p.pucker = 1f;
			p.open = 0.12f;
			p.smile = 0.2f;
			p.raiseL = 0.5f;
			p.raiseR = 0.5f;
			break;
		case 6:
			p.smile = 0.7f;
			p.wide = 0.4f;
			p.open = 0.12f;
			p.tongue = 0.75f + 0.25f * Mathf.Sin(tm * 8f);
			p.raiseL = 0.8f;
			p.raiseR = 0.2f;
			break;
		case 7:
			p.smile = 0.8f;
			p.skew = 1f;
			p.raiseR = 0.9f;
			p.angry = 0.25f;
			break;
		case 8:
		{
			float num2 = Mathf.Sin(Mathf.Clamp(t / 2.5f, 0f, 1f) * 3.14159f);
			p.open = 0.95f * num2;
			p.smile = 0.3f - 0.6f * num2;
			p.angry = -0.4f * num2;
			p.raiseL = 0.6f * num2;
			p.raiseR = 0.6f * num2;
			p.rate = 8f;
			break;
		}
		case 9:
			p.open = 0.95f;
			p.smile = -0.5f;
			p.raiseL = 1f;
			p.raiseR = 1f;
			p.wob = 0.5f;
			p.rate = 30f;
			break;
		case 10:
			p.pucker = 1f;
			p.open = 0.1f + 0.06f * Mathf.Sin(tm * 6f);
			p.raiseL = 0.3f + 0.2f * Mathf.Sin(tm * 3f);
			p.raiseR = p.raiseL;
			break;
		case 11:
			p.open = 0.35f + 0.2f * Mathf.Sin(tm * 3f);
			p.smile = 0.6f * Mathf.Sin(tm * 2.3f);
			p.skew = Mathf.Sin(tm * 1.7f);
			p.raiseL = 0.5f + 0.5f * Mathf.Sin(tm * 2.1f);
			p.raiseR = 0.5f + 0.5f * Mathf.Sin(tm * 2.1f + 3.1f);
			p.tongue = 0.5f;
			p.wob = 0.4f;
			break;
		case 12:
			p.smile = 1f;
			p.wide = 1f;
			p.angry = 1f;
			p.open = 0.15f;
			p.skew = 0.4f;
			break;
		case 13:
			p.open = 0.12f + 0.2f * Mathf.Abs(Mathf.Sin(tm * 7f));
			p.smile = 0.2f;
			p.raiseL = 0.2f;
			p.raiseR = 0.2f;
			p.rate = 20f;
			break;
		case 14:
			p.smile = 0.9f;
			p.skew = -0.5f;
			p.raiseL = -0.8f;
			p.raiseR = 0.6f;
			break;
		case 15:
			p.open = 0.3f + 0.25f * Mathf.Abs(Mathf.Sin(tm * 9f));
			p.smile = -1f;
			p.angry = -1f;
			p.raiseL = 0.4f;
			p.raiseR = 0.4f;
			p.wob = 0.6f;
			p.rate = 18f;
			break;
		}
	}

	public void StartEmote(int id, float seconds)
	{
		Emote = id;
		EmoteLeft = seconds;
		emoteT = 0f;
	}

	public bool Tick(float dt)
	{
		//IL_029c: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_02af: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_02bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_041b: Unknown result type (might be due to invalid IL or missing references)
		//IL_041d: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_0472: Unknown result type (might be due to invalid IL or missing references)
		//IL_0477: Unknown result type (might be due to invalid IL or missing references)
		//IL_0496: Unknown result type (might be due to invalid IL or missing references)
		//IL_049b: Unknown result type (might be due to invalid IL or missing references)
		//IL_049d: Unknown result type (might be due to invalid IL or missing references)
		//IL_04a2: 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_04cd: 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)
		time += dt;
		if (Laugh > 0f)
		{
			Laugh -= dt;
		}
		if (EmoteLeft > 0f)
		{
			EmoteLeft -= dt;
			emoteT += dt;
			if (EmoteLeft <= 0f)
			{
				Emote = -1;
			}
		}
		if (!FaceMod.PEnabled.Value)
		{
			SetVisible(v: false);
			return false;
		}
		SetVisible(v: true);
		if (fitVer != FaceMod.FitVersion)
		{
			fitVer = FaceMod.FitVersion;
			try
			{
				FitHead();
			}
			catch (Exception ex)
			{
				MelonLogger.Msg("[Faces] dopasowanie do glowy nie powiodlo sie: " + ex.Message);
			}
		}
		string text = "";
		if (hasActorLogic && stateMember != null)
		{
			object obj = Read(stateMember, Actor);
			if (obj != null)
			{
				text = obj.ToString().ToLowerInvariant();
			}
		}
		if (text != lastState)
		{
			if (stateLogCount < 30)
			{
				stateLogCount++;
				MelonLogger.Msg("[Faces] stan postaci: '" + lastState + "' -> '" + text + "'");
			}
			bool flag = lastState.Contains("jump") || lastState.Contains("fall");
			bool flag2 = text.Contains("jump") || text.Contains("fall");
			if (flag && !flag2)
			{
				sinceLanding = 0f;
			}
			if (flag2 && !flag)
			{
				airTime = 0f;
			}
			lastState = text;
		}
		sinceLanding += dt;
		bool flag3 = text.Contains("dead");
		bool flag4 = text.Contains("unconscious") || flag3 || text.Contains("knock") || text == "ko";
		bool flag5 = text.Contains("fall") || text.Contains("ragdoll");
		bool flag6 = text.Contains("jump");
		bool flag7 = text.Contains("climb");
		bool flag8 = text.Contains("swim");
		bool flag9 = text.Contains("drive");
		bool flag10 = text.Contains("run");
		if (flag5 || flag6)
		{
			airTime += dt;
		}
		float num = 0f;
		Vector3 val;
		if ((Object)(object)rbChest != (Object)null)
		{
			Vector3 velocity = rbChest.velocity;
			val = new Vector3(velocity.x, 0f, velocity.z);
			num = ((Vector3)(ref val)).magnitude;
			if (hasPrevVel && dt > 0.0005f && !flag4)
			{
				val = velocity - prevVel;
				float num2 = ((Vector3)(ref val)).magnitude / dt;
				float value = FaceMod.PHitThr.Value;
				if (num2 > value)
				{
					float num3 = Mathf.Clamp((num2 - value) / (value * 2f), 0f, 1f);
					bool flag11 = sinceLanding < 0.3f;
					float num4 = (flag11 ? (0.35f + 0.25f * num3) : (0.6f + 0.4f * num3));
					if (hurtHold <= 0f || num4 > hurtPower)
					{
						hurtPower = num4;
					}
					hurtHold = Mathf.Max(hurtHold, (flag11 ? 0.22f : 0.3f) + 0.35f * num3);
					if (hurtLogCount < 12)
					{
						hurtLogCount++;
						MelonLogger.Msg("[Faces] uderzenie/wstrzas: przyspieszenie " + num2.ToString("0") + " (prog " + value.ToString("0") + ")" + (flag11 ? " [ladowanie]" : ""));
					}
				}
			}
			prevVel = velocity;
			hasPrevVel = true;
		}
		if ((Object)(object)rbChest != (Object)null && ((Object)(object)rbL != (Object)null || (Object)(object)rbR != (Object)null) && !flag4 && !flag5 && !flag6)
		{
			Vector3 velocity2 = rbChest.velocity;
			float num5 = 0f;
			if ((Object)(object)rbL != (Object)null)
			{
				float num6 = num5;
				val = rbL.velocity - velocity2;
				num5 = Mathf.Max(num6, ((Vector3)(ref val)).magnitude);
			}
			if ((Object)(object)rbR != (Object)null)
			{
				float num7 = num5;
				val = rbR.velocity - velocity2;
				num5 = Mathf.Max(num7, ((Vector3)(ref val)).magnitude);
			}
			if (num5 > FaceMod.PPunchThr.Value)
			{
				punchHold = 0.5f;
			}
		}
		if (punchHold > 0f)
		{
			punchHold -= dt;
		}
		bool flag12 = hasActorLogic && !flag4 && (AnyTrue(angerFlags, Actor) || punchHold > 0f);
		bool flag13 = hurtHold > 0f && !flag3;
		if (hurtHold > 0f)
		{
			hurtHold -= dt;
		}
		bool flag14 = hasActorLogic && AnyTrue(strainFlags, Actor);
		bool flag15 = IsTalking();
		bool num8 = Emote >= 0;
		if (!(num8 || flag4 || flag13 || flag12 || flag15 || Laugh > 0f || flag6 || flag5 || flag7 || flag8 || flag9 || flag14 || flag10))
		{
			if (idleLeft > 0f)
			{
				idleLeft -= dt;
				idleT += dt;
			}
			else
			{
				idleWait -= dt;
				if (idleWait <= 0f)
				{
					idleKind = IdleSet[Random.Range(0, IdleSet.Length)];
					idleLeft = ((idleKind == 8) ? 2.6f : (0.9f + Random.value * 1.1f));
					idleT = 0f;
					idleWait = 2.5f + Random.value * 4f;
				}
			}
		}
		else
		{
			idleLeft = 0f;
		}
		float num9 = Mathf.PerlinNoise(time * 9f, seed);
		float num10 = 0.5f + 0.5f * Mathf.Sin(time * 1.7f + seed);
		Pose p = new Pose
		{
			rate = 14f,
			smile = 0.3f + 0.1f * num10
		};
		if (num8)
		{
			EmotePose(Emote, emoteT, time, seed, ref p);
		}
		else if (flag3)
		{
			p.open = 0.3f;
			p.smile = -0.6f;
			p.angry = -0.5f;
			p.raiseL = -0.3f;
			p.raiseR = -0.3f;
			p.tongue = 0.9f;
		}
		else if (flag4)
		{
			EmotePose(11, time, time, seed, ref p);
			p.open = Mathf.Max(p.open, 0.45f + 0.1f * Mathf.Sin(time * 2.2f + seed));
		}
		else if (flag13)
		{
			p.open = 0.5f + 0.45f * hurtPower;
			p.smile = -0.8f;
			p.angry = -0.6f;
			p.raiseL = 1f;
			p.raiseR = 1f;
			p.wob = 0.3f * hurtPower;
			p.rate = 30f;
		}
		else if (flag12)
		{
			EmotePose(3, time, time, seed, ref p);
		}
		else if (Laugh > 0f)
		{
			EmotePose(1, time, time, seed, ref p);
		}
		else if (flag15)
		{
			p.open = 0.15f + 0.65f * Mathf.Abs(Mathf.Sin(time * 11f + seed + num9 * 4f));
			p.smile = 0.15f;
			p.raiseL = 0.2f + 0.4f * num9;
			p.raiseR = p.raiseL;
			p.rate = 26f;
		}
		else if (flag5)
		{
			if (airTime < 0.25f)
			{
				EmotePose(4, time, time, seed, ref p);
			}
			else
			{
				EmotePose(9, time, time, seed, ref p);
			}
		}
		else if (flag6)
		{
			p.open = 0.75f;
			p.smile = 0.5f;
			p.wide = 0.6f;
			p.raiseL = 0.9f;
			p.raiseR = 0.9f;
			p.rate = 20f;
		}
		else if (flag7 || flag14)
		{
			p.open = 0.12f;
			p.smile = -0.7f;
			p.angry = 0.7f;
			p.wob = 0.15f;
		}
		else if (flag8)
		{
			p.pucker = 1f;
			p.open = 0.3f + 0.15f * Mathf.Abs(Mathf.Sin(time * 5f));
			p.raiseL = 0.4f;
			p.raiseR = 0.4f;
		}
		else if (flag9)
		{
			p.smile = 0.9f;
			p.wide = 0.8f;
		}
		else if (flag10)
		{
			float num11 = Mathf.Clamp(num / 4f, 0.4f, 1f);
			p.open = 0.1f + 0.22f * num11 * Mathf.Abs(Mathf.Sin(time * (7f + num * 1.5f) + seed));
			p.smile = 0.45f;
			p.wide = 0.3f;
			p.raiseL = 0.15f;
			p.raiseR = 0.15f;
			if (num > 5.5f)
			{
				p.angry = 0.3f;
				p.smile = 0.2f;
			}
		}
		else if (idleLeft > 0f)
		{
			EmotePose(idleKind, idleT, time, seed, ref p);
		}
		float num12 = 1f - Mathf.Exp((0f - p.rate) * dt);
		open = Mathf.Lerp(open, p.open, num12);
		smile = Mathf.Lerp(smile, p.smile, num12);
		angry = Mathf.Lerp(angry, p.angry, num12);
		raiseL = Mathf.Lerp(raiseL, p.raiseL, num12);
		raiseR = Mathf.Lerp(raiseR, p.raiseR, num12);
		wide = Mathf.Lerp(wide, p.wide, num12);
		pucker = Mathf.Lerp(pucker, p.pucker, num12);
		skew = Mathf.Lerp(skew, p.skew, num12);
		tongueOut = Mathf.Lerp(tongueOut, p.tongue, num12);
		wob = Mathf.Lerp(wob, p.wob, num12);
		Apply();
		bool result = flag4 && !wasKnocked;
		wasKnocked = flag4;
		return result;
	}

	private void PlaceRoot()
	{
		//IL_003e: 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_0060: 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_0070: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0087: Unknown result type (might be due to invalid IL or missing references)
		int num = Mathf.Clamp(FaceMod.EffFwd, 0, 5);
		int num2 = Mathf.Clamp(FaceMod.EffUp, 0, 5);
		if (num2 / 2 == num / 2)
		{
			num2 = (num + 2) % 6;
		}
		Transform transform = root.transform;
		float num3 = Mathf.Max(0.0001f, Head.lossyScale.x);
		transform.localRotation = Quaternion.LookRotation(FaceMod.Axes[num], FaceMod.Axes[num2]);
		transform.localScale = Vector3.one * (headDiameter / num3);
		transform.localPosition = Vector3.zero;
	}

	private void FitHead()
	{
		//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00aa: Expected O, but got Unknown
		//IL_015b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0160: Unknown result type (might be due to invalid IL or missing references)
		//IL_0164: Unknown result type (might be due to invalid IL or missing references)
		//IL_0169: Unknown result type (might be due to invalid IL or missing references)
		//IL_0177: Unknown result type (might be due to invalid IL or missing references)
		//IL_017c: 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_0185: Unknown result type (might be due to invalid IL or missing references)
		//IL_018a: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d6: 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_02df: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ff: 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_0303: Unknown result type (might be due to invalid IL or missing references)
		//IL_0308: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0202: Unknown result type (might be due to invalid IL or missing references)
		//IL_0207: Unknown result type (might be due to invalid IL or missing references)
		//IL_020c: 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_01f4: 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_021e: 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_0229: Unknown result type (might be due to invalid IL or missing references)
		//IL_0232: 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_0245: Unknown result type (might be due to invalid IL or missing references)
		//IL_024c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0258: 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_0272: Unknown result type (might be due to invalid IL or missing references)
		//IL_0279: Unknown result type (might be due to invalid IL or missing references)
		//IL_0285: Unknown result type (might be due to invalid IL or missing references)
		//IL_028c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0298: Unknown result type (might be due to invalid IL or missing references)
		//IL_029f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0333: Unknown result type (might be due to invalid IL or missing references)
		//IL_0335: Unknown result type (might be due to invalid IL or missing references)
		//IL_0337: Unknown result type (might be due to invalid IL or missing references)
		//IL_033c: Unknown result type (might be due to invalid IL or missing references)
		//IL_03e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_03e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_03f1: Unknown result type (might be due to invalid IL or missing references)
		//IL_03fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0404: Unknown result type (might be due to invalid IL or missing references)
		//IL_0410: Unknown result type (might be due to invalid IL or missing references)
		//IL_0417: Unknown result type (might be due to invalid IL or missing references)
		//IL_0423: Unknown result type (might be due to invalid IL or missing references)
		//IL_0428: Unknown result type (might be due to invalid IL or missing references)
		//IL_042a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0431: Unknown result type (might be due to invalid IL or missing references)
		//IL_043d: 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_0450: Unknown result type (might be due to invalid IL or missing references)
		//IL_0457: 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_0468: Unknown result type (might be due to invalid IL or missing references)
		//IL_0487: Unknown result type (might be due to invalid IL or missing references)
		//IL_048e: Unknown result type (might be due to invalid IL or missing references)
		//IL_04a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_04a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_04bd: 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_04cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_04d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_04e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_0574: 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_057b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0592: Unknown result type (might be due to invalid IL or missing references)
		//IL_05f7: Unknown result type (might be due to invalid IL or missing references)
		//IL_05d5: Unknown result type (might be due to invalid IL or missing references)
		hasMap = false;
		fitCx = 0f;
		fitCy = FaceMod.PCenterY.Value;
		fitCz = FaceMod.PCenterZ.Value;
		fitR = FaceMod.PRadius.Value;
		if (!hasActorLogic || (Object)(object)root == (Object)null)
		{
			return;
		}
		PlaceRoot();
		Transform val = FindByName(Actor.transform, "actor_head_skinnedMesh");
		if ((Object)(object)val == (Object)null)
		{
			MelonLogger.Msg("[Faces] brak siatki glowy (actor_head_skinnedMesh) - uzywam kuli domyslnej.");
			return;
		}
		SkinnedMeshRenderer component = ((Component)val).GetComponent<SkinnedMeshRenderer>();
		if ((Object)(object)component == (Object)null)
		{
			MelonLogger.Msg("[Faces] siatka glowy nie jest SkinnedMeshRenderer - uzywam kuli domyslnej.");
			return;
		}
		Mesh val2 = new Mesh();
		List<Vector3> list = new List<Vector3>();
		try
		{
			component.BakeMesh(val2);
			if (((object)val2).GetType().GetProperty("vertices").GetValue(val2, null) is IEnumerable enumerable)
			{
				foreach (object item in enumerable)
				{
					list.Add((Vector3)item);
				}
			}
		}
		finally
		{
			Object.Destroy((Object)(object)val2);
		}
		if (list.Count < 20)
		{
			MelonLogger.Msg("[Faces] za malo wierzcholkow glowy (" + list.Count + ") - uzywam kuli domyslnej.");
			return;
		}
		Transform transform = ((Component)component).transform;
		Vector3 position = transform.position;
		Quaternion rotation = transform.rotation;
		Transform transform2 = root.transform;
		Bounds bounds = ((Renderer)component).bounds;
		Vector3 val3 = transform2.InverseTransformPoint(((Bounds)(ref bounds)).center);
		List<Vector3> list2 = null;
		float num = 1E+09f;
		string text = "";
		Vector3 val4 = default(Vector3);
		Vector3 val5 = default(Vector3);
		for (int i = 0; i < 2; i++)
		{
			List<Vector3> list3 = new List<Vector3>(list.Count);
			((Vector3)(ref val4))..ctor(1E+09f, 1E+09f, 1E+09f);
			((Vector3)(ref val5))..ctor(-1E+09f, -1E+09f, -1E+09f);
			for (int j = 0; j < list.Count; j++)
			{
				Vector3 val6 = ((i == 0) ? (position + rotation * list[j]) : transform.TransformPoint(list[j]));
				Vector3 val7 = root.transform.InverseTransformPoint(val6);
				list3.Add(val7);
				((Vector3)(ref val4))..ctor(Mathf.Min(val4.x, val7.x), Mathf.Min(val4.y, val7.y), Mathf.Min(val4.z, val7.z));
				((Vector3)(ref val5))..ctor(Mathf.Max(val5.x, val7.x), Mathf.Max(val5.y, val7.y), Mathf.Max(val5.z, val7.z));
			}
			Vector3 val8 = (val4 + val5) * 0.5f;
			float num2 = (val5.x - val4.x + (val5.y - val4.y)) * 0.25f;
			Vector3 val9 = val8 - val3;
			float num3 = ((Vector3)(ref val9)).magnitude + Mathf.Abs(num2 - 0.55f);
			if (num2 > 0.3f && num2 < 0.95f)
			{
				val9 = val8 - val3;
				if (((Vector3)(ref val9)).magnitude < 0.45f && num3 < num)
				{
					num = num3;
					list2 = list3;
					text = ((i == 0) ? "bez skali" : "ze skala");
				}
			}
		}
		if (list2 == null)
		{
			MelonLogger.Msg("[Faces] ksztalt glowy z siatki nieprawdopodobny (" + list.Count + " wierzcholkow) - uzywam kuli domyslnej.");
			return;
		}
		Vector3 val10 = default(Vector3);
		((Vector3)(ref val10))..ctor(1E+09f, 1E+09f, 1E+09f);
		Vector3 val11 = default(Vector3);
		((Vector3)(ref val11))..ctor(-1E+09f, -1E+09f, -1E+09f);
		foreach (Vector3 item2 in list2)
		{
			val10 = new Vector3(Mathf.Min(val10.x, item2.x), Mathf.Min(val10.y, item2.y), Mathf.Min(val10.z, item2.z));
			val11 = new Vector3(Mathf.Max(val11.x, item2.x), Mathf.Max(val11.y, item2.y), Mathf.Max(val11.z, item2.z));
		}
		fitCx = (val10.x + val11.x) * 0.5f;
		fitCy = (val10.y + val11.y) * 0.5f;
		fitR = (val11.x - val10.x + (val11.y - val10.y)) * 0.25f;
		fitCz = val11.z - fitR;
		hmap = new float[46, 46];
		for (int k = 0; k < 46; k++)
		{
			for (int l = 0; l < 46; l++)
			{
				hmap[k, l] = float.NaN;
			}
		}
		mapX0 = fitCx - 0.91999996f;
		mapY0 = fitCy - 0.91999996f;
		foreach (Vector3 item3 in list2)
		{
			int num4 = (int)((item3.x - mapX0) / 0.04f);
			int num5 = (int)((item3.y - mapY0) / 0.04f);
			if (num4 >= 0 && num5 >= 0 && num4 < 46 && num5 < 46 && (float.IsNaN(hmap[num4, num5]) || item3.z > hmap[num4, num5]))
			{
				hmap[num4, num5] = item3.z;
			}
		}
		for (int m = 0; m < 4; m++)
		{
			float[,] array = (float[,])hmap.Clone();
			for (int n = 1; n < 45; n++)
			{
				for (int num6 = 1; num6 < 45; num6++)
				{
					if (!float.IsNaN(array[n, num6]))
					{
						continue;
					}
					float num7 = 0f;
					int num8 = 0;
					for (int num9 = -1; num9 <= 1; num9++)
					{
						for (int num10 = -1; num10 <= 1; num10++)
						{
							float num11 = array[n + num9, num6 + num10];
							if (!float.IsNaN(num11))
							{
								num7 += num11;
								num8++;
							}
						}
					}
					if (num8 >= 3)
					{
						hmap[n, num6] = num7 / (float)num8;
					}
				}
			}
		}
		hasMap = true;
		if (fitLogCount++ < 4)
		{
			MelonLogger.Msg("[Faces] dopasowanie glowy (" + text + ", " + list2.Count + " wierzcholkow): srodek (x=" + fitCx.ToString("0.00") + ", y=" + fitCy.ToString("0.00") + ", z=" + fitCz.ToString("0.00") + "), promien " + fitR.ToString("0.00") + " jednostki twarzy");
		}
	}

	private float SurfaceZ(float ax, float ay)
	{
		if (hasMap)
		{
			float num = (ax - mapX0) / 0.04f - 0.5f;
			float num2 = (ay - mapY0) / 0.04f - 0.5f;
			int num3 = (int)Mathf.Floor(num);
			int num4 = (int)Mathf.Floor(num2);
			if (num3 >= 0 && num4 >= 0 && num3 < 45 && num4 < 45)
			{
				float num5 = hmap[num3, num4];
				float num6 = hmap[num3 + 1, num4];
				float num7 = hmap[num3, num4 + 1];
				float num8 = hmap[num3 + 1, num4 + 1];
				if (!float.IsNaN(num5) && !float.IsNaN(num6) && !float.IsNaN(num7) && !float.IsNaN(num8))
				{
					float num9 = num - (float)num3;
					float num10 = num2 - (float)num4;
					return Mathf.Lerp(Mathf.Lerp(num5, num6, num9), Mathf.Lerp(num7, num8, num9), num10);
				}
			}
		}
		float num11 = ax - fitCx;
		float num12 = ay - fitCy;
		float num13 = Mathf.Min(num11 * num11 + num12 * num12, fitR * fitR * 0.95f);
		return fitCz + Mathf.Sqrt(fitR * fitR - num13);
	}

	private Vector3 Pos(float x, float y, float eps)
	{
		//IL_004b: Unknown result type (might be due to invalid IL or missing references)
		float value = FaceMod.PSize.Value;
		float num = fitCx + x * value;
		float num2 = fitCy + FaceMod.PFaceY.Value + y * value;
		float num3 = SurfaceZ(num, num2) + eps + 0.012f + FaceMod.PDepth.Value;
		return new Vector3(num, num2, num3);
	}

	public void SetVisible(bool v)
	{
		if (!((Object)(object)root == (Object)null) && visible != v)
		{
			visible = v;
			root.SetActive(v);
		}
	}

	private void Apply()
	{
		//IL_0110: 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_01b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_02df: 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_0282: Unknown result type (might be due to invalid IL or missing references)
		//IL_03e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_0401: Unknown result type (might be due to invalid IL or missing references)
		//IL_0456: Unknown result type (might be due to invalid IL or missing references)
		//IL_0476: Unknown result type (might be due to invalid IL or missing references)
		PlaceRoot();
		float value = FaceMod.PSize.Value;
		float num = FaceMod.PMouthY.Value + open * 0.04f;
		float value2 = FaceMod.PBrowY.Value;
		float value3 = FaceMod.PBrowX.Value;
		float num2 = open * 0.24f;
		float num3 = Mathf.Clamp(0.15f + 0.045f * Mathf.Max(0f, smile) + 0.02f * open + 0.04f * wide - 0.065f * pucker, 0.06f, 0.24f);
		float num4 = smile * 0.06f;
		bool flag = num2 > 0.03f;
		float num5 = num - num4 * 0.5f - num2;
		if ((Object)(object)mouthR != (Object)null)
		{
			mouthR.enabled = flag;
		}
		if (flag)
		{
			float y = num - num4 * 0.17f - num2 * 0.5f;
			mouth.localPosition = Pos(0f, y, 0.004f);
			mouth.localScale = new Vector3(num3 * 1.96f * value, num2 * value, 0.05f);
		}
		bool flag2 = flag && num2 > 0.034f;
		if ((Object)(object)teethR != (Object)null)
		{
			teethR.enabled = flag2;
		}
		if (flag2)
		{
			float num6 = Mathf.Min(0.045f, num2 * 0.35f);
			float num7 = num - num4 * 0.5f;
			teeth.localPosition = Pos(0f, num7 - 0.009f - num6 * 0.5f, 0.006f);
			teeth.localScale = new Vector3(num3 * 1.1f * value, num6 * value, 0.02f);
		}
		bool flag3 = (flag && open > 0.55f) || tongueOut > 0.05f;
		if ((Object)(object)tongueR != (Object)null)
		{
			tongueR.enabled = flag3;
		}
		if (flag3)
		{
			if (tongueOut > 0.05f)
			{
				float num8 = 0.07f + 0.1f * tongueOut;
				tongue.localPosition = Pos(0f, num5 - num8 * 0.35f, 0.005f);
				tongue.localScale = new Vector3(num3 * 0.6f * value, num8 * value, 0.03f);
			}
			else
			{
				float num9 = num - num4 * 0.5f;
				tongue.localPosition = Pos(0f, num9 - num2 * 0.8f, 0.005f);
				tongue.localScale = new Vector3(num3 * 0.7f * value, num2 * 0.38f * value, 0.03f);
			}
		}
		float num10 = 2f * num3 / 12f;
		bool flag4 = num2 > 0.026f || tongueOut > 0.05f;
		for (int i = 0; i < 13; i++)
		{
			float num11 = (float)i / 12f * 2f - 1f;
			float x = num11 * num3;
			float num12 = num + num4 * (num11 * num11 - 0.5f) + skew * 0.045f * num11;
			if (wob > 0.01f)
			{
				num12 += wob * 0.03f * (Mathf.PerlinNoise(time * 14f + (float)i * 0.7f, seed) - 0.5f) * 2f;
			}
			float num13 = Mathf.Max(num10 * 0.95f, 0.024f + 0.015f * (1f - num11 * num11));
			lipU[i].localPosition = Pos(x, num12, 0.009f);
			lipU[i].localScale = new Vector3(num13 * value, num13 * value, 0.03f);
			if ((Object)(object)lipLR[i] != (Object)null)
			{
				lipLR[i].enabled = flag4;
			}
			if (flag4)
			{
				float num14 = num2 * (1f - num11 * num11);
				lipL[i].localPosition = Pos(x, num12 - num14, 0.009f);
				lipL[i].localScale = new Vector3(num13 * value, num13 * value, 0.03f);
			}
		}
		PlaceBrow(browRT, value3, value2, 1f, raiseR, value);
		PlaceBrow(browLT, 0f - value3, value2, -1f, raiseL, value);
	}

	private void PlaceBrow(Transform[] seg, float cx, float cyBrow, float sign, float raise, float S)
	{
		//IL_010a: 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)
		float num = (angry * 24f - raise * 8f) * sign * ((float)Math.PI / 180f);
		float num2 = raise * 0.045f - angry * 0.02f;
		float num3 = 0.15f * 0.5f;
		float num4 = Mathf.Max(0f, 0.012f + 0.015f * raise - 0.01f * angry);
		float num5 = Mathf.Cos(num);
		float num6 = Mathf.Sin(num);
		float num7 = 0.15f / 6f;
		for (int i = 0; i < 7; i++)
		{
			float num8 = (float)i / 6f * 2f - 1f;
			float num9 = num8 * num3;
			float num10 = num4 * (1f - num8 * num8);
			float x = cx + num9 * num5 - num10 * num6;
			float y = cyBrow + num2 + num9 * num6 + num10 * num5;
			float num11 = Mathf.Max(num7 * 1.05f, 0.028f * (1f - 0.3f * Mathf.Abs(num8)));
			seg[i].localPosition = Pos(x, y, 0.009f);
			seg[i].localScale = new Vector3(num11 * S, num11 * S, 0.03f);
		}
	}

	private static Transform FindHead(Transform start)
	{
		Transform val = FindHeadIn(start);
		if ((Object)(object)val == (Object)null && (Object)(object)start.root != (Object)(object)start)
		{
			val = FindHeadIn(start.root);
		}
		return val;
	}

	private static Transform FindHeadIn(Transform start)
	{
		Transform val = null;
		Queue<Transform> queue = new Queue<Transform>();
		queue.Enqueue(start);
		while (queue.Count > 0)
		{
			Transform val2 = queue.Dequeue();
			string text = ((Object)val2).name.ToLowerInvariant();
			if (text == "head")
			{
				return val2;
			}
			if ((Object)(object)val == (Object)null && text.Contains("head") && !text.Contains("phone") && !text.Contains("set"))
			{
				val = val2;
			}
			for (int i = 0; i < val2.childCount; i++)
			{
				queue.Enqueue(val2.GetChild(i));
			}
		}
		return val;
	}

	private static string Path(Transform t)
	{
		string text = ((Object)t).name;
		while ((Object)(object)t.parent != (Object)null)
		{
			t = t.parent;
			text = ((Object)t).name + "/" + text;
		}
		return text;
	}

	private static void Dump(Transform t, Instance log)
	{
		try
		{
			Transform val = t;
			for (int i = 0; i < 2; i++)
			{
				if (!((Object)(object)val.parent != (Object)null))
				{
					break;
				}
				val = val.parent;
			}
			log.Msg("--- hierarchia (zrzut) ---");
			DumpRec(val, 0, log, new int[1]);
			log.Msg("--- koniec zrzutu ---");
		}
		catch
		{
		}
	}

	private static void DumpRec(Transform t, int depth, Instance log, int[] count)
	{
		if (count[0]++ > 80 || depth > 6)
		{
			return;
		}
		string text = "";
		try
		{
			if ((Object)(object)((Component)t).GetComponent<Renderer>() != (Object)null)
			{
				text += " [Renderer]";
			}
			if ((Object)(object)((Component)t).GetComponent<Rigidbody>() != (Object)null)
			{
				text += " [Rigidbody]";
			}
		}
		catch
		{
		}
		log.Msg(new string(' ', depth * 2) + ((Object)t).name + text);
		for (int i = 0; i < t.childCount; i++)
		{
			DumpRec(t.GetChild(i), depth + 1, log, count);
		}
	}
}
public class FaceMod : MelonMod
{
	internal static MelonPreferences_Entry<bool> PManual;

	internal static MelonPreferences_Entry<int> PFwd;

	internal static MelonPreferences_Entry<int> PUp;

	internal static MelonPreferences_Entry<float> PSize;

	internal static MelonPreferences_Entry<bool> PEnabled;

	internal static MelonPreferences_Entry<float> PPunchThr;

	internal static int FitVersion;

	internal static MelonPreferences_Entry<float> PCenterY;

	internal static MelonPreferences_Entry<float> PCenterZ;

	internal static MelonPreferences_Entry<float> PRadius;

	internal static MelonPreferences_Entry<float> PDepth;

	internal static MelonPreferences_Entry<float> PMouthY;

	internal static MelonPreferences_Entry<float> PBrowY;

	internal static MelonPreferences_Entry<float> PBrowX;

	internal static MelonPreferences_Entry<float> PFaceY;

	internal static MelonPreferences_Entry<float> PHitThr;

	internal static readonly Vector3[] Axes = (Vector3[])(object)new Vector3[6]
	{
		Vector3.right,
		Vector3.left,
		Vector3.up,
		Vector3.down,
		Vector3.forward,
		Vector3.back
	};

	internal const float DefCenterY = 0.41f;

	internal const float DefCenterZ = 0.05f;

	internal const float DefRadius = 0.5f;

	internal const float DefMouthY = -0.27f;

	internal const float DefBrowY = 0.12f;

	internal const float DefBrowX = 0.24f;

	internal static int AutoFwd = -1;

	internal static int AutoUp = -1;

	private readonly Dictionary<int, FaceController> faces = new Dictionary<int, FaceController>();

	private Type actorType;

	private bool actorTypeSearched;

	private bool loggedNoActor;

	private float scanTimer;

	private static MethodInfo findObjectsMethod;

	private static bool findObjectsResolved;

	private static bool findObjectsNeedsBool;

	private bool errorLogged;

	private bool scanErrorLogged;

	private int emoteIndex = -1;

	private bool helpVisible;

	private string toast = "";

	private float toastUntil;

	internal static int EffFwd
	{
		get
		{
			if (!PManual.Value && AutoFwd >= 0)
			{
				return AutoFwd;
			}
			return PFwd.Value;
		}
	}

	internal static int EffUp
	{
		get
		{
			if (!PManual.Value && AutoUp >= 0)
			{
				return AutoUp;
			}
			return PUp.Value;
		}
	}

	public override void OnApplicationStart()
	{
		MelonPreferences_Category obj = MelonPreferences.CreateCategory("GBFaces4", "Gang Beasts Faces");
		PEnabled = obj.CreateEntry<bool>("Enabled", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
		PManual = obj.CreateEntry<bool>("ManualOrientation", false, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
		PFwd = obj.CreateEntry<int>("ForwardAxis", 4, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
		PUp = obj.CreateEntry<int>("UpAxis", 2, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
		PSize = obj.CreateEntry<float>("SizeMultiplier", 1f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
		PCenterY = obj.CreateEntry<float>("HeadCenterY", 0.41f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
		PCenterZ = obj.CreateEntry<float>("HeadCenterZ", 0.05f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
		PRadius = obj.CreateEntry<float>("HeadRadius", 0.5f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
		PDepth = obj.CreateEntry<float>("DepthAdjust", 0f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
		PMouthY = obj.CreateEntry<float>("MouthY", -0.27f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
		PBrowY = obj.CreateEntry<float>("BrowY", 0.12f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
		PBrowX = obj.CreateEntry<float>("BrowX", 0.24f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
		PFaceY = obj.CreateEntry<float>("FaceY", 0f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
		PHitThr = obj.CreateEntry<float>("HitThreshold", 160f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
		PPunchThr = obj.CreateEntry<float>("PunchThreshold", 8f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
		((MelonBase)this).LoggerInstance.Msg("Gang Beasts Faces 2.0 (IL2CPP) zaladowany. F1 = pomoc na ekranie. Num* / Num/ = emotki, F5 wl/wyl.");
	}

	public override void OnSceneWasLoaded(int buildIndex, string sceneName)
	{
		foreach (FaceController value in faces.Values)
		{
			try
			{
				value.Destroy();
			}
			catch
			{
			}
		}
		faces.Clear();
		scanTimer = 0f;
	}

	public override void OnUpdate()
	{
		try
		{
			HandleKeys();
			scanTimer -= Time.deltaTime;
			if (scanTimer <= 0f)
			{
				scanTimer = ((actorType != null) ? 1f : 3f);
				Scan();
			}
			List<int> list = null;
			List<FaceController> list2 = null;
			foreach (KeyValuePair<int, FaceController> face in faces)
			{
				FaceController value = face.Value;
				if (!value.IsAlive())
				{
					if (list == null)
					{
						list = new List<int>();
					}
					list.Add(face.Key);
				}
				else if (value.Tick(Time.deltaTime))
				{
					if (list2 == null)
					{
						list2 = new List<FaceController>();
					}
					list2.Add(value);
				}
			}
			if (list != null)
			{
				foreach (int item in list)
				{
					try
					{
						faces[item].Destroy();
					}
					catch
					{
					}
					faces.Remove(item);
				}
			}
			if (list2 == null)
			{
				return;
			}
			foreach (FaceController value2 in faces.Values)
			{
				if (!list2.Contains(value2) && Random.value < 0.7f)
				{
					value2.Laugh = 2f + Random.value * 1.5f;
				}
			}
		}
		catch (Exception ex)
		{
			if (!errorLogged)
			{
				errorLogged = true;
				((MelonBase)this).LoggerInstance.Error("Blad w OnUpdate (kolejne takie same pomijam): " + ex);
			}
		}
	}

	private void Scan()
	{
		try
		{
			if (!actorTypeSearched)
			{
				actorTypeSearched = true;
				actorType = FindActorType();
				if (actorType != null)
				{
					((MelonBase)this).LoggerInstance.Msg("Znaleziono typ postaci: " + actorType.FullName + " (" + actorType.Assembly.GetName().Name + ")");
				}
			}
			List<Object> list;
			if (actorType != null)
			{
				list = FindAll(actorType);
			}
			else
			{
				if (!loggedNoActor)
				{
					loggedNoActor = true;
					((MelonBase)this).LoggerInstance.Warning("Nie znaleziono klasy 'Actor' - szukam obiektow o nazwie 'Head'. Mimika bedzie ograniczona.");
				}
				list = FindAll(typeof(Transform));
			}
			foreach (Object item in list)
			{
				Component val = (Component)(object)((item is Component) ? item : null);
				if ((Object)(object)val == (Object)null || (actorType == null && !string.Equals(((Object)val).name, "Head", StringComparison.OrdinalIgnoreCase)))
				{
					continue;
				}
				int instanceID = ((Object)val).GetInstanceID();
				if (!faces.ContainsKey(instanceID))
				{
					FaceController faceController = FaceController.Create(val, actorType != null, ((MelonBase)this).LoggerInstance);
					if (faceController != null)
					{
						faces[instanceID] = faceController;
					}
				}
			}
		}
		catch (Exception ex)
		{
			if (!scanErrorLogged)
			{
				scanErrorLogged = true;
				((MelonBase)this).LoggerInstance.Error("Blad skanowania postaci (kolejne takie same pomijam): " + ex);
			}
		}
	}

	private static List<Object> FindAll(Type t)
	{
		List<Object> list = new List<Object>();
		if (!findObjectsResolved)
		{
			findObjectsResolved = true;
			MethodInfo methodInfo = null;
			MethodInfo methodInfo2 = null;
			MethodInfo[] methods = typeof(Object).GetMethods(BindingFlags.Static | BindingFlags.Public);
			foreach (MethodInfo methodInfo3 in methods)
			{
				if (!(methodInfo3.Name != "FindObjectsOfType") && methodInfo3.IsGenericMethodDefinition)
				{
					ParameterInfo[] parameters = methodInfo3.GetParameters();
					if (parameters.Length == 0)
					{
						methodInfo = methodInfo3;
					}
					else if (parameters.Length == 1 && parameters[0].ParameterType == typeof(bool))
					{
						methodInfo2 = methodInfo3;
					}
				}
			}
			findObjectsMethod = methodInfo ?? methodInfo2;
			findObjectsNeedsBool = methodInfo == null && methodInfo2 != null;
		}
		if (findObjectsMethod == null)
		{
			return list;
		}
		if (!(findObjectsMethod.MakeGenericMethod(t).Invoke(null, (!findObjectsNeedsBool) ? null : new object[1] { false }) is IEnumerable enumerable))
		{
			return list;
		}
		foreach (object item in enumerable)
		{
			Object val = (Object)((item is Object) ? item : null);
			if (val != (Object)null)
			{
				list.Add(val);
			}
		}
		return list;
	}

	private static Type FindActorType()
	{
		Type type = null;
		Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
		foreach (Assembly assembly in assemblies)
		{
			string name = assembly.GetName().Name;
			if (name.StartsWith("UnityEngine") || name.StartsWith("System") || name.StartsWith("mscorlib") || name.StartsWith("MelonLoader") || name.StartsWith("Mono.") || name.StartsWith("0Harmony") || name.StartsWith("Il2CppInterop") || name.StartsWith("Il2Cppmscorlib") || name.StartsWith("Il2CppSystem"))
			{
				continue;
			}
			Type[] types;
			try
			{
				types = assembly.GetTypes();
			}
			catch (ReflectionTypeLoadException ex)
			{
				types = ex.Types;
			}
			catch
			{
				continue;
			}
			Type[] array = types;
			foreach (Type type2 in array)
			{
				if (type2 == null || type2.Name != "Actor")
				{
					continue;
				}
				bool flag;
				try
				{
					flag = typeof(Component).IsAssignableFrom(type2);
				}
				catch
				{
					continue;
				}
				if (flag)
				{
					if (name.Contains("Assembly-CSharp"))
					{
						return type2;
					}
					if (type == null)
					{
						type = type2;
					}
				}
			}
		}
		return type;
	}

	private static void EnterManual()
	{
		if (!PManual.Value)
		{
			int effFwd = EffFwd;
			int effUp = EffUp;
			PFwd.Value = effFwd;
			PUp.Value = effUp;
			PManual.Value = true;
		}
	}

	private void Toast(string msg)
	{
		toast = msg;
		toastUntil = Time.time + 2.5f;
	}

	private static float Round2(float v)
	{
		return Mathf.Round(v * 100f) / 100f;
	}

	private void HandleKeys()
	{
		bool flag = false;
		string text = null;
		if (KeyInput.Pressed(112))
		{
			helpVisible = !helpVisible;
		}
		if (KeyInput.Pressed(116))
		{
			PEnabled.Value = !PEnabled.Value;
			text = "Twarze: " + (PEnabled.Value ? "WLACZONE" : "WYLACZONE");
			flag = true;
		}
		if (KeyInput.Pressed(117))
		{
			EnterManual();
			PFwd.Value = (PFwd.Value + 1) % 6;
			if (PUp.Value / 2 == PFwd.Value / 2)
			{
				PUp.Value = NextUp(PFwd.Value, PUp.Value);
			}
			text = "Przod twarzy: os " + PFwd.Value;
			FitVersion++;
			flag = true;
		}
		if (KeyInput.Pressed(118))
		{
			EnterManual();
			PUp.Value = NextUp(PFwd.Value, PUp.Value);
			text = "Gora twarzy: os " + PUp.Value;
			FitVersion++;
			flag = true;
		}
		if (KeyInput.Pressed(119, repeat: true))
		{
			PSize.Value = Round2(Mathf.Max(0.3f, PSize.Value * 0.95f));
			text = "Rozmiar twarzy: " + PSize.Value;
			flag = true;
		}
		if (KeyInput.Pressed(120, repeat: true))
		{
			PSize.Value = Round2(Mathf.Min(3f, PSize.Value * 1.05f));
			text = "Rozmiar twarzy: " + PSize.Value;
			flag = true;
		}
		if (KeyInput.Pressed(107, repeat: true) || KeyInput.Pressed(187, repeat: true))
		{
			PFaceY.Value = Round2(PFaceY.Value + 0.01f);
			text = "Cala twarz wyzej: " + PFaceY.Value;
			flag = true;
		}
		if (KeyInput.Pressed(109, repeat: true) || KeyInput.Pressed(189, repeat: true))
		{
			PFaceY.Value = Round2(PFaceY.Value - 0.01f);
			text = "Cala twarz nizej: " + PFaceY.Value;
			flag = true;
		}
		if (KeyInput.Pressed(33, repeat: true))
		{
			PMouthY.Value = Round2(PMouthY.Value + 0.01f);
			text = "Usta: " + PMouthY.Value;
			flag = true;
		}
		if (KeyInput.Pressed(34, repeat: true))
		{
			PMouthY.Value = Round2(PMouthY.Value - 0.01f);
			text = "Usta: " + PMouthY.Value;
			flag = true;
		}
		if (KeyInput.Pressed(45, repeat: true))
		{
			PBrowY.Value = Round2(PBrowY.Value + 0.01f);
			text = "Brwi: " + PBrowY.Value;
			flag = true;
		}
		if (KeyInput.Pressed(46, repeat: true))
		{
			PBrowY.Value = Round2(PBrowY.Value - 0.01f);
			text = "Brwi: " + PBrowY.Value;
			flag = true;
		}
		if (KeyInput.Pressed(36, repeat: true))
		{
			PDepth.Value = Round2(PDepth.Value + 0.01f);
			text = "Glebokosc (dalej od glowy): " + PDepth.Value;
			flag = true;
		}
		if (KeyInput.Pressed(35, repeat: true))
		{
			PDepth.Value = Round2(PDepth.Value - 0.01f);
			text = "Glebokosc (blizej glowy): " + PDepth.Value;
			flag = true;
		}
		bool flag2 = KeyInput.Pressed(106);
		bool flag3 = KeyInput.Pressed(111);
		if (flag2 || flag3)
		{
			int num = FaceController.EmoteNames.Length;
			emoteIndex = (flag2 ? ((emoteIndex + 1) % num) : ((emoteIndex + num - 1) % num));
			foreach (FaceController value in faces.Values)
			{
				value.StartEmote(emoteIndex, 3.5f);
			}
			text = "Emotka: " + FaceController.EmoteNames[emoteIndex];
			flag = true;
		}
		if (KeyInput.Pressed(110))
		{
			foreach (FaceController value2 in faces.Values)
			{
				value2.StartEmote(-1, 0f);
			}
			text = "Emotka: koniec";
			flag = true;
		}
		if (KeyInput.Pressed(122))
		{
			PManual.Value = false;
			AutoFwd = -1;
			AutoUp = -1;
			text = "Kalibracja orientacji twarzy od nowa";
			FitVersion++;
			flag = true;
		}
		if (KeyInput.Pressed(121))
		{
			PManual.Value = false;
			AutoFwd = -1;
			AutoUp = -1;
			PFwd.Value = 4;
			PUp.Value = 2;
			PSize.Value = 1f;
			PCenterY.Value = 0.41f;
			PCenterZ.Value = 0.05f;
			PRadius.Value = 0.5f;
			PDepth.Value = 0f;
			PMouthY.Value = -0.27f;
			PBrowY.Value = 0.12f;
			PBrowX.Value = 0.24f;
			PFaceY.Value = 0f;
			text = "Twarz: ustawienia domyslne";
			FitVersion++;
			flag = true;
		}
		if (flag)
		{
			((MelonBase)this).LoggerInstance.Msg((text ?? "Twarz") + " | " + (PManual.Value ? "reczna" : "auto") + " przod=" + EffFwd + " gora=" + EffUp + " rozmiar x" + PSize.Value.ToString("0.00") + " wysokosc=" + PFaceY.Value.ToString("0.00") + " usta=" + PMouthY.Value.ToString("0.00") + " brwi=" + PBrowY.Value.ToString("0.00") + " glebokosc=" + PDepth.Value.ToString("0.00"));
			if (text != null)
			{
				Toast(text);
			}
			try
			{
				MelonPreferences.Save();
			}
			catch
			{
			}
		}
	}

	public override void OnGUI()
	{
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Expected O, but got Unknown
		//IL_0097: 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_00c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			bool flag = toast.Length > 0 && Time.time < toastUntil;
			if (flag || helpVisible)
			{
				GUIStyle val = new GUIStyle(GUI.skin.label);
				val.fontSize = 18;
				val.fontStyle = (FontStyle)1;
				string text = "";
				if (helpVisible)
				{
					text = "[Faces] F5 wl/wyl | Num* / Num/ nastepna / poprzednia emotka | Num. koniec emotki | F8/F9 rozmiar\nNum+/Num- cala twarz gora/dol | PgUp/PgDn usta | Ins/Del brwi | Home/End glebokosc\nF6/F7 obrot | F10 reset | F11 kalibracja | F1 ukryj pomoc";
				}
				if (flag)
				{
					text = ((text.Length > 0) ? (text + "\n") : "") + "[Faces] " + toast;
				}
				val.normal.textColor = Color.black;
				GUI.Label(new Rect(21f, 21f, 1100f, 90f), text, val);
				val.normal.textColor = Color.white;
				GUI.Label(new Rect(20f, 20f, 1100f, 90f), text, val);
			}
		}
		catch
		{
		}
	}

	private static int NextUp(int fwd, int up)
	{
		for (int i = 1; i <= 6; i++)
		{
			int num = (up + i) % 6;
			if (num / 2 != fwd / 2)
			{
				return num;
			}
		}
		return up;
	}
}
internal static class KeyInput
{
	public const int F1 = 112;

	public const int F2 = 113;

	public const int F3 = 114;

	public const int F4 = 115;

	public const int F5 = 116;

	public const int F6 = 117;

	public const int F7 = 118;

	public const int F8 = 119;

	public const int F9 = 120;

	public const int F10 = 121;

	public const int F11 = 122;

	public const int PageUp = 33;

	public const int PageDown = 34;

	public const int End = 35;

	public const int Home = 36;

	public const int Insert = 45;

	public const int Delete = 46;

	public const int NumAdd = 107;

	public const int NumSub = 109;

	public const int NumMul = 106;

	public const int NumDiv = 111;

	public const int NumDec = 110;

	public const int OemPlus = 187;

	public const int OemMinus = 189;

	public const int Num0 = 96;

	public const int Num1 = 97;

	public const int Num2 = 98;

	public const int Num3 = 99;

	public const int Num4 = 100;

	public const int Num5 = 101;

	public const int Num6 = 102;

	public const int Num7 = 103;

	public const int Num8 = 104;

	public const int Num9 = 105;

	private static readonly uint myPid = (uint)Process.GetCurrentProcess().Id;

	private static readonly double[] downAt = new double[256];

	private static readonly double[] nextRepeat = new double[256];

	private static double focusChecked = -1.0;

	private static bool focused;

	[DllImport("user32.dll")]
	private static extern short GetAsyncKeyState(int vKey);

	[DllImport("user32.dll")]
	private static extern IntPtr GetForegroundWindow();

	[DllImport("user32.dll")]
	private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint pid);

	private static double Now()
	{
		return (double)Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
	}

	private static bool GameFocused(double now)
	{
		if (now - focusChecked > 0.1)
		{
			focusChecked = now;
			try
			{
				GetWindowThreadProcessId(GetForegroundWindow(), out var pid);
				focused = pid == myPid;
			}
			catch
			{
				focused = false;
			}
		}
		return focused;
	}

	private static bool IsDown(int vk, double now)
	{
		try
		{
			return GameFocused(now) && (GetAsyncKeyState(vk) & 0x8000) != 0;
		}
		catch
		{
			return false;
		}
	}

	public static bool Pressed(int vk, bool repeat)
	{
		double num = Now();
		if (!IsDown(vk, num))
		{
			downAt[vk] = 0.0;
			return false;
		}
		if (downAt[vk] == 0.0)
		{
			downAt[vk] = num;
			nextRepeat[vk] = num + 0.4;
			return true;
		}
		if (repeat && num >= nextRepeat[vk])
		{
			nextRepeat[vk] = num + 0.07;
			return true;
		}
		return false;
	}

	public static bool Pressed(int vk)
	{
		return Pressed(vk, repeat: false);
	}
}