GuzCharacter.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text;
using System.Text.Json;
using System.Text.RegularExpressions;
using Assets.Scripts.Actors.Player;
using Assets.Scripts.Inventory__Items__Pickups.AbilitiesPassive;
using Assets.Scripts.Inventory__Items__Pickups.AbilitiesPassive.Implementations;
using Assets.Scripts.Inventory__Items__Pickups.Stats;
using Assets.Scripts.Managers;
using Assets.Scripts.Menu.Shop;
using Assets.Scripts.Saves___Serialization.Progression;
using Assets.Scripts.Saves___Serialization.Progression.Achievements;
using Assets.Scripts.Saves___Serialization.Progression.Stats;
using Assets.Scripts.Saves___Serialization.Progression.Unlocks;
using Assets.Scripts.Saves___Serialization.SaveFiles;
using Assets.Scripts.Saves___Serialization.SaveFiles.Configs;
using Assets.Scripts.Steam;
using Assets.Scripts.UI.Localization;
using Assets.Scripts._Data;
using Assets.Scripts._Data.Hats;
using Assets.Scripts._Data.MapsAndStages;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using HarmonyLib;
using Il2CppInterop.Runtime.Attributes;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using Il2CppSystem.Reflection;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("GuzCharacter")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.2.0.0")]
[assembly: AssemblyInformationalVersion("1.2.0")]
[assembly: AssemblyProduct("GuzCharacter")]
[assembly: AssemblyTitle("GuzCharacter")]
[assembly: AssemblyVersion("1.2.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace GuzCharacter
{
	internal static class AllPassives
	{
		private sealed class Entry
		{
			public PassiveAbility Passive;

			public IntPtr Ptr;

			public EPassive Type;

			public Set Owner;

			public bool NoFloat;

			public readonly Dictionary<int, string> Keys = new Dictionary<int, string>();

			public string Key(StatModifier m)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_0009: Unknown result type (might be due to invalid IL or missing references)
				//IL_0010: Unknown result type (might be due to invalid IL or missing references)
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				//IL_0013: Expected I4, but got Unknown
				//IL_0042: 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_0074: Unknown result type (might be due to invalid IL or missing references)
				int key = (m.stat << 4) | (m.modifyType & 0xF);
				if (!Keys.TryGetValue(key, out var value))
				{
					value = (Keys[key] = $"Guz.{Type}.{m.stat}.{m.modifyType}");
				}
				return value;
			}
		}

		private sealed class Set
		{
			public PlayerInventory Inv;

			public IntPtr Ptr;

			public readonly List<Entry> Entries = new List<Entry>();

			public readonly HashSet<int> Types = new HashSet<int>();

			public bool TickSeen;

			public bool StatSeen;

			public IntPtr Native;

			public bool NativeNoFloat;

			public float SpeedShare = 1f;
		}

		private static readonly Dictionary<IntPtr, Set> _sets = new Dictionary<IntPtr, Set>();

		private static readonly Dictionary<IntPtr, Entry> _byPassive = new Dictionary<IntPtr, Entry>();

		private static readonly HashSet<string> _warned = new HashSet<string>();

		public static bool GuzRunActive;

		public static bool NoFloat;

		public static bool IsTracked(IntPtr inventory)
		{
			return _sets.ContainsKey(inventory);
		}

		public static int CountFor(IntPtr inventory)
		{
			if (!_sets.TryGetValue(inventory, out var value))
			{
				return 0;
			}
			return value.Entries.Count;
		}

		public static PassiveAbility Find(IntPtr inventory, EPassive type)
		{
			//IL_0028: 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)
			if (!_sets.TryGetValue(inventory, out var value))
			{
				return null;
			}
			foreach (Entry entry in value.Entries)
			{
				if (entry.Type == type)
				{
					return entry.Passive;
				}
			}
			return null;
		}

		public unsafe static void Attach(PlayerInventory inv)
		{
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Unknown result type (might be due to invalid IL or missing references)
			//IL_0217: Expected O, but got Unknown
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Expected I4, but got Unknown
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			if (!Guz.Injected || inv == null)
			{
				return;
			}
			IntPtr pointer = ((Il2CppObjectBase)inv).Pointer;
			if (pointer == IntPtr.Zero || _sets.ContainsKey(pointer) || !Guz.IsGuz(inv.characterData))
			{
				return;
			}
			Set set = new Set
			{
				Inv = inv,
				Ptr = pointer
			};
			set.SpeedShare = (float)Math.Clamp(Plugin.MoveSpeedBonus.Value, 0, 100) / 100f;
			_sets[pointer] = set;
			try
			{
				PassiveAbility passiveAbility = inv.passiveAbility;
				if (passiveAbility != null)
				{
					EPassive ePassive = Guz.PrimarySource.ePassive;
					set.Native = ((Il2CppObjectBase)passiveAbility).Pointer;
					set.NativeNoFloat = NoGlide(ePassive);
					if (set.NativeNoFloat)
					{
						NoFloat = true;
					}
					Restrain(passiveAbility, ePassive);
				}
			}
			catch (Exception ex)
			{
				WarnOnce("native", "Guz's native passive could not be adjusted: " + ex.Message);
			}
			foreach (PassiveData item in Guz.Secondary)
			{
				EPassive ePassive2 = item.ePassive;
				try
				{
					PassiveAbility val = PassiveAbilityFactory.CreatePassiveAbility(item);
					if (val != null)
					{
						Entry entry = new Entry
						{
							Passive = val,
							Ptr = ((Il2CppObjectBase)val).Pointer,
							Type = ePassive2,
							Owner = set,
							NoFloat = NoGlide(ePassive2)
						};
						set.Entries.Add(entry);
						set.Types.Add((int)ePassive2);
						_byPassive[entry.Ptr] = entry;
						val.Init();
						Restrain(val, ePassive2);
					}
				}
				catch (Exception ex2)
				{
					WarnOnce("init:" + ((object)(*(EPassive*)(&ePassive2))/*cast due to .constrained prefix*/).ToString(), $"Passive {ePassive2} failed to start: {ex2.Message}");
				}
			}
			ManualLogSource l = Plugin.L;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(80, 4, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Guz inventory ready: 1 native + ");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(set.Entries.Count);
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" extra passives ");
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("(speed bonus ");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<float>(set.SpeedShare * 100f, "0");
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("%, glide ");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(OnOff(Plugin.Glide.Value));
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", hover ");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(OnOff(Plugin.Hover.Value));
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(").");
			}
			l.LogInfo(val2);
		}

		private static string OnOff(bool b)
		{
			if (!b)
			{
				return "off";
			}
			return "on";
		}

		private static bool NoGlide(EPassive type)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			if ((int)type == 10)
			{
				return !Plugin.Glide.Value;
			}
			return false;
		}

		private static void Restrain(PassiveAbility ability, EPassive type)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			if ((int)type == 21 && !Plugin.Hover.Value)
			{
				PassiveAbilityHoarder val = ((Il2CppObjectBase)ability).TryCast<PassiveAbilityHoarder>();
				if (val != null)
				{
					val.maxAccumulatedTicks = 0;
				}
			}
		}

		public static void OnRunInventory(PlayerInventory inv)
		{
			if (inv != null)
			{
				IntPtr pointer = ((Il2CppObjectBase)inv).Pointer;
				if (_sets.Count > 0 && (_sets.Count != 1 || !_sets.ContainsKey(pointer)))
				{
					DetachAllExcept(pointer);
				}
				if (!_sets.ContainsKey(pointer))
				{
					Attach(inv);
				}
				GuzRunActive = _sets.ContainsKey(pointer);
			}
		}

		private static void DetachAllExcept(IntPtr keep)
		{
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Expected O, but got Unknown
			List<Set> list = new List<Set>();
			foreach (Set value in _sets.Values)
			{
				if (value.Ptr != keep)
				{
					list.Add(value);
				}
			}
			foreach (Set item in list)
			{
				Detach(item);
			}
			if (list.Count > 0)
			{
				ManualLogSource l = Plugin.L;
				bool flag = default(bool);
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(63, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Guz: released the passives of ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(list.Count);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" inventory(ies) no longer in use.");
				}
				l.LogInfo(val);
			}
		}

		public static void Tick(PlayerInventory inv)
		{
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Expected O, but got Unknown
			if (_sets.Count == 0)
			{
				return;
			}
			IntPtr pointer = ((Il2CppObjectBase)inv).Pointer;
			if (!_sets.TryGetValue(pointer, out var value))
			{
				return;
			}
			if (_sets.Count > 1)
			{
				DetachAllExcept(pointer);
			}
			if (inv.pause)
			{
				return;
			}
			if (!value.TickSeen)
			{
				value.TickSeen = true;
				ManualLogSource l = Plugin.L;
				bool flag = default(bool);
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(47, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Guz: ticking ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(value.Entries.Count);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" extra passives each physics step.");
				}
				l.LogInfo(val);
			}
			List<Entry> entries = value.Entries;
			for (int i = 0; i < entries.Count; i++)
			{
				Entry entry = entries[i];
				NoFloat = entry.NoFloat;
				try
				{
					entry.Passive.Tick();
				}
				catch (Exception ex)
				{
					WarnOnce("tick:" + ((object)Unsafe.As<EPassive, EPassive>(ref entry.Type)/*cast due to .constrained prefix*/).ToString(), $"Passive {entry.Type} failed in Tick: {ex.Message}");
				}
			}
			NoFloat = value.NativeNoFloat;
		}

		public static void Cleanup(PlayerInventory inv)
		{
			if (_sets.Count != 0 && inv != null && _sets.TryGetValue(((Il2CppObjectBase)inv).Pointer, out var value))
			{
				Detach(value);
			}
		}

		private static void Detach(Set set)
		{
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			_sets.Remove(set.Ptr);
			foreach (Entry entry in set.Entries)
			{
				_byPassive.Remove(entry.Ptr);
				try
				{
					entry.Passive.Cleanup();
				}
				catch (Exception ex)
				{
					WarnOnce("cleanup:" + ((object)Unsafe.As<EPassive, EPassive>(ref entry.Type)/*cast due to .constrained prefix*/).ToString(), $"Passive {entry.Type} failed in Cleanup: {ex.Message}");
				}
			}
			set.Entries.Clear();
			if (_sets.Count == 0)
			{
				GuzRunActive = (NoFloat = false);
			}
		}

		public static bool Has(PlayerInventory inv, EPassive passive)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Invalid comparison between Unknown and I4
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected I4, but got Unknown
			if (_sets.Count != 0 && (int)passive != 9 && _sets.TryGetValue(((Il2CppObjectBase)inv).Pointer, out var value))
			{
				return value.Types.Contains((int)passive);
			}
			return false;
		}

		public static void OnSetStat(PassiveAbility passive, StatModifier modifier)
		{
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Invalid comparison between Unknown and I4
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Invalid comparison between Unknown and I4
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Expected O, but got Unknown
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Expected O, but got Unknown
			if (_sets.Count == 0 || passive == null || modifier == null)
			{
				return;
			}
			IntPtr pointer = ((Il2CppObjectBase)passive).Pointer;
			if (!_byPassive.TryGetValue(pointer, out var value))
			{
				if ((int)modifier.stat != 25)
				{
					return;
				}
				{
					foreach (Set value2 in _sets.Values)
					{
						if (value2.Native == pointer)
						{
							modifier.modification = CutSpeed(modifier, value2.SpeedShare);
							break;
						}
					}
					return;
				}
			}
			try
			{
				StatInventory statInventory = value.Owner.Inv.statInventory;
				if (statInventory == null)
				{
					return;
				}
				string text = value.Key(modifier);
				if ((int)modifier.stat == 25 && value.Owner.SpeedShare < 1f)
				{
					modifier = new StatModifier
					{
						stat = modifier.stat,
						modifyType = modifier.modifyType,
						modification = CutSpeed(modifier, value.Owner.SpeedShare)
					};
				}
				statInventory.ChangeMovingStat(text, modifier);
				if (!value.Owner.StatSeen)
				{
					value.Owner.StatSeen = true;
					ManualLogSource l = Plugin.L;
					bool flag = default(bool);
					BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(58, 2, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Guz: extra passives are feeding stat bonuses (first: ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" = ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(modifier.modification);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(").");
					}
					l.LogInfo(val);
				}
			}
			catch (Exception ex)
			{
				WarnOnce("stat:" + ((object)Unsafe.As<EPassive, EPassive>(ref value.Type)/*cast due to .constrained prefix*/).ToString(), $"Passive {value.Type} could not apply a stat bonus: {ex.Message}");
			}
		}

		private static float CutSpeed(StatModifier m, float share)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Invalid comparison between Unknown and I4
			float modification = m.modification;
			if ((int)m.modifyType != 1)
			{
				return modification * share;
			}
			return 1f + (modification - 1f) * share;
		}

		private static void WarnOnce(string key, string message)
		{
			if (_warned.Add(key))
			{
				Plugin.L.LogWarning((object)message);
			}
		}
	}
	internal static class Guz
	{
		public static readonly ECharacter Id = (ECharacter)72126;

		public const string IdString = "72126";

		public static bool Injected;

		public static CharacterData Data;

		public static IntPtr DataPtr;

		public static PassiveData Passive;

		public static IntPtr PassivePtr;

		public static ECharacter BaseId = (ECharacter)4;

		public static PassiveData PrimarySource;

		public static readonly List<PassiveData> Secondary = new List<PassiveData>();

		public static readonly List<PassiveData> AllPassiveSources = new List<PassiveData>();

		public static readonly List<WeaponData> Weapons = new List<WeaponData>();

		private static readonly Dictionary<int, PassiveData> _nativeCopies = new Dictionary<int, PassiveData>();

		private static readonly HashSet<string> _warned = new HashSet<string>();

		public static bool TintOn;

		public static Color Tint = Color.white;

		public static bool CustomPortrait;

		private static bool _failed;

		public static string DisplayName
		{
			get
			{
				string value = Plugin.CharacterName.Value;
				if (!string.IsNullOrWhiteSpace(value))
				{
					return value.Trim();
				}
				return "Guz";
			}
		}

		public static string Description => Plugin.CharacterDescription.Value ?? "";

		public static string PassiveDisplayName
		{
			get
			{
				string value = Plugin.PassiveName.Value;
				if (!string.IsNullOrWhiteSpace(value))
				{
					return value.Trim();
				}
				return "All of the Above";
			}
		}

		public static int PassiveCount => Secondary.Count + (((Object)(object)PrimarySource != (Object)null) ? 1 : 0);

		public static string PassiveDescription()
		{
			string text = ((PassiveCount >= AllPassiveSources.Count) ? $"Every other character's passive, all {PassiveCount} at once." : $"{PassiveCount} of the other characters' {AllPassiveSources.Count} passives at once.");
			if (Plugin.ListPassiveNames.Value)
			{
				List<string> list = PassiveNames();
				if (list.Count > 0)
				{
					text = text + " " + string.Join(", ", list) + ".";
				}
			}
			return text;
		}

		public static List<string> PassiveNames()
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			List<string> list = new List<string>();
			List<PassiveData> list2 = new List<PassiveData>();
			if ((Object)(object)PrimarySource != (Object)null)
			{
				list2.Add(PrimarySource);
			}
			list2.AddRange(Secondary);
			foreach (PassiveData item in list2)
			{
				string text = null;
				try
				{
					text = item.GetName();
				}
				catch
				{
				}
				list.Add(string.IsNullOrEmpty(text) ? ((object)item.ePassive/*cast due to .constrained prefix*/).ToString() : text);
			}
			return list;
		}

		public static bool IsGuz(CharacterData cd)
		{
			if ((Object)(object)cd != (Object)null && DataPtr != IntPtr.Zero)
			{
				return ((Il2CppObjectBase)cd).Pointer == DataPtr;
			}
			return false;
		}

		public static void TryInject()
		{
			if (Injected || _failed)
			{
				return;
			}
			try
			{
				DataManager instance = DataManager.Instance;
				if (!((Object)(object)instance == (Object)null))
				{
					Dictionary<ECharacter, CharacterData> characterData = instance.characterData;
					List<CharacterData> unsortedCharacterData = instance.unsortedCharacterData;
					if (characterData != null && unsortedCharacterData != null && characterData.Count != 0)
					{
						Inject(instance);
						Injected = true;
						SaveGuard.EnsureEntries(afterLoad: false);
					}
				}
			}
			catch (Exception ex)
			{
				_failed = true;
				Plugin.L.LogError((object)("Could not register Guz: " + ex));
			}
		}

		private static void Inject(DataManager dm)
		{
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Expected O, but got Unknown
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0268: Unknown result type (might be due to invalid IL or missing references)
			//IL_027a: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cb: Expected O, but got Unknown
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0391: Unknown result type (might be due to invalid IL or missing references)
			//IL_0396: Unknown result type (might be due to invalid IL or missing references)
			//IL_0310: Unknown result type (might be due to invalid IL or missing references)
			//IL_0345: Unknown result type (might be due to invalid IL or missing references)
			//IL_034a: 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_03c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0403: Unknown result type (might be due to invalid IL or missing references)
			//IL_040a: Expected O, but got Unknown
			//IL_00c2: 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_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Invalid comparison between Unknown and I4
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Expected I4, but got Unknown
			Dictionary<ECharacter, CharacterData> characterData = dm.characterData;
			List<CharacterData> unsortedCharacterData = dm.unsortedCharacterData;
			TintOn = Plugin.TintEnabled.Value && TryParseColor(Plugin.TintColor.Value, out Tint);
			BaseId = ResolveBase(dm);
			CharacterData val = characterData[BaseId];
			if ((Object)(object)val == (Object)null)
			{
				throw new InvalidOperationException("Base character data is missing: " + ((object)Unsafe.As<ECharacter, ECharacter>(ref BaseId)/*cast due to .constrained prefix*/).ToString());
			}
			AllPassiveSources.Clear();
			HashSet<int> hashSet = new HashSet<int>();
			for (int i = 0; i < unsortedCharacterData.Count; i++)
			{
				CharacterData val2 = unsortedCharacterData[i];
				if ((Object)(object)val2 == (Object)null || val2.eCharacter == Id)
				{
					continue;
				}
				PassiveData passive = val2.passive;
				if (!((Object)(object)passive == (Object)null))
				{
					EPassive ePassive = passive.ePassive;
					if ((int)ePassive != 9 && hashSet.Add((int)ePassive))
					{
						AllPassiveSources.Add(passive);
					}
				}
			}
			PassiveData passive2 = SelectPassives(val);
			CharacterData val3 = ((Il2CppObjectBase)Object.Instantiate<CharacterData>(val)).Cast<CharacterData>();
			((Object)val3).name = "Guz";
			((Object)val3).hideFlags = (HideFlags)32;
			val3.eCharacter = Id;
			val3.passive = passive2;
			((UnlockableBase)val3).author = "Guz";
			((UnlockableBase)val3).isEnabled = true;
			((UnlockableBase)val3).showInUnlocks = false;
			((UnlockableBase)val3).canAlwaysToggle = false;
			((UnlockableBase)val3).price = 0;
			((UnlockableBase)val3).sortingPriority = -100000;
			val3.achievementRequirement = null;
			val3.numQuestsRequiredForVisibilityInCharacterSelection = 0;
			val3.categoryScores = val.categoryScores;
			CollectWeapons(dm);
			SelectWeapon(dm, val3, val);
			Texture2D val4 = LoadPortrait();
			if ((Object)(object)val4 != (Object)null)
			{
				val3.icon = (Texture)(object)val4;
				CustomPortrait = true;
			}
			val3.Init();
			List<SkinData> val5 = BuildSkins(dm);
			bool flag = default(bool);
			try
			{
				GuzModel.Apply(val, val3, val5[0]);
			}
			catch (Exception ex)
			{
				ManualLogSource l = Plugin.L;
				BepInExWarningLogInterpolatedStringHandler val6 = new BepInExWarningLogInterpolatedStringHandler(43, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val6).AppendLiteral("Custom model not applied, Guz looks like ");
					((BepInExLogInterpolatedStringHandler)val6).AppendFormatted<ECharacter>(BaseId);
					((BepInExLogInterpolatedStringHandler)val6).AppendLiteral(": ");
					((BepInExLogInterpolatedStringHandler)val6).AppendFormatted<string>(ex.Message);
				}
				l.LogWarning(val6);
			}
			try
			{
				GuzSkins.Add(val5);
			}
			catch (Exception ex2)
			{
				Plugin.L.LogWarning((object)("Guz's extra skins were not added: " + ex2.Message));
			}
			Data = val3;
			DataPtr = ((Il2CppObjectBase)val3).Pointer;
			characterData[Id] = val3;
			dm.skinData[Id] = val5;
			unsortedCharacterData.Add(val3);
			int num = 0;
			try
			{
				num = AddHatOrientations(dm);
			}
			catch (Exception ex3)
			{
				Plugin.L.LogWarning((object)("Hat placement for Guz could not be set up: " + ex3.Message));
			}
			ManualLogSource l2 = Plugin.L;
			BepInExInfoLogInterpolatedStringHandler val7 = new BepInExInfoLogInterpolatedStringHandler(56, 5, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val7).AppendLiteral("Registered '");
				((BepInExLogInterpolatedStringHandler)val7).AppendFormatted<string>(DisplayName);
				((BepInExLogInterpolatedStringHandler)val7).AppendLiteral("' (id ");
				((BepInExLogInterpolatedStringHandler)val7).AppendFormatted<string>("72126");
				((BepInExLogInterpolatedStringHandler)val7).AppendLiteral(") based on ");
				((BepInExLogInterpolatedStringHandler)val7).AppendFormatted<ECharacter>(BaseId);
				((BepInExLogInterpolatedStringHandler)val7).AppendLiteral(", weapon ");
				((BepInExLogInterpolatedStringHandler)val7).AppendFormatted<string>(((Object)(object)val3.weapon != (Object)null) ? ((object)val3.weapon.eWeapon/*cast due to .constrained prefix*/).ToString() : "none");
				((BepInExLogInterpolatedStringHandler)val7).AppendLiteral(", ");
				((BepInExLogInterpolatedStringHandler)val7).AppendFormatted<int>(num);
				((BepInExLogInterpolatedStringHandler)val7).AppendLiteral(" hat placements.");
			}
			l2.LogInfo(val7);
			List<string> list = new List<string> { ((object)PrimarySource.ePassive/*cast due to .constrained prefix*/).ToString() };
			foreach (PassiveData item in Secondary)
			{
				list.Add(((object)item.ePassive/*cast due to .constrained prefix*/).ToString());
			}
			ManualLogSource l3 = Plugin.L;
			val7 = new BepInExInfoLogInterpolatedStringHandler(13, 2, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val7).AppendLiteral("Passives (");
				((BepInExLogInterpolatedStringHandler)val7).AppendFormatted<int>(list.Count);
				((BepInExLogInterpolatedStringHandler)val7).AppendLiteral("): ");
				((BepInExLogInterpolatedStringHandler)val7).AppendFormatted<string>(string.Join(", ", list));
			}
			l3.LogInfo(val7);
		}

		private static ECharacter ResolveBase(DataManager dm)
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Expected O, but got Unknown
			//IL_0037: 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)
			string text = (Plugin.BaseCharacter.Value ?? "").Trim();
			if (text.Length > 0 && Enum.TryParse<ECharacter>(text, ignoreCase: true, out ECharacter result) && Enum.IsDefined(typeof(ECharacter), result) && dm.characterData.ContainsKey(result))
			{
				return result;
			}
			ManualLogSource l = Plugin.L;
			bool flag = default(bool);
			BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(46, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("BaseCharacter '");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' not recognised; falling back.");
			}
			l.LogWarning(val);
			if (dm.characterData.ContainsKey((ECharacter)4))
			{
				return (ECharacter)4;
			}
			return (ECharacter)0;
		}

		private static HashSet<EPassive> ParseExcluded()
		{
			//IL_005a: 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)
			HashSet<EPassive> hashSet = new HashSet<EPassive>();
			string[] array = (Plugin.ExcludedPassives.Value ?? "").Split(new char[2] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries);
			for (int i = 0; i < array.Length; i++)
			{
				string text = array[i].Trim();
				if (text.Length != 0)
				{
					if (Enum.TryParse<EPassive>(text, ignoreCase: true, out EPassive result) && Enum.IsDefined(typeof(EPassive), result))
					{
						hashSet.Add(result);
					}
					else
					{
						WarnOnce("Unknown passive in Exclude list: '" + text + "'");
					}
				}
			}
			return hashSet;
		}

		private static void WarnOnce(string message)
		{
			if (_warned.Add(message))
			{
				Plugin.L.LogWarning((object)message);
			}
		}

		private static PassiveData SelectPassives(CharacterData baseData)
		{
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Expected I4, but got Unknown
			HashSet<EPassive> excluded = ParseExcluded();
			if (!Plugin.WallClimb.Value)
			{
				excluded.Add((EPassive)8);
			}
			List<PassiveData> list = AllPassiveSources.FindAll((PassiveData p) => !excluded.Contains(p.ePassive));
			PrimarySource = list.Find((PassiveData p) => (int)p.ePassive == 20);
			if ((Object)(object)PrimarySource == (Object)null && (Object)(object)baseData.passive != (Object)null)
			{
				PrimarySource = list.Find((PassiveData p) => ((Il2CppObjectBase)p).Pointer == ((Il2CppObjectBase)baseData.passive).Pointer);
			}
			if ((Object)(object)PrimarySource == (Object)null && list.Count > 0)
			{
				PrimarySource = list[0];
			}
			if ((Object)(object)PrimarySource == (Object)null)
			{
				PrimarySource = baseData.passive;
			}
			if ((Object)(object)PrimarySource == (Object)null)
			{
				throw new InvalidOperationException("No passive data available.");
			}
			Secondary.Clear();
			foreach (PassiveData item in list)
			{
				if (((Il2CppObjectBase)item).Pointer != ((Il2CppObjectBase)PrimarySource).Pointer)
				{
					Secondary.Add(item);
				}
			}
			int key = (int)PrimarySource.ePassive;
			if (!_nativeCopies.TryGetValue(key, out var value))
			{
				value = ((Il2CppObjectBase)Object.Instantiate<PassiveData>(PrimarySource)).Cast<PassiveData>();
				((Object)value).name = "GuzPassive";
				((Object)value).hideFlags = (HideFlags)32;
				_nativeCopies[key] = value;
			}
			Passive = value;
			PassivePtr = ((Il2CppObjectBase)value).Pointer;
			return value;
		}

		private static void CollectWeapons(DataManager dm)
		{
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Expected O, but got Unknown
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Invalid comparison between Unknown and I4
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			Weapons.Clear();
			List<WeaponData> unsortedWeapons = dm.unsortedWeapons;
			if (unsortedWeapons == null || dm.weapons == null)
			{
				return;
			}
			List<string> list = new List<string>();
			for (int i = 0; i < 2; i++)
			{
				if (Weapons.Count != 0)
				{
					break;
				}
				list.Clear();
				for (int j = 0; j < unsortedWeapons.Count; j++)
				{
					WeaponData val = unsortedWeapons[j];
					if (!((Object)(object)val == (Object)null) && (int)val.eWeapon != -1 && dm.weapons.ContainsKey(val.eWeapon))
					{
						if (i == 0 && !((UnlockableBase)val).isEnabled)
						{
							list.Add(((object)val.eWeapon/*cast due to .constrained prefix*/).ToString());
						}
						else
						{
							Weapons.Add(val);
						}
					}
				}
			}
			if (list.Count > 0 && Weapons.Count > 0)
			{
				ManualLogSource l = Plugin.L;
				bool flag = default(bool);
				BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(63, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Weapons the game has switched off are not offered in the menu: ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(string.Join(", ", list));
				}
				l.LogInfo(val2);
			}
		}

		private static void SelectWeapon(DataManager dm, CharacterData data, CharacterData baseData)
		{
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			WeaponData weapon = baseData.weapon;
			string text = (Plugin.StartingWeapon.Value ?? "").Trim();
			if (text.Length > 0)
			{
				if (Enum.TryParse<EWeapon>(text, ignoreCase: true, out EWeapon result) && dm.weapons != null && dm.weapons.ContainsKey(result))
				{
					weapon = dm.weapons[result];
				}
				else
				{
					WarnOnce($"StartingWeapon '{text}' not recognised; using {BaseId}'s weapon.");
				}
			}
			data.weapon = weapon;
		}

		public static void ApplyLoadout()
		{
			//IL_0013: 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: Expected O, but got Unknown
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			if (Injected)
			{
				DataManager instance = DataManager.Instance;
				CharacterData baseData = instance.characterData[BaseId];
				Data.passive = SelectPassives(baseData);
				SelectWeapon(instance, Data, baseData);
				ManualLogSource l = Plugin.L;
				bool flag = default(bool);
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(59, 3, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Loadout from the next run: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(PassiveCount);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" of ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(AllPassiveSources.Count);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" passives, starting weapon ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(((Object)(object)Data.weapon != (Object)null) ? ((object)Data.weapon.eWeapon/*cast due to .constrained prefix*/).ToString() : "none");
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(".");
				}
				l.LogInfo(val);
			}
		}

		public static bool HasPassive(EPassive p)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)PrimarySource != (Object)null && PrimarySource.ePassive == p)
			{
				return true;
			}
			foreach (PassiveData item in Secondary)
			{
				if (item.ePassive == p)
				{
					return true;
				}
			}
			return false;
		}

		public static bool SetPassive(EPassive passive, bool on)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			return SetPassives((EPassive p) => (p != passive) ? HasPassive(p) : on);
		}

		public static bool SetPassives(Predicate<EPassive> wanted)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			List<EPassive> list = new List<EPassive>();
			foreach (PassiveData allPassiveSource in AllPassiveSources)
			{
				if (!wanted(allPassiveSource.ePassive))
				{
					list.Add(allPassiveSource.ePassive);
				}
			}
			if (list.Count >= AllPassiveSources.Count)
			{
				return false;
			}
			Plugin.WallClimb.Value = !list.Contains((EPassive)8);
			list.Remove((EPassive)8);
			Plugin.ExcludedPassives.Value = string.Join(", ", list);
			ApplyLoadout();
			return true;
		}

		public unsafe static void SetWeapon(EWeapon weapon)
		{
			Plugin.StartingWeapon.Value = ((object)(*(EWeapon*)(&weapon))/*cast due to .constrained prefix*/).ToString();
			ApplyLoadout();
		}

		private static List<SkinData> BuildSkins(DataManager dm)
		{
			//IL_0006: 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_00b7: 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_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Expected O, but got Unknown
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: 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_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			List<SkinData> val = (dm.skinData.ContainsKey(BaseId) ? dm.skinData[BaseId] : null);
			SkinData val2 = null;
			if (val != null)
			{
				for (int i = 0; i < val.Count; i++)
				{
					SkinData val3 = val[i];
					if (!((Object)(object)val3 == (Object)null))
					{
						if ((Object)(object)val2 == (Object)null)
						{
							val2 = val3;
						}
						if ((int)val3.skinType == 0)
						{
							val2 = val3;
							break;
						}
					}
				}
			}
			if ((Object)(object)val2 == (Object)null)
			{
				throw new InvalidOperationException("Base character has no skins: " + ((object)Unsafe.As<ECharacter, ECharacter>(ref BaseId)/*cast due to .constrained prefix*/).ToString());
			}
			SkinData val4 = ((Il2CppObjectBase)Object.Instantiate<SkinData>(val2)).Cast<SkinData>();
			((Object)val4).name = "GuzDefault";
			((Object)val4).hideFlags = (HideFlags)32;
			val4.character = Id;
			val4.skinType = (ESkinType)0;
			val4.unlockRequirement = null;
			((UnlockableBase)val4).price = 0;
			((UnlockableBase)val4).isEnabled = true;
			((UnlockableBase)val4).author = "Guz";
			Il2CppReferenceArray<Material> materials = val2.materials;
			if (materials != null && TintOn)
			{
				try
				{
					Il2CppReferenceArray<Material> val5 = new Il2CppReferenceArray<Material>((long)((Il2CppArrayBase<Material>)(object)materials).Length);
					for (int j = 0; j < ((Il2CppArrayBase<Material>)(object)materials).Length; j++)
					{
						Material val6 = ((Il2CppArrayBase<Material>)(object)materials)[j];
						if (!((Object)(object)val6 == (Object)null))
						{
							Material val7 = new Material(val6);
							((Object)val7).name = ((Object)val6).name + " (Guz)";
							((Object)val7).hideFlags = (HideFlags)32;
							if (val7.HasProperty("_Color"))
							{
								Color color = val7.GetColor("_Color");
								val7.SetColor("_Color", new Color(color.r * Tint.r, color.g * Tint.g, color.b * Tint.b, color.a));
							}
							((Il2CppArrayBase<Material>)(object)val5)[j] = val7;
						}
					}
					val4.materials = val5;
				}
				catch (Exception ex)
				{
					Plugin.L.LogWarning((object)("Tinting Guz's skin failed, using the base colours: " + ex.Message));
					val4.materials = materials;
				}
			}
			List<SkinData> obj = new List<SkinData>();
			obj.Add(val4);
			return obj;
		}

		private static int AddHatOrientations(DataManager dm)
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Expected O, but got Unknown
			//IL_00ae: 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_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			List<HatData> unsortedHats = dm.unsortedHats;
			if (unsortedHats == null)
			{
				return 0;
			}
			int num = 0;
			for (int i = 0; i < unsortedHats.Count; i++)
			{
				HatData val = unsortedHats[i];
				List<HatOrientation> val2 = (((Object)(object)val != (Object)null) ? val.orientations : null);
				if (val2 == null)
				{
					continue;
				}
				HatOrientation val3 = null;
				bool flag = false;
				for (int j = 0; j < val2.Count; j++)
				{
					HatOrientation val4 = val2[j];
					if (val4 != null)
					{
						if (val4.character == Id)
						{
							flag = true;
						}
						else if (val4.character == BaseId)
						{
							val3 = val4;
						}
					}
				}
				if (!flag && val3 != null)
				{
					float num2 = (GuzModel.HasMesh ? GuzModel.HeadScale : 1f);
					HatOrientation val5 = new HatOrientation();
					val5.character = Id;
					val5.meshForHat = val3.meshForHat;
					val5.pos = val3.pos * num2;
					val5.rot = val3.rot;
					val5.scale = val3.scale * num2;
					val2.Add(val5);
					num++;
				}
			}
			return num;
		}

		private static Texture2D LoadPortrait()
		{
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Expected O, but got Unknown
			//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: 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_010c: 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_0124: Expected O, but got Unknown
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Expected O, but got Unknown
			//IL_017e: Expected O, but got Unknown
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			string text = (Plugin.Portrait.Value ?? "").Trim();
			if (text.Length == 0)
			{
				return null;
			}
			bool flag = default(bool);
			try
			{
				if (!Path.IsPathRooted(text))
				{
					string text2 = Path.GetDirectoryName(typeof(Plugin).Assembly.Location);
					if (string.IsNullOrEmpty(text2))
					{
						text2 = Path.Combine(Paths.PluginPath, "Guz");
					}
					text = Path.Combine(text2, text);
				}
				BepInExInfoLogInterpolatedStringHandler val;
				if (!File.Exists(text))
				{
					ManualLogSource l = Plugin.L;
					val = new BepInExInfoLogInterpolatedStringHandler(41, 2, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("No portrait image at ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("; using ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<ECharacter>(BaseId);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'s portrait.");
					}
					l.LogInfo(val);
					return null;
				}
				int width;
				int height;
				byte[] array = PngDecoder.Decode(File.ReadAllBytes(text), out width, out height);
				Texture2D val2 = new Texture2D(width, height, (TextureFormat)4, false);
				val2.LoadRawTextureData(Il2CppStructArray<byte>.op_Implicit(array));
				val2.Apply();
				((Object)val2).name = "GuzPortrait";
				((Object)val2).hideFlags = (HideFlags)32;
				((Texture)val2).wrapMode = (TextureWrapMode)1;
				ManualLogSource l2 = Plugin.L;
				val = new BepInExInfoLogInterpolatedStringHandler(22, 3, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Portrait loaded: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(Path.GetFileName(text));
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" (");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(width);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("x");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(height);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(").");
				}
				l2.LogInfo(val);
				return val2;
			}
			catch (Exception ex)
			{
				ManualLogSource l3 = Plugin.L;
				BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(54, 3, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("Portrait '");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(text);
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("' could not be loaded (");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(ex.Message);
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("); using ");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<ECharacter>(BaseId);
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("'s portrait.");
				}
				l3.LogWarning(val3);
				return null;
			}
		}

		private static bool TryParseColor(string hex, out Color color)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected O, but got Unknown
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Expected O, but got Unknown
			color = Color.white;
			if (string.IsNullOrWhiteSpace(hex))
			{
				return false;
			}
			hex = hex.Trim().TrimStart('#');
			bool flag = default(bool);
			if (hex.Length != 6)
			{
				ManualLogSource l = Plugin.L;
				BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(43, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TintColor '");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(hex);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' is not #RRGGBB; tint disabled.");
				}
				l.LogWarning(val);
				return false;
			}
			if (!int.TryParse(hex, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var result))
			{
				ManualLogSource l2 = Plugin.L;
				BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(43, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TintColor '");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(hex);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' is not #RRGGBB; tint disabled.");
				}
				l2.LogWarning(val);
				return false;
			}
			color = new Color((float)((result >> 16) & 0xFF) / 255f, (float)((result >> 8) & 0xFF) / 255f, (float)(result & 0xFF) / 255f, 1f);
			return true;
		}
	}
	public class GuzExportRunner : MonoBehaviour
	{
		private float _runAt = -1f;

		private bool _done;

		public GuzExportRunner(IntPtr ptr)
			: base(ptr)
		{
		}

		private void Update()
		{
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Expected O, but got Unknown
			//IL_0134: 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_0167: Expected O, but got Unknown
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			if (_done)
			{
				return;
			}
			try
			{
				DataManager instance = DataManager.Instance;
				if ((Object)(object)instance == (Object)null || instance.characterData == null || instance.characterData.Count == 0)
				{
					return;
				}
				if (_runAt < 0f)
				{
					_runAt = Time.realtimeSinceStartup + 4f;
					return;
				}
				if (Time.realtimeSinceStartup < _runAt)
				{
					return;
				}
			}
			catch (Exception ex)
			{
				_done = true;
				Plugin.L.LogError((object)("[export] could not start: " + ex));
				return;
			}
			_done = true;
			try
			{
				DataManager instance2 = DataManager.Instance;
				string text = (Plugin.ExportDir.Value ?? "").Trim();
				if (text.Length == 0)
				{
					text = Path.Combine(Paths.BepInExRootPath, "GuzExport");
				}
				string[] array = Plugin.ExportCharacters.Split(new char[2] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries);
				bool flag = default(bool);
				for (int i = 0; i < array.Length; i++)
				{
					string text2 = array[i].Trim();
					CharacterData val = null;
					ECharacter result;
					if (string.Equals(text2, "Guz", StringComparison.OrdinalIgnoreCase))
					{
						val = Guz.Data;
					}
					else if (Enum.TryParse<ECharacter>(text2, ignoreCase: true, out result) && instance2.characterData.ContainsKey(result))
					{
						val = instance2.characterData[result];
					}
					if ((Object)(object)val == (Object)null)
					{
						ManualLogSource l = Plugin.L;
						BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(29, 1, ref flag);
						if (flag)
						{
							((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[export] unknown character '");
							((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(text2);
							((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("'");
						}
						l.LogWarning(val2);
						continue;
					}
					try
					{
						ModelExport.Run(val, Path.Combine(text, text2));
					}
					catch (Exception ex2)
					{
						ManualLogSource l2 = Plugin.L;
						BepInExErrorLogInterpolatedStringHandler val3 = new BepInExErrorLogInterpolatedStringHandler(18, 2, ref flag);
						if (flag)
						{
							((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[export] ");
							((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(text2);
							((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" failed: ");
							((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<Exception>(ex2);
						}
						l2.LogError(val3);
					}
				}
			}
			catch (Exception ex3)
			{
				Plugin.L.LogError((object)("[export] failed: " + ex3));
			}
			Plugin.L.LogInfo((object)"[export] DONE");
		}
	}
	public class GuzMenuHost : MonoBehaviour
	{
		public GuzMenuHost(IntPtr ptr)
			: base(ptr)
		{
		}

		private void OnGUI()
		{
			GuzMenu.OnGUI();
		}
	}
	internal static class GuzMenu
	{
		private struct Box
		{
			public float X;

			public float Y;

			public float W;

			public float H;

			public Rect Rect => new Rect(X, Y, W, H);

			public Box(float x, float y, float w, float h)
			{
				X = x;
				Y = y;
				W = w;
				H = h;
			}

			public bool Has(Vector2 p)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_000e: 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_0031: Unknown result type (might be due to invalid IL or missing references)
				if (p.x >= X && p.x < X + W && p.y >= Y)
				{
					return p.y < Y + H;
				}
				return false;
			}
		}

		private sealed class Item
		{
			public string Name;

			public string Hint;

			public Texture Icon;

			public bool HasIcon;

			public bool On;

			public bool Usable = true;

			public bool Choice;

			public EPassive Passive;

			public EWeapon Weapon;
		}

		public static CharacterMenu CharacterScreen;

		public static CharacterInfoUI InfoPanel;

		public static bool Preview;

		public static int Repaints;

		public static string Error;

		private static readonly Color White = new Color(1f, 1f, 1f, 1f);

		private static readonly Color Faded = new Color(1f, 1f, 1f, 0.4f);

		private static readonly Color Unpicked = new Color(1f, 1f, 1f, 0.85f);

		private static readonly Color Accent = new Color(1f, 0.82f, 0.29f, 1f);

		private static readonly Color AccentHalf = new Color(1f, 0.82f, 0.29f, 0.55f);

		private static readonly Color AccentSoft = new Color(1f, 0.82f, 0.29f, 0.16f);

		private static readonly Color PanelBg = new Color(0.07f, 0.08f, 0.11f, 0.97f);

		private static readonly Color RowIdle = new Color(1f, 1f, 1f, 0.05f);

		private static readonly Color RowHover = new Color(1f, 1f, 1f, 0.14f);

		private static readonly Color TextOn = new Color(0.95f, 0.95f, 0.95f, 1f);

		private static readonly Color TextOff = new Color(0.58f, 0.6f, 0.65f, 1f);

		private static readonly Color TextUnpicked = new Color(0.8f, 0.81f, 0.84f, 1f);

		private static readonly Color Dim = new Color(0f, 0f, 0f, 0.6f);

		private const float W = 1400f;

		private const float Pad = 24f;

		private const float Top = 100f;

		private const float RowH = 34f;

		private const float Pitch = 38f;

		private const float ColGap = 6f;

		private const float PassiveCol = 222f;

		private const float PassiveBlock = 678f;

		private const float WeaponX = 730f;

		private const float WeaponBlock = 646f;

		private const float WeaponCol = 211.33333f;

		private static readonly List<Item> _passives = new List<Item>();

		private static readonly List<Item> _weapons = new List<Item>();

		private static Item _glide;

		private static Item _lift;

		private static int _on;

		private static string _weaponName = "";

		private static readonly Dictionary<string, GUIContent> _content = new Dictionary<string, GUIContent>();

		private static Texture2D _white;

		private static GUIStyle _title;

		private static GUIStyle _head;

		private static GUIStyle _row;

		private static GUIStyle _note;

		private static GUIStyle _right;

		private static GUIStyle _center;

		private static float _styleScale;

		private static bool _failed;

		private static bool _shown;

		private static bool _open;

		private static bool _changed;

		private static int _frame = -1;

		private static bool _visible;

		private static bool _paint;

		private static bool _click;

		private static Vector2 _mouse;

		private static float _s = 1f;

		private static float _ox;

		private static float _oy;

		private static Item _hot;

		private static string _flash;

		private static float _flashUntil;

		private static bool _press;

		private static bool _drag;

		private static Vector2 _pressAt;

		private static Vector2 _grab;

		private static float _bx = -1f;

		private static float _by;

		private static GameObject _blocker;

		private static RectTransform _blockRect;

		private static bool _noBlocker;

		private static bool _blocking;

		private static Box _blocked;

		private static bool _snapped;

		private static float _previewSince;

		public static void OnGUI()
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Invalid comparison between Unknown and I4
			//IL_003a: 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_0072: Invalid comparison between Unknown and I4
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Invalid comparison between Unknown and I4
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Invalid comparison between Unknown and I4
			//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_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			if (_failed)
			{
				return;
			}
			try
			{
				if (!Visible())
				{
					if (_shown)
					{
						Hide();
					}
					return;
				}
				Event current = Event.current;
				if (current == null)
				{
					return;
				}
				EventType type = current.type;
				if ((int)type != 7 && (int)type != 0 && (int)type != 1 && (int)type != 3)
				{
					return;
				}
				if (!_shown)
				{
					_shown = true;
					_open = Preview;
					_previewSince = Time.realtimeSinceStartup;
					Refresh();
				}
				_paint = (int)type == 7;
				_click = (int)type == 0 && current.button == 0;
				_mouse = current.mousePosition;
				float num = (Preview ? (Time.realtimeSinceStartup - _previewSince) : 0f);
				bool flag = _paint && _open && !_snapped && num >= 6f && Plugin.PhotoPrefix.Length > 0;
				if (flag)
				{
					Refresh();
				}
				float num2 = Screen.width;
				float num3 = Screen.height;
				if (_open)
				{
					Panel(current, type, num2, num3);
				}
				else
				{
					Button(current, type, num2, num3);
				}
				if (_paint)
				{
					Repaints++;
					GUI.color = White;
					if (flag)
					{
						Snapshot((int)num2, (int)num3);
					}
					if (num >= 12f)
					{
						Preview = false;
						Hide();
					}
				}
			}
			catch (Exception ex)
			{
				_failed = true;
				Error = ex.ToString();
				Plugin.L.LogError((object)("The setup menu stopped after an error: " + ex));
				try
				{
					Hide();
				}
				catch
				{
				}
			}
		}

		private static bool Visible()
		{
			int frameCount = Time.frameCount;
			if (frameCount == _frame)
			{
				return _visible;
			}
			_frame = frameCount;
			_visible = false;
			if (!Guz.Injected)
			{
				return false;
			}
			if (Preview)
			{
				return _visible = true;
			}
			CharacterMenu characterScreen = CharacterScreen;
			if ((Object)(object)characterScreen == (Object)null)
			{
				return false;
			}
			try
			{
				if (((Component)characterScreen).gameObject.activeInHierarchy)
				{
					MyButtonCharacter selectedButton = characterScreen.selectedButton;
					_visible = (Object)(object)selectedButton != (Object)null && Guz.IsGuz(selectedButton.characterData);
				}
			}
			catch
			{
				CharacterScreen = null;
			}
			return _visible;
		}

		private static void Hide()
		{
			_shown = (_open = (_press = (_changed = false)));
			if (!_blocking)
			{
				return;
			}
			_blocking = false;
			try
			{
				_blocker.SetActive(false);
			}
			catch
			{
			}
		}

		private static void Open()
		{
			_open = true;
			Refresh();
		}

		private static void Close()
		{
			_open = false;
			if (!_changed)
			{
				return;
			}
			_changed = false;
			try
			{
				CharacterMenu characterScreen = CharacterScreen;
				CharacterInfoUI infoPanel = InfoPanel;
				if (!((Object)(object)characterScreen == (Object)null) && !((Object)(object)infoPanel == (Object)null))
				{
					MyButtonCharacter selectedButton = characterScreen.selectedButton;
					if ((Object)(object)selectedButton != (Object)null && Guz.IsGuz(selectedButton.characterData))
					{
						infoPanel.OnCharacterSelected(selectedButton);
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.L.LogWarning((object)("The character panel could not be refreshed: " + ex.Message));
			}
		}

		private unsafe static void Refresh()
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Invalid comparison between Unknown and I4
			//IL_0092: 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_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: 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_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_0218: Unknown result type (might be due to invalid IL or missing references)
			//IL_0251: Unknown result type (might be due to invalid IL or missing references)
			_passives.Clear();
			foreach (PassiveData allPassiveSource in Guz.AllPassiveSources)
			{
				EPassive ePassive = allPassiveSource.ePassive;
				string text = Read((Func<string>)allPassiveSource.GetDescription, "");
				if ((int)ePassive == 8)
				{
					text += " Off by default: at the top of a wall or slope it throws Guz into the air.";
				}
				_passives.Add(new Item
				{
					Name = Read((Func<string>)allPassiveSource.GetName, ((object)(*(EPassive*)(&ePassive))/*cast due to .constrained prefix*/).ToString()),
					Hint = text,
					Icon = allPassiveSource.icon,
					Passive = ePassive
				});
			}
			_weapons.Clear();
			foreach (WeaponData weapon in Guz.Weapons)
			{
				_weapons.Add(new Item
				{
					Name = Read((Func<string>)((UnlockableBase)weapon).GetName, ((object)weapon.eWeapon/*cast due to .constrained prefix*/).ToString()),
					Hint = Read((Func<string>)((UnlockableBase)weapon).GetDescription, ""),
					Icon = weapon.icon,
					Weapon = weapon.eWeapon,
					Choice = true
				});
			}
			foreach (Item passife in _passives)
			{
				passife.HasIcon = (Object)(object)passife.Icon != (Object)null;
			}
			foreach (Item weapon2 in _weapons)
			{
				weapon2.HasIcon = (Object)(object)weapon2.Icon != (Object)null;
			}
			_glide = new Item
			{
				Name = "Glide (" + NameOf((EPassive)10) + ")",
				Passive = (EPassive)10,
				Hint = "Holding jump in the air slows Guz's fall to a glide. Off, he still gets the passive's damage bonus while airborne."
			};
			_lift = new Item
			{
				Name = "Hover (" + NameOf((EPassive)21) + ")",
				Passive = (EPassive)21,
				Hint = "Holding jump keeps lifting Guz for as long as he is moving upwards. Off, he still gets the passive's chest drops."
			};
			Sync();
		}

		private unsafe static string NameOf(EPassive passive)
		{
			//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)
			foreach (Item passife in _passives)
			{
				if (passife.Passive == passive)
				{
					return passife.Name;
				}
			}
			return ((object)(*(EPassive*)(&passive))/*cast due to .constrained prefix*/).ToString();
		}

		private static string Read(Func<string> get, string fallback = "")
		{
			string text = null;
			try
			{
				text = get();
			}
			catch
			{
			}
			if (!string.IsNullOrWhiteSpace(text))
			{
				return Regex.Replace(text, "<[^>]+>", "").Trim();
			}
			return fallback;
		}

		private unsafe static void Sync()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: 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_00a3: Unknown result type (might be due to invalid IL or missing references)
			_on = 0;
			foreach (Item passife in _passives)
			{
				passife.On = Guz.HasPassive(passife.Passive);
				if (passife.On)
				{
					_on++;
				}
			}
			WeaponData weapon = Guz.Data.weapon;
			EWeapon val = (EWeapon)((!((Object)(object)weapon != (Object)null)) ? (-1) : ((int)weapon.eWeapon));
			_weaponName = ((object)(*(EWeapon*)(&val))/*cast due to .constrained prefix*/).ToString();
			foreach (Item weapon2 in _weapons)
			{
				weapon2.On = weapon2.Weapon == val;
				if (weapon2.On)
				{
					_weaponName = weapon2.Name;
				}
			}
			_glide.On = Plugin.Glide.Value;
			_glide.Usable = Guz.HasPassive((EPassive)10);
			_lift.On = Plugin.Hover.Value;
			_lift.Usable = Guz.HasPassive((EPassive)21);
		}

		private static void Changed()
		{
			_changed = true;
			Sync();
		}

		private static void Button(Event e, EventType type, float sw, float sh)
		{
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: 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_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: 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_0261: Invalid comparison between Unknown and I4
			//IL_0321: Unknown result type (might be due to invalid IL or missing references)
			//IL_0323: Invalid comparison between Unknown and I4
			//IL_0210: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			_s = Math.Max(0.5f, Math.Min(sw / 1920f, sh / 1080f));
			Styles();
			if (_bx < 0f)
			{
				_bx = Math.Clamp(Plugin.MenuButtonX.Value, 0f, 1f);
				_by = Math.Clamp(Plugin.MenuButtonY.Value, 0f, 1f);
			}
			float num = 520f * _s;
			float num2 = 40f * _s;
			Box r = new Box(Math.Clamp(_bx * sw - num / 2f, 0f, Math.Max(0f, sw - num)), Math.Clamp(_by * sh, 0f, Math.Max(0f, sh - num2)), num, num2);
			bool flag = r.Has(_mouse);
			Block(r, sw, sh);
			Fill(r, PanelBg);
			Frame(r, 2f * _s, (flag || _press) ? Accent : AccentHalf);
			Label(new Box(r.X + 14f * _s, r.Y, 150f * _s, num2), "GUZ SETUP", _head, Accent);
			Label(new Box(r.X + 150f * _s, r.Y, num - 164f * _s, num2), (flag && !_drag) ? "click to change, drag to move" : $"{_on}/{_passives.Count} passives  ·  {_weaponName}", _right, TextOn);
			if ((int)type == 0)
			{
				if (flag && e.button == 0)
				{
					_press = true;
					_drag = false;
					_pressAt = _mouse;
					_grab.x = _mouse.x - (r.X + num / 2f);
					_grab.y = _mouse.y - r.Y;
					e.Use();
				}
			}
			else if ((int)type == 3 && _press)
			{
				float num3 = _mouse.x - _pressAt.x;
				float num4 = _mouse.y - _pressAt.y;
				if (!_drag && num3 * num3 + num4 * num4 > 36f)
				{
					_drag = true;
				}
				if (_drag)
				{
					_bx = Math.Clamp((_mouse.x - _grab.x) / sw, 0f, 1f);
					_by = Math.Clamp((_mouse.y - _grab.y) / sh, 0f, 1f);
				}
				e.Use();
			}
			else if ((int)type == 1 && _press)
			{
				_press = false;
				if (_drag)
				{
					Plugin.MenuButtonX.Value = (float)Math.Round(_bx, 3);
					Plugin.MenuButtonY.Value = (float)Math.Round(_by, 3);
				}
				else if (flag)
				{
					Open();
				}
				_drag = false;
				e.Use();
			}
		}

		private static void Panel(Event e, EventType type, float sw, float sh)
		{
			//IL_0111: 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_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: Unknown result type (might be due to invalid IL or missing references)
			//IL_0344: 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_0401: Unknown result type (might be due to invalid IL or missing references)
			//IL_042e: 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_0490: Unknown result type (might be due to invalid IL or missing references)
			//IL_0597: Unknown result type (might be due to invalid IL or missing references)
			//IL_053e: Unknown result type (might be due to invalid IL or missing references)
			//IL_056c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0504: Unknown result type (might be due to invalid IL or missing references)
			//IL_060c: Unknown result type (might be due to invalid IL or missing references)
			int num = (_passives.Count + 2) / 3;
			int num2 = (_weapons.Count + 2) / 3;
			float num3 = 100f + (float)num * 38f + 10f;
			float num4 = Math.Max(num3 + 26f + 34f, 100f + (float)num2 * 38f - 4f) + 14f;
			float num5 = num4 + 66f + 18f;
			_s = Math.Min(Math.Min(sw / 1920f, sh / 1080f), Math.Min(sw * 0.98f / 1400f, sh * 0.96f / num5));
			_ox = (sw - 1400f * _s) / 2f;
			_oy = (sh - num5 * _s) / 2f;
			Styles();
			Box r = new Box(0f, 0f, sw, sh);
			Box r2 = At(0f, 0f, 1400f, num5);
			Block(r, sw, sh);
			_hot = null;
			Fill(r, Dim);
			Fill(r2, PanelBg);
			Frame(r2, 2f * _s, Accent);
			Label(At(24f, 12f, 400f, 38f), "GUZ SETUP", _title, Accent);
			Label(At(830f, 12f, 500f, 38f), "Changes count from your next run", _right, TextOff);
			bool flag = Small(At(1340f, 13f, 36f, 36f), "X");
			Fill(At(24f, 58f, 1352f, 1f), RowHover);
			Label(At(24f, 64f, 300f, 30f), $"PASSIVES   {_on} / {_passives.Count}", _head, TextOn);
			bool flag2 = Small(At(490f, 66f, 96f, 26f), "ALL ON");
			bool flag3 = Small(At(592f, 66f, 110f, 26f), "DEFAULT");
			for (int i = 0; i < _passives.Count; i++)
			{
				Item item = _passives[i];
				if (Row(At(24f + (float)(i % 3) * 228f, 100f + (float)(i / 3) * 38f, 222f, 34f), item))
				{
					if (Guz.SetPassive(item.Passive, !item.On))
					{
						Changed();
					}
					else
					{
						Flash("Guz needs at least one passive.");
					}
				}
			}
			Label(At(24f, num3, 678f, 26f), "WHILE HOLDING JUMP", _head, TextOff);
			float num6 = 336f;
			if (Row(At(24f, num3 + 26f, num6, 34f), _glide))
			{
				Plugin.Glide.Value = !Plugin.Glide.Value;
				Sync();
			}
			if (Row(At(24f + num6 + 6f, num3 + 26f, num6, 34f), _lift))
			{
				Plugin.Hover.Value = !Plugin.Hover.Value;
				Sync();
			}
			Label(At(730f, 64f, 646f, 30f), "STARTING WEAPON", _head, TextOn);
			Label(At(730f, 64f, 646f, 30f), _weaponName, _right, Accent);
			for (int j = 0; j < _weapons.Count; j++)
			{
				Item item2 = _weapons[j];
				if (Row(At(730f + (float)(j % 3) * 217.33333f, 100f + (float)(j / 3) * 38f, 211.33333f, 34f), item2) && !item2.On)
				{
					Guz.SetWeapon(item2.Weapon);
					Changed();
				}
			}
			Fill(At(24f, num4, 1352f, 66f), RowIdle);
			if (_flash != null && Time.realtimeSinceStartup < _flashUntil)
			{
				Label(At(38f, num4, 1324f, 66f), _flash, _head, Accent);
			}
			else if (_hot != null)
			{
				Label(At(38f, num4, 230f, 66f), _hot.Name, _head, Accent);
				Label(At(274f, num4, 1088f, 66f), _hot.Hint, _note, TextOn);
			}
			else
			{
				Label(At(38f, num4, 1324f, 66f), "Click a passive to switch it on or off, click a weapon to start with it. Point at anything to read what it does.", _note, TextOff);
			}
			if (flag2 && Guz.SetPassives((EPassive p) => true))
			{
				Changed();
			}
			if (flag3 && Guz.SetPassives((EPassive p) => (int)p != 8))
			{
				Changed();
			}
			if (_click && (flag || !r2.Has(_mouse)))
			{
				Close();
			}
			if (!_paint)
			{
				e.Use();
			}
		}

		private static void Flash(string text)
		{
			_flash = text;
			_flashUntil = Time.realtimeSinceStartup + 2.5f;
		}

		private static Box At(float x, float y, float w, float h)
		{
			return new Box(_ox + x * _s, _oy + y * _s, w * _s, h * _s);
		}

		private static bool Row(Box r, Item it)
		{
			//IL_0002: 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_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d7: 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_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			bool num = r.Has(_mouse);
			bool flag = num && it.Usable;
			if (num)
			{
				_hot = it;
			}
			if (_paint)
			{
				bool flag2 = it.On && it.Usable;
				Fill(r, flag2 ? AccentSoft : (flag ? RowHover : RowIdle));
				float num2 = (float)Math.Round(r.H * 0.47f);
				float num3 = (r.H - num2) / 2f;
				float num4 = Math.Max(1f, (float)Math.Round(2f * _s));
				Box r2 = new Box(r.X + num3, r.Y + num3, num2, num2);
				Fill(r2, flag2 ? Accent : TextOff);
				if (!flag2)
				{
					Fill(new Box(r2.X + num4, r2.Y + num4, num2 - 2f * num4, num2 - 2f * num4), PanelBg);
				}
				float num5 = r2.X + num2 + num3;
				if (it.HasIcon)
				{
					float num6 = r.H * 0.82f;
					GUI.color = (flag2 ? White : (it.Choice ? Unpicked : Faded));
					GUI.DrawTexture(new Box(num5 - num3 * 0.3f, r.Y + (r.H - num6) / 2f, num6, num6).Rect, it.Icon);
					num5 += num6 + num3 * 0.4f;
				}
				Label(new Box(num5, r.Y, r.X + r.W - num5 - 2f, r.H), it.Name, _row, flag2 ? TextOn : (it.Choice ? TextUnpicked : TextOff));
			}
			if (flag)
			{
				return _click;
			}
			return false;
		}

		private static bool Small(Box r, string text)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: 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_002c: Unknown result type (might be due to invalid IL or missing references)
			bool flag = r.Has(_mouse);
			Fill(r, flag ? RowHover : RowIdle);
			Label(r, text, _center, flag ? Accent : TextOn);
			if (flag)
			{
				return _click;
			}
			return false;
		}

		private static void Fill(Box r, Color color)
		{
			//IL_0019: 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)
			if (_paint)
			{
				if (_white == null)
				{
					_white = Texture2D.whiteTexture;
				}
				GUI.color = color;
				GUI.DrawTexture(r.Rect, (Texture)(object)_white);
			}
		}

		private static void Frame(Box r, float line, Color color)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			Fill(new Box(r.X, r.Y, r.W, line), color);
			Fill(new Box(r.X, r.Y + r.H - line, r.W, line), color);
			Fill(new Box(r.X, r.Y, line, r.H), color);
			Fill(new Box(r.X + r.W - line, r.Y, line, r.H), color);
		}

		private static void Label(Box r, string text, GUIStyle style, Color color)
		{
			//IL_0032: 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_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			//IL_0032: Expected O, but got Unknown
			if (_paint && !string.IsNullOrEmpty(text))
			{
				if (!_content.TryGetValue(text, out var value))
				{
					Dictionary<string, GUIContent> content = _content;
					GUIContent val = new GUIContent(text);
					value = val;
					content[text] = val;
				}
				GUI.color = color;
				GUI.Label(r.Rect, value, style);
			}
		}

		private static void Styles()
		{
			if (_title == null || _styleScale != _s)
			{
				_styleScale = _s;
				_title = Style(26, (TextAnchor)3, bold: true, wrap: false);
				_head = Style(16, (TextAnchor)3, bold: true, wrap: false);
				_row = Style(16, (TextAnchor)3, bold: false, wrap: false);
				_note = Style(15, (TextAnchor)3, bold: false, wrap: true);
				_right = Style(15, (TextAnchor)5, bold: false, wrap: false);
				_center = Style(14, (TextAnchor)4, bold: true, wrap: false);
			}
		}

		private static GUIStyle Style(int size, TextAnchor anchor, bool bold, bool wrap)
		{
			//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_0020: 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_0027: 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_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: 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_005a: Expected O, but got Unknown
			GUIStyle val = new GUIStyle
			{
				fontSize = Math.Max(8, (int)Math.Round((float)size * _s)),
				alignment = anchor,
				fontStyle = (FontStyle)(bold ? 1 : 0),
				wordWrap = wrap,
				clipping = (TextClipping)1,
				richText = false
			};
			val.normal.textColor = White;
			return val;
		}

		private static void Block(Box r, float sw, float sh)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected O, but got Unknown
			//IL_0064: 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_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: 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_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			if (_noBlocker || !_paint)
			{
				return;
			}
			try
			{
				if ((Object)(object)_blocker == (Object)null)
				{
					_blocker = new GameObject("GuzMenuBlocker");
					Object.DontDestroyOnLoad((Object)(object)_blocker);
					Canvas obj = _blocker.AddComponent<Canvas>();
					obj.renderMode = (RenderMode)0;
					obj.sortingOrder = 32000;
					_blocker.AddComponent<GraphicRaycaster>();
					GameObject val = new GameObject("Shape");
					val.transform.SetParent(_blocker.transform, false);
					((Graphic)val.AddComponent<RawImage>()).color = new Color(0f, 0f, 0f, 0.01f);
					_blockRect = val.GetComponent<RectTransform>();
					_blocked = new Box(-1f, -1f, -1f, -1f);
					_blocking = true;
				}
				if (!_blocking)
				{
					_blocker.SetActive(true);
					_blocking = true;
				}
				if (r.X != _blocked.X || r.Y != _blocked.Y || r.W != _blocked.W || r.H != _blocked.H)
				{
					_blocked = r;
					_blockRect.anchorMin = Point(r.X / sw, 1f - (r.Y + r.H) / sh);
					_blockRect.anchorMax = Point((r.X + r.W) / sw, 1f - r.Y / sh);
					_blockRect.offsetMin = Point(0f, 0f);
					_blockRect.offsetMax = Point(0f, 0f);
				}
			}
			catch (Exception ex)
			{
				_noBlocker = true;
				Plugin.L.LogWarning((object)("Clicks on the setup menu will also reach the game's menu behind it: " + ex.Message));
			}
		}

		private static Vector2 Point(float x, float y)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			return new Vector2
			{
				x = x,
				y = y
			};
		}

		private static void Snapshot(int width, int height)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			//IL_0021: 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_00f5: Expected O, but got Unknown
			//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_007e: 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)
			_snapped = true;
			Texture2D val = null;
			try
			{
				val = new Texture2D(width, height, (TextureFormat)4, false);
				val.ReadPixels(new Rect(0f, 0f, (float)width, (float)height), 0, 0);
				val.Apply();
				Il2CppStructArray<Color32> pixels = val.GetPixels32();
				byte[] array = new byte[width * height * 4];
				for (int i = 0; i < height; i++)
				{
					int num = (height - 1 - i) * width;
					int num2 = i * width * 4;
					int num3 = 0;
					while (num3 < width)
					{
						Color32 val2 = ((Il2CppArrayBase<Color32>)(object)pixels)[num + num3];
						array[num2] = val2.r;
						array[num2 + 1] = val2.g;
						array[num2 + 2] = val2.b;
						array[num2 + 3] = byte.MaxValue;
						num3++;
						num2 += 4;
					}
				}
				string path = Plugin.PhotoPrefix + "_menu.png";
				Directory.CreateDirectory(Path.GetDirectoryName(path));
				File.WriteAllBytes(path, PngEncoder.Encode(array, width, height));
				ManualLogSource l = Plugin.L;
				bool flag = default(bool);
				BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(12, 3, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[photo] ");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(Path.GetFileName(path));
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" (");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(width);
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("x");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(height);
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(")");
				}
				l.LogInfo(val3);
			}
			catch (Exception ex)
			{
				Plugin.L.LogWarning((object)("[photo] no picture of the setup menu: " + ex.Message));
			}
			finally
			{
				if ((Object)(object)val != (Object)null)
				{
					Object.Destroy((Object)(object)val);
				}
			}
		}
	}
	internal static class GuzModel
	{
		public static Mesh Mesh;

		public static Mesh HatMesh;

		public static Texture2D Texture;

		public static Material Material;

		public static GameObject Prefab;

		public static float HeadScale = 1f;

		private static GameObject _holder;

		public static bool HasMesh => (Object)(object)Mesh != (Object)null;

		public static bool HasTexture => (Object)(object)Texture != (Object)null;

		public static string Resolve(string file)
		{
			file = (file ?? "").Trim();
			if (file.Length == 0)
			{
				return null;
			}
			if (Path.IsPathRooted(file))
			{
				return file;
			}
			string text = Path.GetDirectoryName(typeof(Plugin).Assembly.Location);
			if (string.IsNullOrEmpty(text))
			{
				text = Path.Combine(Paths.PluginPath, "Guz");
			}
			return Path.Combine(text, file);
		}

		public static void Apply(CharacterData baseData, CharacterData data, SkinData skin)
		{
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Expected O, but got Unknown
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Expected O, but got Unknown
			//IL_0241: Unknown result type (might be due to invalid IL or missing references)
			//IL_0248: Expected O, but got Unknown
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0347: Unknown result type (might be due to invalid IL or missing references)
			//IL_034e: Expected O, but got Unknown
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Expected O, but got Unknown
			//IL_029b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a5: Expected O, but got Unknown
			//IL_0376: Unknown result type (might be due to invalid IL or missing references)
			//IL_037b: 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_0422: Unknown result type (might be due to invalid IL or missing references)
			ManualLogSource l = Plugin.L;
			string text = Resolve(Plugin.ModelTexture.Value);
			string text2 = Resolve(Plugin.ModelMesh.Value);
			bool flag = text != null && File.Exists(text);
			bool flag2 = text2 != null && File.Exists(text2);
			if (!flag && !flag2)
			{
				return;
			}
			GameObject prefab = baseData.prefab;
			if ((Object)(object)prefab == (Object)null)
			{
				l.LogWarning((object)"Custom model skipped: the base character has no prefab.");
				return;
			}
			bool flag3 = default(bool);
			try
			{
				if (flag)
				{
					Texture = LoadTexture(text, "t_guz");
				}
			}
			catch (Exception ex)
			{
				BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(38, 2, ref flag3);
				if (flag3)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Model texture '");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' could not be loaded: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
				}
				l.LogWarning(val);
			}
			_holder = new GameObject("GuzAssets");
			_holder.SetActive(false);
			Object.DontDestroyOnLoad((Object)(object)_holder);
			GameObject val2 = ((Il2CppObjectBase)Object.Instantiate<GameObject>(prefab, _holder.transform)).Cast<GameObject>();
			((Object)val2).name = "B_Guz";
			SkinnedMeshRenderer componentInChildren = val2.GetComponentInChildren<SkinnedMeshRenderer>(true);
			if ((Object)(object)componentInChildren == (Object)null)
			{
				l.LogWarning((object)"Custom model skipped: no skinned mesh on the base prefab.");
				return;
			}
			if (flag2)
			{
				try
				{
					Mesh = BuildMesh(text2, componentInChildren, "GuzMesh");
					componentInChildren.sharedMesh = Mesh;
					data.meshDefault = Mesh;
					data.meshLow = Mesh;
					data.meshLowest = Mesh;
				}
				catch (Exception ex2)
				{
					Mesh = null;
					BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(47, 3, ref flag3);
					if (flag3)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Model mesh '");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text2);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' could not be loaded, keeping ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<ECharacter>(baseData.eCharacter);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'s: ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex2.Message);
					}
					l.LogWarning(val);
				}
				string text3 = Resolve(Plugin.ModelHatMesh.Value);
				if ((Object)(object)Mesh != (Object)null && text3 != null && File.Exists(text3))
				{
					try
					{
						HatMesh = BuildMesh(text3, componentInChildren, "GuzMeshUnderHat");
						data.meshLow = HatMesh;
						data.meshLowest = HatMesh;
					}
					catch (Exception ex3)
					{
						BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(64, 2, ref flag3);
						if (flag3)
						{
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Mesh for under hats '");
							((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text3);
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' could not be loaded, using the full one: ");
							((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex3.Message);
						}
						l.LogWarning(val);
					}
				}
			}
			if ((Object)(object)Texture != (Object)null)
			{
				try
				{
					Material = new Material(((Renderer)componentInChildren).sharedMaterial);
					((Object)Material).name = "m_guz";
					((Object)Material).hideFlags = (HideFlags)32;
					SetTexture(Material, (Texture)(object)Texture);
					Il2CppReferenceArray<Material> val3 = new Il2CppReferenceArray<Material>(1L);
					((Il2CppArrayBase<Material>)(object)val3)[0] = Material;
					((Renderer)componentInChildren).sharedMaterials = val3;
					if ((Object)(object)skin != (Object)null)
					{
						Il2CppReferenceArray<Material> val4 = new Il2CppReferenceArray<Material>(1L);
						((Il2CppArrayBase<Material>)(object)val4)[0] = Material;
						skin.materials = val4;
					}
				}
				catch (Exception ex4)
				{
					l.LogWarning((object)("Model material could not be set up: " + ex4.Message));
				}
			}
			Prefab = val2;
			data.prefab = val2;
			BepInExInfoLogInterpolatedStringHandler val5 = new BepInExInfoLogInterpolatedStringHandler(30, 3, ref flag3);
			if (flag3)
			{
				((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("Custom model: mesh ");
				((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(((Object)(object)Mesh != (Object)null) ? (Mesh.vertexCount + " vertices") : ("from " + ((object)baseData.eCharacter/*cast due to .constrained prefix*/).ToString()));
				((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(((Object)(object)HatMesh != (Object)null) ? (" (" + HatMesh.vertexCount + " under hats)") : "");
				((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(", ");
				((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("texture ");
				((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(((Object)(object)Texture != (Object)null) ? (((Texture)Texture).width + "x" + ((Texture)Texture).height) : ("from " + ((object)baseData.eCharacter/*cast due to .constrained prefix*/).ToString()));
				((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(".");
			}
			l.LogInfo(val5);
		}

		internal static void SetTexture(Material material, Texture texture)
		{
			string[] array = new string[3] { "_MainTex", "_AlbedoMap", "_BaseMap" };
			foreach (string text in array)
			{
				if (material.HasProperty(text))
				{
					material.SetTexture(text, texture);
				}
			}
		}

		internal static Texture2D LoadTexture(string path, string name)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Expected O, but got Unknown
			int width;
			int height;
			byte[] array = PngDecoder.Decode(File.ReadAllBytes(path), out width, out height);
			Texture2D val = new Texture2D(width, height, (TextureFormat)4, false);
			val.LoadRawTextureData(Il2CppStructArray<byte>.op_Implicit(array));
			val.Apply();
			((Object)val).name = name;
			((Object)val).hideFlags = (HideFlags)32;
			((Texture)val).filterMode = (FilterMode)0;
			((Texture)val).wrapMode = (TextureWrapMode)0;
			return val;
		}

		private static Mesh BuildMesh(string path, SkinnedMeshRenderer renderer, string meshName)
		{
			//IL_0369: Unknown result type (might be due to invalid IL or missing references)
			//IL_036e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0390: Unknown result type (might be due to invalid IL or missing references)
			//IL_0395: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cb: Expected O, but got Unknown
			//IL_060c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0613: Expected O, but got Unknown
			Mesh sharedMesh = renderer.sharedMesh;
			if ((Object)(object)sharedMesh == (Object)null)
			{
				throw new InvalidOperationException("base renderer has no mesh");
			}
			using JsonDocument jsonDocument = JsonDocument.Parse((ReadOnlyMemory<byte>)File.ReadAllBytes(path), default(JsonDocumentOptions));
			JsonElement rootElement = jsonDocument.RootElement;
			JsonElement value;
			float num = (rootElement.TryGetProperty("headScale", out value) ? value.GetSingle() : 1f);
			Il2CppReferenceArray<Transform> bones = renderer.bones;
			Dictionary<string, int> dictionary = new Dictionary<string, int>();
			for (int i = 0; i < ((Il2CppArrayBase<Transform>)(object)bones).Length; i++)
			{
				if ((Object)(object)((Il2CppArrayBase<Transform>)(object)bones)[i] != (Object)null)
				{
					dictionary[((Object)((Il2CppArrayBase<Transform>)(object)bones)[i]).name] = i;
				}
			}
			List<int> list = new List<int>();
			foreach (JsonElement item in rootElement.GetProperty("bones").EnumerateArray())
			{
				string text = item.GetString();
				if (!dictionary.TryGetValue(text, out var value2))
				{
					throw new InvalidDataException("bone '" + text + "' is not part of the base skeleton");
				}
				list.Add(value2);
			}
			float[] array = Floats(rootElement, "vertices");
			float[] array2 = Floats(rootElement, "normals");
			float[] array3 = Floats(rootElement, "uv");
			int num2 = array.Length / 3;
			if (num2 == 0 || array2.Length != array.Length || array3.Length != num2 * 2)
			{
				throw new InvalidDataException("vertex data is inconsistent");
			}
			List<int> list2 = new List<int>();
			foreach (JsonElement item2 in rootElement.GetProperty("triangles").EnumerateArray())
			{
				list2.Add(item2.GetInt32());
			}
			if (list2.Count % 3 != 0)
			{
				throw new InvalidDataException("triangle list is not a multiple of 3");
			}
			foreach (int item3 in list2)
			{
				if (item3 < 0 || item3 >= num2)
				{
					throw new InvalidDataException("triangle index out of range");
				}
			}
			List<byte> list3 = new List<byte>();
			foreach (JsonElement item4 in rootElement.GetProperty("bonesPerVertex").EnumerateArray())
			{
				list3.Add((byte)item4.GetInt32());
			}
			float[] array4 = Floats(rootElement, "weights");
			int num3 = array4.Length / 2;
			int num4 = 0;
			foreach (byte item5 in list3)
			{
				num4 += item5;
			}
			if (list3.Count != num2 || num4 != num3)
			{
				throw new InvalidDataException("bone weight data is inconsistent");
			}
			int bindposeCount = sharedMesh.bindposeCount;
			if (bindposeCount != ((Il2CppArrayBase<Transform>)(object)bones).Length)
			{
				throw new InvalidDataException("base mesh bind poses do not match its bones");
			}
			byte[] array5 = new byte[bindposeCount * 64];
			Marshal.Copy(sharedMesh.GetBindposesArray(), array5, 0, array5.Length);
			Vector3[] array6 = (Vector3[])(object)new Vector3[num2];
			Vector3[] array7 = (Vector3[])(object)new Vector3[num2];
			Vector2[] array8 = (Vector2[])(object)new Vector2[num2];
			for (int j = 0; j < num2; j++)
			{
				array6[j] = new Vector3(array[j * 3], array[j * 3 + 1], array[j * 3 + 2]);
				array7[j] = new Vector3(array2[j * 3], array2[j * 3 + 1], array2[j * 3 + 2]);
				array8[j] = new Vector2(array3[j * 2], array3[j * 2 + 1]);
			}
			Mesh val = new Mesh();
			((Object)val).name = meshName;
			((Object)val).hideFlags = (HideFlags)32;
			val.vertices = Il2CppStructArray<Vector3>.op_Implicit(array6);
			val.normals = Il2CppStructArray<Vector3>.op_Implicit(array7);
			val.uv = Il2CppStructArray<Vector2>.op_Implicit(array8);
			val.triangles = Il2CppStructArray<int>.op_Implicit(list2.ToArray());
			IntPtr intPtr = Marshal.AllocHGlobal(num2);
			IntPtr intPtr2 = Marshal.AllocHGlobal(Math.Max(1, num3) * 8);
			IntPtr intPtr3 = Marshal.AllocHGlobal(array5.Length);
			try
			{
				Marshal.Copy(list3.ToArray(), 0, intPtr, num2);
				for (int k = 0; k < num3; k++)
				{
					int num5 = (int)array4[k * 2 + 1];
					if (num5 < 0 || num5 >= list.Count)
					{
						throw new InvalidDataException("bone index out of range");
					}
					Marshal.WriteInt32(intPtr2, k * 8, BitConverter.SingleToInt32Bits(array4[k * 2]));
					Marshal.WriteInt32(intPtr2, k * 8 + 4, list[num5]);
				}
				val.InternalSetBoneWeights(intPtr, num2, intPtr2, num3);
				Marshal.Copy(array5, 0, intPtr3, array5.Length);
				val.SetBindposesFromScript_NativeArray(intPtr3, bindposeCount);
			}
			finally
			{
				Marshal.FreeHGlobal(intPtr);
				Marshal.FreeHGlobal(intPtr2);
				Marshal.FreeHGlobal(intPtr3);
			}
			val.RecalculateBounds();
			int bindposeCount2 = val.bindposeCount;
			int num6 = (val