Decompiled source of FlatWalk v1.3.0

BepInEx/plugins/FlatWalk.dll

Decompiled 21 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using Enviro;
using HarmonyLib;
using HorizonBasedAmbientOcclusion.Universal;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.Attributes;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Bindings;
using UnityEngine.Events;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(/*Could not decode attribute arguments.*/)]
[assembly: AssemblyTitle("Flat Walk")]
[assembly: AssemblyProduct("Flat Walk")]
[assembly: AssemblyFileVersion("1.3.0")]
[assembly: AssemblyInformationalVersion("1.3.0")]
[assembly: SecurityPermission((SecurityAction)8, SkipVerification = true)]
[assembly: AssemblyVersion("1.3.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : System.Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(/*Could not decode attribute arguments.*/)]
	internal sealed class RefSafetyRulesAttribute : System.Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace FlatWalk
{
	internal static class ShaderIds
	{
		internal static readonly int BaseColor = Shader.PropertyToID("_BaseColor");

		internal static readonly int Color = Shader.PropertyToID("_Color");

		internal static readonly int Color0 = Shader.PropertyToID("_Color0");

		internal static readonly int DrawnBumpScale = Shader.PropertyToID("_DrawnBumpScale");

		internal static readonly int DrawnFineDetail = Shader.PropertyToID("_DrawnFineDetail");

		internal static readonly int DrawnLimbStrength = Shader.PropertyToID("_DrawnLimbStrength");

		internal static readonly int DrawnProtectEyes = Shader.PropertyToID("_DrawnProtectEyes");

		internal static readonly int DrawnStrength = Shader.PropertyToID("_DrawnStrength");

		internal static readonly int FlatBaseSaturation = Shader.PropertyToID("_FlatBaseSaturation");

		internal static readonly int FlatColor = Shader.PropertyToID("_FlatColor");

		internal static readonly int FlatHighlightSaturation = Shader.PropertyToID("_FlatHighlightSaturation");

		internal static readonly int FlatLight = Shader.PropertyToID("_FlatLight");

		internal static readonly int FlatReceiveShadows = Shader.PropertyToID("_FlatReceiveShadows");

		internal static readonly int FlatShadowStrength = Shader.PropertyToID("_FlatShadowStrength");

		internal static readonly int FlatShiny = Shader.PropertyToID("_FlatShiny");

		internal static readonly int FlatShineGleamDelay = Shader.PropertyToID("_FlatShineGleamDelay");

		internal static readonly int LimbRadius = Shader.PropertyToID("_LimbRadius");

		internal static readonly int MainTex = Shader.PropertyToID("_MainTex");

		internal static readonly int NoseOcclusion = Shader.PropertyToID("_NoseOcclusion");

		internal static readonly int NoseOcclusionEnd = Shader.PropertyToID("_NoseOcclusionEnd");

		internal static readonly int NoseOcclusionStart = Shader.PropertyToID("_NoseOcclusionStart");

		internal static readonly int TintColor = Shader.PropertyToID("_TintColor");

		internal static readonly int TintMask0 = Shader.PropertyToID("_TintMask0");

		internal static readonly int TintMask1 = Shader.PropertyToID("_TintMask1");

		internal static readonly int TintMask2 = Shader.PropertyToID("_TintMask2");

		internal static readonly int TintMask3 = Shader.PropertyToID("_TintMask3");
	}
	internal enum FlatPart
	{
		Head,
		Torso,
		Legs,
		Eye,
		Equipment
	}
	internal sealed class FlatRenderer
	{
		internal sealed class Slot
		{
			internal bool DrawnEye;

			internal bool Compatible;

			internal bool Nose;

			internal bool VertexColors;

			internal int CopiedRendererTints;

			internal int AppliedRevision = -1;
		}

		internal Slot[] Slots;

		internal bool ProtectOriginalEyes;

		internal readonly Renderer Renderer;

		internal readonly FlatPart DefaultPart;

		internal Material[] OriginalMaterials;

		internal Material[] FlatMaterials;

		internal readonly List<Material> OwnedMaterials = new List<Material>();

		internal FlatPart[] Parts;

		internal Color[] SourceColors;

		internal Material[] CapturedOriginals;

		internal readonly List<LooksRenderer> LooksOwners = new List<LooksRenderer>();

		internal readonly List<LimbSpline> Splines = new List<LimbSpline>();

		internal readonly List<PropertyBlockHelper> Helpers = new List<PropertyBlockHelper>();

		internal bool OriginalReceiveShadowsCaptured;

		internal bool OriginalReceiveShadows;

		internal bool DrawnBoundsCaptured;

		internal Bounds DrawnOriginalBounds;

		internal Bounds DrawnExpandedBounds;

		internal MeshFilter DrawnMeshFilter;

		internal bool DrawnUsesMeshBounds;

		internal bool DrawnEyesRequested;

		internal PlayerEyes EyesOwner;

		internal HashSet<int> EyeSlots;

		internal FlatRenderer(Renderer renderer, FlatPart defaultPart)
		{
			Renderer = renderer;
			DefaultPart = defaultPart;
		}
	}
	internal abstract class FlatLit
	{
		internal const int ProbeCount = 3;

		internal Color Light = Color.white;

		internal Color TargetLight = Color.white;

		internal bool HasLight;

		internal float NextLightingSample;

		internal int LastSmoothedFrame = -1;

		internal readonly Color[] ProbeLight = (Color[])(object)new Color[3];

		internal int NextProbe;

		internal int ProbesFilled;
	}
	internal sealed class FlatPlayer : FlatLit
	{
		internal float NextRendererDiscovery;

		internal readonly PlayerCharacter Player;

		internal readonly Dictionary<int, FlatRenderer> Renderers = new Dictionary<int, FlatRenderer>();

		internal FlatPlayer(PlayerCharacter player)
		{
			Player = player;
		}
	}
	internal sealed class FlatForeignRenderer
	{
		internal readonly Renderer Renderer;

		internal int[] Slots;

		internal FlatForeignRenderer(Renderer renderer)
		{
			Renderer = renderer;
		}
	}
	internal sealed class FlatForeign : FlatLit
	{
		internal readonly Transform Root;

		internal readonly List<FlatForeignRenderer> Renderers = new List<FlatForeignRenderer>();

		internal Color AppliedLight;

		internal Vector4 AppliedSettings;

		internal bool Applied;

		internal float NextForcedApply;

		internal FlatForeign(Transform root)
		{
			Root = root;
		}
	}
	internal sealed class OriginalHbaoIntensity
	{
		internal readonly HBAO Component;

		internal readonly float Intensity;

		internal readonly bool OverrideState;

		internal OriginalHbaoIntensity(HBAO component)
		{
			Component = component;
			Intensity = ((VolumeParameter<float>)(object)component.intensity).value;
			OverrideState = ((VolumeParameter)component.intensity).overrideState;
		}
	}
	internal sealed class FlatWalkController : MonoBehaviour
	{
		private struct ForeignNode
		{
			internal Transform Transform;

			internal int Child;

			internal bool Visited;
		}

		private const float PlayerRefreshSeconds = 0.5f;

		private const float LightRefreshSeconds = 0.75f;

		private const float DirectionalLightRayDistance = 200f;

		private const float LightFixtureRadius = 0.4f;

		private const float PlayerProbeSpacing = 0.5f;

		private const float ForeignProbeSpacing = 0.5f;

		private const float ShaderLoadRetrySeconds = 5f;

		private const string EmbeddedShaderBundleName = "FlatWalk.FlatWalkShader.bundle";

		private const float HbaoRefreshSeconds = 0.5f;

		private const float HbaoDiscoverySeconds = 10f;

		private const float ForeignRefreshSeconds = 1f;

		private const float ForeignSweepSeconds = 15f;

		private const float ForeignForcedApplySeconds = 0.5f;

		private const int MaxLightsPerPlayer = 32;

		private readonly Dictionary<int, FlatPlayer> players = new Dictionary<int, FlatPlayer>();

		private readonly List<int> stalePlayers = new List<int>();

		private readonly List<Light> lights = new List<Light>();

		private readonly Dictionary<int, HashSet<int>> eyeSlotsByRenderer = new Dictionary<int, HashSet<int>>();

		private readonly HashSet<int> collectedRenderers = new HashSet<int>();

		private readonly List<int> staleRenderers = new List<int>();

		private readonly Dictionary<int, OriginalHbaoIntensity> originalHbaoIntensities = new Dictionary<int, OriginalHbaoIntensity>();

		private readonly List<int> staleHbao = new List<int>();

		private readonly Dictionary<int, FlatForeign> foreign = new Dictionary<int, FlatForeign>();

		private readonly List<int> staleForeign = new List<int>();

		private readonly HashSet<int> classifiedRenderers = new HashSet<int>();

		private readonly HashSet<int> flatShaderIds = new HashSet<int>();

		private readonly HashSet<int> scannedRoots = new HashSet<int>();

		private readonly Dictionary<int, Material> originalByFlatMaterial = new Dictionary<int, Material>();

		private readonly MaterialPropertyBlock propertyBlock = new MaterialPropertyBlock();

		private readonly MaterialPropertyBlock rendererPropertyBlock = new MaterialPropertyBlock();

		private static readonly int[] EquipmentTintIds = new int[5]
		{
			ShaderIds.TintColor,
			ShaderIds.TintMask0,
			ShaderIds.TintMask1,
			ShaderIds.TintMask2,
			ShaderIds.TintMask3
		};

		private readonly List<Material> materialScratch = new List<Material>();

		private readonly Light[] bestLights = (Light[])(object)new Light[32];

		private readonly float[] bestLightValues = new float[32];

		private Il2CppStructArray<RaycastHit> raycastHits;

		private Material unlitTemplate;

		private Material limbTemplate;

		private Material noseTemplate;

		private Material bodyTemplate;

		private Material vertexColorTemplate;

		private AssetBundle shaderBundle;

		private Material eyeTemplate;

		private bool shaderLoadAttempted;

		private float nextShaderLoadRetry;

		private float nextPlayerRefresh;

		private float nextLightRefresh;

		private bool hbaoDiscoveryPending = true;

		private float nextHbaoRefresh;

		private float nextHbaoDiscovery;

		private UnityAction<Scene, LoadSceneMode> hbaoSceneLoadedHandler;

		private Action hbaoPipelineCreatedHandler;

		private readonly Stack<ForeignNode> pendingForeignNodes = new Stack<ForeignNode>();

		private readonly Queue<Renderer> pendingForeignFallback = new Queue<Renderer>();

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

		private float nextForeignRefresh;

		private float nextForeignSweep;

		private bool rootScanUsable = true;

		private string foreignScene;

		private bool materialsReplacedThisPass;

		private static FlatWalkController instance;

		private static readonly int[] EyeVectors = new int[5]
		{
			Shader.PropertyToID("_GridSize"),
			Shader.PropertyToID("_EyeMoodLeft"),
			Shader.PropertyToID("_EyeMoodRight"),
			Shader.PropertyToID("_EyeOffsetLeft"),
			Shader.PropertyToID("_EyeOffsetRight")
		};

		[HideFromIl2Cpp]
		internal static Material OriginalMaterialFor(Material material)
		{
			FlatWalkController flatWalkController = instance;
			if ((Object)(object)flatWalkController == (Object)null || IsNull((Object)(object)material))
			{
				return null;
			}
			Material val = default(Material);
			if (!flatWalkController.IsLiveFlatMaterial(material) || !flatWalkController.originalByFlatMaterial.TryGetValue(((Object)material).GetInstanceID(), ref val))
			{
				return null;
			}
			if (!IsNull((Object)(object)val))
			{
				return val;
			}
			return null;
		}

		[HideFromIl2Cpp]
		private bool IsLiveFlatMaterial(Material material)
		{
			//IL_000b: 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_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			Enumerator<int, FlatPlayer> enumerator = players.Values.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					Enumerator<int, FlatRenderer> enumerator2 = enumerator.Current.Renderers.Values.GetEnumerator();
					try
					{
						while (enumerator2.MoveNext())
						{
							Material[] flatMaterials = enumerator2.Current.FlatMaterials;
							if (flatMaterials == null)
							{
								continue;
							}
							for (int i = 0; i < flatMaterials.Length; i++)
							{
								if ((Object)(object)flatMaterials[i] == (Object)(object)material)
								{
									return true;
								}
							}
						}
					}
					finally
					{
						((System.IDisposable)enumerator2/*cast due to .constrained prefix*/).Dispose();
					}
				}
			}
			finally
			{
				((System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
			}
			return false;
		}

		public FlatWalkController(System.IntPtr pointer)
			: base(pointer)
		{
		}//IL_009b: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a5: Expected O, but got Unknown
		//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b0: Expected O, but got Unknown


		private void Awake()
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected O, but got Unknown
			instance = this;
			hbaoSceneLoadedHandler = DelegateSupport.ConvertDelegate<UnityAction<Scene, LoadSceneMode>>((System.Delegate)(object)new Action<Scene, LoadSceneMode>(OnHbaoSceneLoaded));
			hbaoPipelineCreatedHandler = DelegateSupport.ConvertDelegate<Action>((System.Delegate)new Action(OnHbaoPipelineCreated));
			SceneManager.sceneLoaded += hbaoSceneLoadedHandler;
			RenderPipelineManager.activeRenderPipelineCreated += hbaoPipelineCreatedHandler;
			Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
			raycastHits = new Il2CppStructArray<RaycastHit>(32L);
		}

		private void Update()
		{
			if (!Plugin.Enabled.Value)
			{
				RestoreEverything();
				RestoreHbaoIntensities();
				return;
			}
			UpdateHbaoIntensities();
			if (Time.unscaledTime >= nextPlayerRefresh)
			{
				nextPlayerRefresh = Time.unscaledTime + 0.5f;
				RefreshPlayers();
			}
			if (Time.unscaledTime >= nextLightRefresh)
			{
				nextLightRefresh = Time.unscaledTime + 0.75f;
				RefreshLights();
			}
			if (Time.unscaledTime >= nextForeignRefresh)
			{
				nextForeignRefresh = Time.unscaledTime + 1f;
				RefreshForeign();
			}
			ProcessForeignDiscovery();
		}

		private void LateUpdate()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			if (!Plugin.Enabled.Value)
			{
				return;
			}
			Enumerator<int, FlatPlayer> enumerator = players.Values.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					FlatPlayer current = enumerator.Current;
					if (!IsNull((Object)(object)current.Player) && !IsNull((Object)(object)current.Player.kernal))
					{
						if (Time.unscaledTime >= current.NextLightingSample)
						{
							current.NextLightingSample = Time.unscaledTime + 0.05f;
							current.TargetLight = SampleLighting(current, current.Player.kernal.position + Vector3.up, 0.5f, current.Player.kernal);
						}
						AdvanceLighting(current);
						Apply(current);
					}
				}
			}
			finally
			{
				((System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
			}
			Enumerator<int, FlatForeign> enumerator2 = foreign.Values.GetEnumerator();
			try
			{
				while (enumerator2.MoveNext())
				{
					FlatForeign current2 = enumerator2.Current;
					if (IsNull((Object)(object)current2.Root))
					{
						continue;
					}
					if (!ForeignBounds(current2, out var bounds))
					{
						current2.HasLight = false;
						current2.NextLightingSample = 0f;
						current2.NextProbe = 0;
						current2.ProbesFilled = 0;
						continue;
					}
					if (Time.unscaledTime >= current2.NextLightingSample)
					{
						current2.NextLightingSample = Time.unscaledTime + 0.05f;
						current2.TargetLight = SampleLighting(current2, ((Bounds)(ref bounds)).center, ((Bounds)(ref bounds)).extents.y * 0.5f, current2.Root);
					}
					AdvanceLighting(current2);
					ApplyForeign(current2);
				}
			}
			finally
			{
				((System.IDisposable)enumerator2/*cast due to .constrained prefix*/).Dispose();
			}
		}

		private void OnDestroy()
		{
			if ((Delegate)(object)hbaoSceneLoadedHandler != (Delegate)null)
			{
				SceneManager.sceneLoaded -= hbaoSceneLoadedHandler;
			}
			if ((Delegate)(object)hbaoPipelineCreatedHandler != (Delegate)null)
			{
				RenderPipelineManager.activeRenderPipelineCreated -= hbaoPipelineCreatedHandler;
			}
			RestoreEverything();
			RestoreHbaoIntensities();
			if (!IsNull((Object)(object)eyeTemplate))
			{
				Object.Destroy((Object)(object)eyeTemplate);
				eyeTemplate = null;
			}
			if (!IsNull((Object)(object)unlitTemplate))
			{
				Object.Destroy((Object)(object)unlitTemplate);
				unlitTemplate = null;
			}
			if (!IsNull((Object)(object)limbTemplate))
			{
				Object.Destroy((Object)(object)limbTemplate);
				limbTemplate = null;
			}
			if (!IsNull((Object)(object)noseTemplate))
			{
				Object.Destroy((Object)(object)noseTemplate);
				noseTemplate = null;
			}
			if (!IsNull((Object)(object)bodyTemplate))
			{
				Object.Destroy((Object)(object)bodyTemplate);
				bodyTemplate = null;
			}
			if (!IsNull((Object)(object)vertexColorTemplate))
			{
				Object.Destroy((Object)(object)vertexColorTemplate);
				vertexColorTemplate = null;
			}
			ReleaseShaderBundle();
			if ((Object)(object)instance == (Object)(object)this)
			{
				instance = null;
			}
		}

		[HideFromIl2Cpp]
		internal static void ApplyAfterPlayerLateUpdate(PlayerCharacter player)
		{
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)instance == (Object)null) && Plugin.Enabled.Value && !IsNull((Object)(object)player) && player.looks != null && !IsNull((Object)(object)player.kernal))
			{
				int instanceID = ((Object)player).GetInstanceID();
				FlatPlayer flatPlayer = default(FlatPlayer);
				if (!instance.players.TryGetValue(instanceID, ref flatPlayer))
				{
					flatPlayer = new FlatPlayer(player);
					instance.players.Add(instanceID, flatPlayer);
				}
				instance.DiscoverPlayerRenderers(flatPlayer);
				if (Time.unscaledTime >= flatPlayer.NextLightingSample)
				{
					flatPlayer.NextLightingSample = Time.unscaledTime + 0.05f;
					flatPlayer.TargetLight = instance.SampleLighting(flatPlayer, player.kernal.position + Vector3.up, 0.5f, player.kernal);
				}
				AdvanceLighting(flatPlayer);
				instance.Apply(flatPlayer);
			}
		}

		[HideFromIl2Cpp]
		private void RefreshPlayers()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			stalePlayers.Clear();
			Enumerator<int, FlatPlayer> enumerator = players.Keys.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					int current = enumerator.Current;
					stalePlayers.Add(current);
				}
			}
			finally
			{
				((System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
			}
			if (PlayerCharacter.allPlayerCharacters != null)
			{
				FlatPlayer flatPlayer = default(FlatPlayer);
				for (int i = 0; i < PlayerCharacter.allPlayerCharacters.Count; i++)
				{
					PlayerCharacter val = PlayerCharacter.allPlayerCharacters[i];
					if (!IsNull((Object)(object)val) && val.looks != null && !IsNull((Object)(object)val.kernal))
					{
						int instanceID = ((Object)val).GetInstanceID();
						stalePlayers.Remove(instanceID);
						if (!players.TryGetValue(instanceID, ref flatPlayer))
						{
							flatPlayer = new FlatPlayer(val);
							players.Add(instanceID, flatPlayer);
						}
						DiscoverPlayerRenderers(flatPlayer);
					}
				}
			}
			Enumerator<int> enumerator2 = stalePlayers.GetEnumerator();
			try
			{
				FlatPlayer state = default(FlatPlayer);
				while (enumerator2.MoveNext())
				{
					int current2 = enumerator2.Current;
					if (players.TryGetValue(current2, ref state))
					{
						Restore(state);
						players.Remove(current2);
					}
				}
			}
			finally
			{
				((System.IDisposable)enumerator2/*cast due to .constrained prefix*/).Dispose();
			}
		}

		[HideFromIl2Cpp]
		private void DiscoverPlayerRenderers(FlatPlayer state)
		{
			float unscaledTime = Time.unscaledTime;
			if (!(unscaledTime < state.NextRendererDiscovery))
			{
				state.NextRendererDiscovery = unscaledTime + 0.1f;
				CollectPlayerRenderers(state);
			}
		}

		[HideFromIl2Cpp]
		private void CollectPlayerRenderers(FlatPlayer state)
		{
			materialsReplacedThisPass = false;
			eyeSlotsByRenderer.Clear();
			collectedRenderers.Clear();
			PlayerEyes playerEyes = state.Player.playerEyes;
			if (playerEyes != null && playerEyes.renderers != null)
			{
				int submeshIndex = playerEyes.submeshIndex;
				HashSet<int> val2 = default(HashSet<int>);
				for (int i = 0; i < ((Il2CppArrayBase<Renderer>)(object)playerEyes.renderers).Length; i++)
				{
					Renderer val = ((Il2CppArrayBase<Renderer>)(object)playerEyes.renderers)[i];
					if (!IsNull((Object)(object)val))
					{
						int instanceID = ((Object)val).GetInstanceID();
						if (!eyeSlotsByRenderer.TryGetValue(instanceID, ref val2))
						{
							val2 = new HashSet<int>();
							eyeSlotsByRenderer.Add(instanceID, val2);
						}
						val2.Add(submeshIndex);
					}
				}
			}
			AddLooksRenderers(state, state.Player.looks.headRenderers, FlatPart.Head);
			AddLooksRenderers(state, state.Player.looks.torsoRenderers, FlatPart.Torso);
			AddLooksRenderers(state, state.Player.looks.legsRenderers, FlatPart.Legs);
			AddArmSplines(state);
			PlayerRegistry registry = state.Player.registry;
			if (registry != null)
			{
				AddRenderer(state, (Renderer)(object)registry.fakeHolster, FlatPart.Equipment);
				AddPocketShell(state, registry.backpackPocket);
				AddPocketShell(state, registry.holsterPocket);
				ReleaseUnequippedRenderers(state);
			}
			RepushLookColours(state);
		}

		[HideFromIl2Cpp]
		private void ReleaseUnequippedRenderers(FlatPlayer state)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			staleRenderers.Clear();
			Enumerator<int, FlatRenderer> enumerator = state.Renderers.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					KeyValuePair<int, FlatRenderer> current = enumerator.Current;
					if (current.Value.DefaultPart == FlatPart.Equipment && !collectedRenderers.Contains(current.Key))
					{
						staleRenderers.Add(current.Key);
					}
				}
			}
			finally
			{
				((System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
			}
			Enumerator<int> enumerator2 = staleRenderers.GetEnumerator();
			try
			{
				while (enumerator2.MoveNext())
				{
					int current2 = enumerator2.Current;
					Restore(state.Renderers[current2]);
					state.Renderers.Remove(current2);
				}
			}
			finally
			{
				((System.IDisposable)enumerator2/*cast due to .constrained prefix*/).Dispose();
			}
		}

		[HideFromIl2Cpp]
		private void RepushLookColours(FlatPlayer state)
		{
			if (materialsReplacedThisPass)
			{
				materialsReplacedThisPass = false;
				WriteLookColours(state.Player);
			}
		}

		[HideFromIl2Cpp]
		private static void WriteLookColours(PlayerCharacter player)
		{
			//IL_0020: 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_0044: Unknown result type (might be due to invalid IL or missing references)
			if (IsNull((Object)(object)player) || player.looks == null)
			{
				return;
			}
			PlayerLooks looks = player.looks;
			try
			{
				looks.SetColor(looks.headRenderers, looks.headColor);
				looks.SetColor(looks.torsoRenderers, looks.torsoColor);
				looks.SetColor(looks.legsRenderers, looks.legsColor);
			}
			catch (System.Exception ex)
			{
				Plugin.Log.LogWarning((object)("Flat Walk could not re-apply look colours: " + ex.Message));
			}
		}

		[HideFromIl2Cpp]
		private void AddArmSplines(FlatPlayer state)
		{
			PlayerArms arms = state.Player.arms;
			if (arms != null)
			{
				AddArmSpline(state, arms.leftArmLimbSpline);
				AddArmSpline(state, arms.rightArmLimbSpline);
				AddArmSpline(state, arms.localLeftArmSpline);
				AddArmSpline(state, arms.localRightArmSpline);
			}
		}

		[HideFromIl2Cpp]
		private void AddArmSpline(FlatPlayer state, LimbSpline spline)
		{
			if (!IsNull((Object)(object)spline) && !IsNull((Object)(object)spline.meshRenderer))
			{
				AddRenderer(state, (Renderer)(object)spline.meshRenderer, FlatPart.Torso, null, spline);
			}
		}

		[HideFromIl2Cpp]
		private void AddLooksRenderers(FlatPlayer state, Il2CppReferenceArray<LooksRenderer> looksRenderers, FlatPart part)
		{
			if (looksRenderers == null)
			{
				return;
			}
			for (int i = 0; i < ((Il2CppArrayBase<LooksRenderer>)(object)looksRenderers).Length; i++)
			{
				LooksRenderer val = ((Il2CppArrayBase<LooksRenderer>)(object)looksRenderers)[i];
				if (val == null)
				{
					continue;
				}
				LimbSpline limbSpline = val.limbSpline;
				PropertyBlockHelper propertyBlockHelper = val.propertyBlockHelper;
				AddRenderer(state, val.renderer, part, val, limbSpline, propertyBlockHelper);
				if (!IsNull((Object)(object)limbSpline))
				{
					AddRenderer(state, (Renderer)(object)limbSpline.meshRenderer, part, val, limbSpline, propertyBlockHelper);
				}
				if (IsNull((Object)(object)propertyBlockHelper))
				{
					continue;
				}
				AddRenderer(state, propertyBlockHelper.targetRenderer, part, val, limbSpline, propertyBlockHelper);
				Il2CppReferenceArray<Renderer> additonalRenderers = propertyBlockHelper.additonalRenderers;
				if (additonalRenderers != null)
				{
					for (int j = 0; j < ((Il2CppArrayBase<Renderer>)(object)additonalRenderers).Length; j++)
					{
						AddRenderer(state, ((Il2CppArrayBase<Renderer>)(object)additonalRenderers)[j], part);
					}
				}
			}
		}

		[HideFromIl2Cpp]
		private void AddPocketShell(FlatPlayer state, PropHome home)
		{
			if (!IsNull((Object)(object)home) && !IsNull((Object)(object)home.pinnedProp) && home.pinnedProp.renderers != null)
			{
				Il2CppReferenceArray<Renderer> renderers = home.pinnedProp.renderers;
				for (int i = 0; i < ((Il2CppArrayBase<Renderer>)(object)renderers).Length; i++)
				{
					AddRenderer(state, ((Il2CppArrayBase<Renderer>)(object)renderers)[i], FlatPart.Equipment);
				}
			}
		}

		[HideFromIl2Cpp]
		private void AddRenderer(FlatPlayer state, Renderer renderer, FlatPart part, LooksRenderer looksOwner = null, LimbSpline spline = null, PropertyBlockHelper helper = null)
		{
			if (!IsNull((Object)(object)renderer))
			{
				int instanceID = ((Object)renderer).GetInstanceID();
				collectedRenderers.Add(instanceID);
				FlatRenderer flatRenderer = default(FlatRenderer);
				if (!state.Renderers.TryGetValue(instanceID, ref flatRenderer))
				{
					flatRenderer = new FlatRenderer(renderer, part);
					state.Renderers.Add(instanceID, flatRenderer);
				}
				bool flag = false;
				if (looksOwner != null && !flatRenderer.LooksOwners.Contains(looksOwner))
				{
					flatRenderer.LooksOwners.Add(looksOwner);
					flag = true;
				}
				if (!IsNull((Object)(object)spline) && !flatRenderer.Splines.Contains(spline))
				{
					flatRenderer.Splines.Add(spline);
					flag = true;
				}
				if (!IsNull((Object)(object)helper) && !flatRenderer.Helpers.Contains(helper))
				{
					flatRenderer.Helpers.Add(helper);
					flag = true;
				}
				bool flag2 = flatRenderer.FlatMaterials != null;
				eyeSlotsByRenderer.TryGetValue(instanceID, ref flatRenderer.EyeSlots);
				EnsureMaterials(flatRenderer, part);
				if (flag && flag2 && flatRenderer.FlatMaterials != null)
				{
					AdoptGameMaterialInstances(flatRenderer);
				}
			}
		}

		[HideFromIl2Cpp]
		private void EnsureMaterials(FlatRenderer flat, FlatPart defaultPart)
		{
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			if (IsNull((Object)(object)flat.Renderer))
			{
				return;
			}
			flat.Renderer.GetSharedMaterials(materialScratch);
			if (materialScratch.Count == 0)
			{
				return;
			}
			bool flag = true;
			if (flat.FlatMaterials != null && SameMaterials(materialScratch, flat.FlatMaterials) && flat.DrawnEyesRequested == flag)
			{
				return;
			}
			Restore(flat);
			if (!EnsureTemplates())
			{
				return;
			}
			Il2CppReferenceArray<Material> sharedMaterials = flat.Renderer.sharedMaterials;
			if (sharedMaterials == null || ((Il2CppArrayBase<Material>)(object)sharedMaterials).Length == 0)
			{
				return;
			}
			int length = ((Il2CppArrayBase<Material>)(object)sharedMaterials).Length;
			if (!flat.OriginalReceiveShadowsCaptured)
			{
				flat.OriginalReceiveShadowsCaptured = true;
				flat.OriginalReceiveShadows = flat.Renderer.receiveShadows;
			}
			bool flag2 = flat.CapturedOriginals != null && flat.CapturedOriginals.Length == length;
			Material[] array = (Material[])(object)new Material[length];
			Material val2 = default(Material);
			for (int i = 0; i < length; i++)
			{
				Material val = (flag2 ? flat.CapturedOriginals[i] : null);
				if (IsNull((Object)(object)val))
				{
					val = ((Il2CppArrayBase<Material>)(object)sharedMaterials)[i];
					if (!IsNull((Object)(object)val) && originalByFlatMaterial.TryGetValue(((Object)val).GetInstanceID(), ref val2) && !IsNull((Object)(object)val2))
					{
						val = val2;
					}
				}
				array[i] = val;
			}
			flat.CapturedOriginals = array;
			flat.OriginalMaterials = array;
			flat.FlatMaterials = (Material[])(object)new Material[length];
			flat.Parts = new FlatPart[length];
			flat.SourceColors = (Color[])(object)new Color[length];
			flat.Slots = new FlatRenderer.Slot[length];
			flat.ProtectOriginalEyes = false;
			flat.DrawnEyesRequested = flag;
			HashSet<int> eyeSlots = flat.EyeSlots;
			for (int j = 0; j < length; j++)
			{
				Material val3 = array[j];
				flat.Parts[j] = (IsEyeSlot(eyeSlots, j) ? FlatPart.Eye : defaultPart);
				flat.SourceColors[j] = ReadBaseColor(val3);
				flat.FlatMaterials[j] = CreateFlatMaterial(val3, flat.Parts[j], out var owned);
				Material val4 = flat.FlatMaterials[j];
				FlatRenderer.Slot slot = new FlatRenderer.Slot
				{
					DrawnEye = (flat.Parts[j] == FlatPart.Eye && IsDrawnEye(val4)),
					Compatible = UsesCompatibleCharacterShader(val4),
					Nose = (!IsNull((Object)(object)val4) && !IsNull((Object)(object)noseTemplate) && (Object)(object)val4.shader == (Object)(object)noseTemplate.shader),
					VertexColors = (!IsNull((Object)(object)val4) && !IsNull((Object)(object)vertexColorTemplate) && (Object)(object)val4.shader == (Object)(object)vertexColorTemplate.shader)
				};
				flat.Slots[j] = slot;
				if (flat.Parts[j] == FlatPart.Eye && !slot.DrawnEye)
				{
					flat.ProtectOriginalEyes = true;
				}
				if (owned)
				{
					flat.OwnedMaterials.Add(flat.FlatMaterials[j]);
					originalByFlatMaterial[((Object)flat.FlatMaterials[j]).GetInstanceID()] = val3;
				}
			}
			flat.Renderer.sharedMaterials = new Il2CppReferenceArray<Material>(flat.FlatMaterials);
			flat.Renderer.receiveShadows = Plugin.ReceiveShadows.Value;
			AdoptGameMaterialInstances(flat);
			materialsReplacedThisPass = true;
		}

		[HideFromIl2Cpp]
		private void AdoptGameMaterialInstances(FlatRenderer flat)
		{
			ClearCachedInstances(flat);
			for (int i = 0; i < flat.Splines.Count; i++)
			{
				LimbSpline val = flat.Splines[i];
				if (!IsNull((Object)(object)val))
				{
					SafeSplineMaterial(val);
				}
			}
			for (int j = 0; j < flat.Helpers.Count; j++)
			{
				PropertyBlockHelper val2 = flat.Helpers[j];
				if (!IsNull((Object)(object)val2))
				{
					SafeHelperMaterial(val2);
				}
			}
			for (int k = 0; k < flat.LooksOwners.Count; k++)
			{
				LooksRenderer val3 = flat.LooksOwners[k];
				if (val3 != null)
				{
					SafeLooksMaterial(val3);
				}
			}
			AdoptCurrentMaterials(flat);
		}

		[HideFromIl2Cpp]
		private static void ClearCachedInstances(FlatRenderer flat)
		{
			for (int i = 0; i < flat.Splines.Count; i++)
			{
				LimbSpline val = flat.Splines[i];
				if (!IsNull((Object)(object)val))
				{
					val._materialInstance = null;
				}
			}
			for (int j = 0; j < flat.LooksOwners.Count; j++)
			{
				LooksRenderer val2 = flat.LooksOwners[j];
				if (val2 != null)
				{
					val2._materialInstanceForSimpleRenderer = null;
				}
			}
			for (int k = 0; k < flat.Helpers.Count; k++)
			{
				PropertyBlockHelper val3 = flat.Helpers[k];
				if (!IsNull((Object)(object)val3))
				{
					val3._replacementMaterial = null;
				}
			}
		}

		[HideFromIl2Cpp]
		private static void SafeSplineMaterial(LimbSpline spline)
		{
			try
			{
				_ = spline.materialInstance;
				spline.RefreshShaderMode();
			}
			catch (System.Exception ex)
			{
				Plugin.Log.LogWarning((object)("Flat Walk could not refresh a limb spline material: " + ex.Message));
			}
		}

		[HideFromIl2Cpp]
		private static void SafeLooksMaterial(LooksRenderer owner)
		{
			try
			{
				owner.GetMaterial();
			}
			catch (System.Exception ex)
			{
				Plugin.Log.LogWarning((object)("Flat Walk could not refresh a looks renderer material: " + ex.Message));
			}
		}

		[HideFromIl2Cpp]
		private static void SafeHelperMaterial(PropertyBlockHelper helper)
		{
			try
			{
				_ = helper.replacementMaterial;
			}
			catch (System.Exception ex)
			{
				Plugin.Log.LogWarning((object)("Flat Walk could not refresh a property block helper material: " + ex.Message));
			}
		}

		[HideFromIl2Cpp]
		private void AdoptCurrentMaterials(FlatRenderer flat)
		{
			Il2CppReferenceArray<Material> sharedMaterials = flat.Renderer.sharedMaterials;
			if (sharedMaterials == null || ((Il2CppArrayBase<Material>)(object)sharedMaterials).Length != flat.FlatMaterials.Length)
			{
				return;
			}
			Material val3 = default(Material);
			for (int i = 0; i < ((Il2CppArrayBase<Material>)(object)sharedMaterials).Length; i++)
			{
				Material val = ((Il2CppArrayBase<Material>)(object)sharedMaterials)[i];
				Material val2 = flat.FlatMaterials[i];
				if (!((Object)(object)val == (Object)(object)val2) && !IsNull((Object)(object)val) && !IsNull((Object)(object)val2) && !IsNull((Object)(object)val.shader) && !IsNull((Object)(object)val2.shader) && !((Object)(object)val.shader != (Object)(object)val2.shader))
				{
					if (!flat.OwnedMaterials.Contains(val))
					{
						flat.OwnedMaterials.Add(val);
					}
					if (originalByFlatMaterial.TryGetValue(((Object)val2).GetInstanceID(), ref val3))
					{
						originalByFlatMaterial[((Object)val).GetInstanceID()] = val3;
					}
					flat.FlatMaterials[i] = val;
				}
			}
		}

		[HideFromIl2Cpp]
		private Material CreateFlatMaterial(Material source, FlatPart part, out bool owned)
		{
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Expected O, but got Unknown
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Expected O, but got Unknown
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Expected O, but got Unknown
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Expected O, but got Unknown
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Expected O, but got Unknown
			owned = false;
			if (part == FlatPart.Eye)
			{
				if (!IsNull((Object)(object)eyeTemplate) && !IsNull((Object)(object)source) && !IsNull((Object)(object)source.shader) && ((Object)source.shader).name == "househouse/eyes" && !IsNull((Object)(object)source.GetTexture(ShaderIds.MainTex)))
				{
					Material val = new Material(source)
					{
						shader = eyeTemplate.shader,
						name = "Flat Walk " + ((Object)source).name,
						renderQueue = 2000
					};
					owned = true;
					return val;
				}
				return source;
			}
			Material val2 = MatchDeformingTemplate(source);
			if (!IsNull((Object)(object)val2))
			{
				owned = true;
				return val2;
			}
			if (IsNull((Object)(object)unlitTemplate) && part == FlatPart.Equipment)
			{
				return source;
			}
			if (part != FlatPart.Equipment && UsesCompatibleCharacterShader(source))
			{
				Material val3 = new Material(source)
				{
					name = "Flat Walk " + ((Object)source).name,
					enableInstancing = source.enableInstancing
				};
				SetFloatIfPresent(val3, "_SpecularHighlights", 0f);
				SetFloatIfPresent(val3, "_EnvironmentReflections", 0f);
				SetFloatIfPresent(val3, "_ReceiveShadows", 0f);
				val3.EnableKeyword("_SPECULARHIGHLIGHTS_OFF");
				val3.EnableKeyword("_ENVIRONMENTREFLECTIONS_OFF");
				val3.EnableKeyword("_RECEIVE_SHADOWS_OFF");
				owned = true;
				return val3;
			}
			if (!IsNull((Object)(object)unlitTemplate))
			{
				return unlitTemplate;
			}
			return source;
		}

		[HideFromIl2Cpp]
		private Material MatchDeformingTemplate(Material source)
		{
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Expected O, but got Unknown
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			if (IsNull((Object)(object)source) || IsNull((Object)(object)source.shader))
			{
				return null;
			}
			string name = ((Object)source.shader).name;
			Material val = null;
			if (string.Equals(name, "househouse/PlayerLImb", (StringComparison)4))
			{
				val = limbTemplate;
			}
			else if (string.Equals(name, "househouse/PlayerNose", (StringComparison)4))
			{
				val = noseTemplate;
			}
			else if (string.Equals(name, "househouse/PlayerCharacter", (StringComparison)4))
			{
				val = bodyTemplate;
			}
			else if (string.Equals(name, "househouse/VertexColors", (StringComparison)4))
			{
				val = vertexColorTemplate;
			}
			if (IsNull((Object)(object)val))
			{
				return null;
			}
			Material val2 = new Material(val);
			((Object)val2).name = "Flat Walk " + ((Object)source).name;
			val2.enableInstancing = source.enableInstancing;
			if ((Object)(object)val == (Object)(object)vertexColorTemplate)
			{
				int[] equipmentTintIds = EquipmentTintIds;
				foreach (int num in equipmentTintIds)
				{
					if (source.HasProperty(num))
					{
						val2.SetColor(num, source.GetColor(num));
					}
				}
			}
			return val2;
		}

		[HideFromIl2Cpp]
		private static bool UsesCompatibleCharacterShader(Material material)
		{
			if (IsNull((Object)(object)material) || IsNull((Object)(object)material.shader))
			{
				return false;
			}
			string name = ((Object)material.shader).name;
			if (!string.Equals(name, "househouse/PlayerCharacter", (StringComparison)4) && !string.Equals(name, "househouse/PlayerNose", (StringComparison)4) && !string.Equals(name, "househouse/PlayerLImb", (StringComparison)4))
			{
				return string.Equals(name, "househouse/VertexColors", (StringComparison)4);
			}
			return true;
		}

		[HideFromIl2Cpp]
		private static void SetFloatIfPresent(Material material, string propertyName, float value)
		{
			if (material.HasProperty(propertyName))
			{
				material.SetFloat(propertyName, value);
			}
		}

		[HideFromIl2Cpp]
		private static byte[] ReadEmbeddedShaderBundle()
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			Stream manifestResourceStream = typeof(Plugin).Assembly.GetManifestResourceStream("FlatWalk.FlatWalkShader.bundle");
			try
			{
				if (manifestResourceStream == null)
				{
					return null;
				}
				MemoryStream val = new MemoryStream((int)manifestResourceStream.Length);
				try
				{
					manifestResourceStream.CopyTo((Stream)(object)val);
					return val.ToArray();
				}
				finally
				{
					((System.IDisposable)val)?.Dispose();
				}
			}
			finally
			{
				((System.IDisposable)manifestResourceStream)?.Dispose();
			}
		}

		[HideFromIl2Cpp]
		private unsafe bool EnsureTemplates()
		{
			if (HasAnyTemplate())
			{
				return true;
			}
			if (shaderLoadAttempted)
			{
				if (Time.unscaledTime < nextShaderLoadRetry)
				{
					return false;
				}
				Plugin.Log.LogWarning((object)"Flat Walk's shader templates were unloaded; reloading the bundle.");
				ReleaseShaderBundle();
			}
			shaderLoadAttempted = true;
			nextShaderLoadRetry = Time.unscaledTime + 5f;
			try
			{
				byte[] array = ReadEmbeddedShaderBundle();
				if (array == null)
				{
					Plugin.Log.LogError((object)"Flat Walk's embedded shader bundle (FlatWalk.FlatWalkShader.bundle) is missing from the DLL. Original player materials will remain active.");
					return false;
				}
				fixed (byte* ptr = array)
				{
					ManagedSpanWrapper val = default(ManagedSpanWrapper);
					((ManagedSpanWrapper)(ref val))..ctor((void*)ptr, array.Length);
					System.IntPtr intPtr = AssetBundle.LoadFromMemory_Internal_Injected(ref val, 0u);
					shaderBundle = ((intPtr == System.IntPtr.Zero) ? null : Unmarshal.UnmarshalUnityObject<AssetBundle>(intPtr));
				}
				if (IsNull((Object)(object)shaderBundle))
				{
					Plugin.Log.LogError((object)"Unity returned no AssetBundle for Flat Walk's embedded shader bundle. Original player materials will remain active.");
					return false;
				}
				limbTemplate = LoadTemplate("assets/flatwalklimbmaterial.mat", "FlatWalk/Limb", "Limbs");
				noseTemplate = LoadTemplate("assets/flatwalknosematerial.mat", "FlatWalk/Nose", "Noses");
				bodyTemplate = LoadTemplate("assets/flatwalkcharacterbodymaterial.mat", "FlatWalk/CharacterBody", "Bodies");
				vertexColorTemplate = LoadTemplate("assets/flatwalkvertexcolorsmaterial.mat", "FlatWalk/VertexColors", "Vertex-coloured parts");
				unlitTemplate = LoadTemplate("assets/flatwalkflatmaterial.mat", "FlatWalk/Character", "Equipment");
				eyeTemplate = LoadTemplate("assets/flatwalkeyesmaterial.mat", "FlatWalk/Eyes", "Eyes");
				if (!HasAnyTemplate())
				{
					Plugin.Log.LogError((object)"Flat Walk loaded no usable shaders from its bundle. Original player materials will remain active.");
					ReleaseShaderBundle();
					return false;
				}
				return true;
			}
			catch (System.Exception ex)
			{
				Plugin.Log.LogError((object)("Flat Walk could not load its shader bundle: " + (object)ex));
				ReleaseShaderBundle();
				return false;
			}
		}

		[HideFromIl2Cpp]
		private bool HasAnyTemplate()
		{
			if (IsNull((Object)(object)limbTemplate) && IsNull((Object)(object)noseTemplate) && IsNull((Object)(object)bodyTemplate) && IsNull((Object)(object)vertexColorTemplate) && IsNull((Object)(object)unlitTemplate))
			{
				return !IsNull((Object)(object)eyeTemplate);
			}
			return true;
		}

		[HideFromIl2Cpp]
		private Material LoadTemplate(string assetPath, string shaderName, string subject)
		{
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Expected O, but got Unknown
			//IL_010e: Expected O, but got Unknown
			Material val = shaderBundle.LoadAsset<Material>(assetPath);
			if (IsNull((Object)(object)val) || IsNull((Object)(object)val.shader))
			{
				Plugin.Log.LogWarning((object)string.Concat(new string[5] { "Flat Walk's shader bundle has no ", assetPath, ". ", subject, " stay on the game's lit shader." }));
				return null;
			}
			if (!string.Equals(((Object)val.shader).name, shaderName, (StringComparison)4))
			{
				Plugin.Log.LogWarning((object)string.Concat(new string[5]
				{
					"Flat Walk expected ",
					shaderName,
					" but loaded ",
					((Object)val.shader).name,
					"."
				}));
				return null;
			}
			if (!val.shader.isSupported)
			{
				Plugin.Log.LogWarning((object)(shaderName + " is not supported by the active graphics device. " + subject + " stay on the game's lit shader."));
				return null;
			}
			Material val2 = new Material(val)
			{
				name = "Flat Walk " + shaderName + " Template",
				renderQueue = 2000,
				hideFlags = (HideFlags)61
			};
			Object.DontDestroyOnLoad((Object)val2);
			return val2;
		}

		[HideFromIl2Cpp]
		private void ReleaseShaderBundle()
		{
			if (!IsNull((Object)(object)shaderBundle))
			{
				shaderBundle.Unload(false);
				shaderBundle = null;
			}
		}

		[HideFromIl2Cpp]
		private void RefreshLights()
		{
			lights.Clear();
			Il2CppArrayBase<Light> val = Object.FindObjectsOfType<Light>(true);
			if (val == null)
			{
				return;
			}
			for (int i = 0; i < val.Length; i++)
			{
				Light val2 = val[i];
				if (!IsNull((Object)(object)val2))
				{
					lights.Add(val2);
				}
			}
		}

		[HideFromIl2Cpp]
		private void RefreshForeign()
		{
			//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)
			CollectFlatShaders();
			if (flatShaderIds.Count != 0)
			{
				Scene activeScene = SceneManager.GetActiveScene();
				string name = ((Scene)(ref activeScene)).name;
				if (!string.Equals(name, foreignScene, (StringComparison)4))
				{
					foreignScene = name;
					foreign.Clear();
					classifiedRenderers.Clear();
					scannedRoots.Clear();
					pendingForeignNodes.Clear();
					pendingForeignFallback.Clear();
					nextForeignSweep = Time.unscaledTime + 15f;
				}
				ValidateForeign();
				bool flag = Time.unscaledTime >= nextForeignSweep && pendingForeignNodes.Count == 0 && pendingForeignFallback.Count == 0;
				if (flag)
				{
					nextForeignSweep = Time.unscaledTime + 15f;
					scannedRoots.Clear();
				}
				if (rootScanUsable)
				{
					ScanNewRoots();
				}
				else if (flag)
				{
					SweepRenderers();
				}
			}
		}

		[HideFromIl2Cpp]
		private void ProcessForeignDiscovery()
		{
			if (pendingForeignNodes.Count == 0 && pendingForeignFallback.Count == 0)
			{
				return;
			}
			long timestamp = Stopwatch.GetTimestamp();
			double num = (double)(0.25f * (float)Stopwatch.Frequency) / 1000.0;
			for (int i = 0; i < 64; i++)
			{
				if (pendingForeignNodes.Count != 0)
				{
					ForeignNode foreignNode = pendingForeignNodes.Pop();
					if (!IsNull((Object)(object)foreignNode.Transform))
					{
						if (!foreignNode.Visited)
						{
							((Component)foreignNode.Transform).GetComponents<Renderer>(discoveryRendererScratch);
							for (int j = 0; j < discoveryRendererScratch.Count; j++)
							{
								Consider(discoveryRendererScratch[j]);
							}
							discoveryRendererScratch.Clear();
							foreignNode.Visited = true;
						}
						else if (foreignNode.Child < foreignNode.Transform.childCount)
						{
							Transform child = foreignNode.Transform.GetChild(foreignNode.Child++);
							pendingForeignNodes.Push(foreignNode);
							pendingForeignNodes.Push(new ForeignNode
							{
								Transform = child
							});
							if ((double)(Stopwatch.GetTimestamp() - timestamp) >= num)
							{
								break;
							}
							continue;
						}
						if (foreignNode.Child < foreignNode.Transform.childCount)
						{
							pendingForeignNodes.Push(foreignNode);
						}
					}
				}
				else
				{
					if (pendingForeignFallback.Count == 0)
					{
						break;
					}
					Consider(pendingForeignFallback.Dequeue());
				}
				if ((double)(Stopwatch.GetTimestamp() - timestamp) >= num)
				{
					break;
				}
			}
			nextForeignSweep = Time.unscaledTime + 15f;
		}

		[HideFromIl2Cpp]
		private void ScanNewRoots()
		{
			//IL_000c: 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)
			try
			{
				int sceneCount = SceneManager.sceneCount;
				for (int i = 0; i < sceneCount; i++)
				{
					ScanSceneRoots(SceneManager.GetSceneAt(i), requireLoaded: true);
				}
				ScanSceneRoots(((Component)this).gameObject.scene, requireLoaded: false);
			}
			catch (System.Exception ex)
			{
				rootScanUsable = false;
				Plugin.Log.LogWarning((object)("Flat Walk could not walk the scene roots, so bodies built from its shaders are now found by the exhaustive search alone: " + ex.Message));
			}
		}

		[HideFromIl2Cpp]
		private void ScanSceneRoots(Scene scene, bool requireLoaded)
		{
			if (!((Scene)(ref scene)).IsValid() || (requireLoaded && !((Scene)(ref scene)).isLoaded))
			{
				return;
			}
			Il2CppReferenceArray<GameObject> rootGameObjects = ((Scene)(ref scene)).GetRootGameObjects();
			if (rootGameObjects == null)
			{
				return;
			}
			for (int i = 0; i < ((Il2CppArrayBase<GameObject>)(object)rootGameObjects).Length; i++)
			{
				GameObject val = ((Il2CppArrayBase<GameObject>)(object)rootGameObjects)[i];
				if (!IsNull((Object)(object)val) && scannedRoots.Add(((Object)val).GetInstanceID()))
				{
					pendingForeignNodes.Push(new ForeignNode
					{
						Transform = val.transform
					});
				}
			}
		}

		[HideFromIl2Cpp]
		private void SweepRenderers()
		{
			Il2CppArrayBase<Renderer> val = Object.FindObjectsOfType<Renderer>(true);
			if (val != null)
			{
				for (int i = 0; i < val.Length; i++)
				{
					pendingForeignFallback.Enqueue(val[i]);
				}
			}
		}

		[HideFromIl2Cpp]
		private void Consider(Renderer renderer)
		{
			if (!IsNull((Object)(object)renderer) && classifiedRenderers.Add(((Object)renderer).GetInstanceID()))
			{
				Classify(renderer);
			}
		}

		[HideFromIl2Cpp]
		private void CollectFlatShaders()
		{
			flatShaderIds.Clear();
			AddFlatShader(limbTemplate);
			AddFlatShader(noseTemplate);
			AddFlatShader(bodyTemplate);
			AddFlatShader(vertexColorTemplate);
			AddFlatShader(unlitTemplate);
			AddFlatShader(eyeTemplate);
		}

		[HideFromIl2Cpp]
		private void AddFlatShader(Material template)
		{
			if (!IsNull((Object)(object)template) && !IsNull((Object)(object)template.shader))
			{
				flatShaderIds.Add(((Object)template.shader).GetInstanceID());
			}
		}

		[HideFromIl2Cpp]
		private void Classify(Renderer renderer)
		{
			int[] array = ForeignSlots(renderer);
			if (array != null && !((Object)(object)((Component)renderer).GetComponentInParent<PlayerCharacter>() != (Object)null) && !IsPlayerRenderer(renderer))
			{
				Transform root = ((Component)renderer).transform.root;
				int instanceID = ((Object)root).GetInstanceID();
				FlatForeign flatForeign = default(FlatForeign);
				if (!foreign.TryGetValue(instanceID, ref flatForeign))
				{
					flatForeign = new FlatForeign(root);
					foreign.Add(instanceID, flatForeign);
				}
				flatForeign.Renderers.Add(new FlatForeignRenderer(renderer)
				{
					Slots = array
				});
			}
		}

		[HideFromIl2Cpp]
		private int[] ForeignSlots(Renderer renderer)
		{
			Il2CppReferenceArray<Material> sharedMaterials = renderer.sharedMaterials;
			if (sharedMaterials == null || ((Il2CppArrayBase<Material>)(object)sharedMaterials).Length == 0)
			{
				return null;
			}
			int num = 0;
			for (int i = 0; i < ((Il2CppArrayBase<Material>)(object)sharedMaterials).Length; i++)
			{
				if (UsesFlatShader(((Il2CppArrayBase<Material>)(object)sharedMaterials)[i]))
				{
					num++;
				}
			}
			if (num == 0)
			{
				return null;
			}
			int[] array = new int[num];
			num = 0;
			for (int j = 0; j < ((Il2CppArrayBase<Material>)(object)sharedMaterials).Length; j++)
			{
				if (UsesFlatShader(((Il2CppArrayBase<Material>)(object)sharedMaterials)[j]))
				{
					array[num++] = j;
				}
			}
			return array;
		}

		[HideFromIl2Cpp]
		private bool UsesFlatShader(Material material)
		{
			if (!IsNull((Object)(object)material) && !IsNull((Object)(object)material.shader))
			{
				return flatShaderIds.Contains(((Object)material.shader).GetInstanceID());
			}
			return false;
		}

		[HideFromIl2Cpp]
		private bool IsPlayerRenderer(Renderer renderer)
		{
			//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)
			int instanceID = ((Object)renderer).GetInstanceID();
			Enumerator<int, FlatPlayer> enumerator = players.Values.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					if (enumerator.Current.Renderers.ContainsKey(instanceID))
					{
						return true;
					}
				}
			}
			finally
			{
				((System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
			}
			return false;
		}

		[HideFromIl2Cpp]
		private void ValidateForeign()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			staleForeign.Clear();
			Enumerator<int, FlatForeign> enumerator = foreign.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					KeyValuePair<int, FlatForeign> current = enumerator.Current;
					FlatForeign value = current.Value;
					if (IsNull((Object)(object)value.Root))
					{
						staleForeign.Add(current.Key);
						continue;
					}
					for (int num = value.Renderers.Count - 1; num >= 0; num--)
					{
						FlatForeignRenderer flatForeignRenderer = value.Renderers[num];
						bool flag = !IsNull((Object)(object)flatForeignRenderer.Renderer);
						int[] array = (flag ? ForeignSlots(flatForeignRenderer.Renderer) : null);
						if (array != null)
						{
							flatForeignRenderer.Slots = array;
						}
						else
						{
							if (flag)
							{
								classifiedRenderers.Remove(((Object)flatForeignRenderer.Renderer).GetInstanceID());
							}
							value.Renderers.RemoveAt(num);
						}
					}
					if (value.Renderers.Count == 0)
					{
						staleForeign.Add(current.Key);
					}
				}
			}
			finally
			{
				((System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
			}
			Enumerator<int> enumerator2 = staleForeign.GetEnumerator();
			try
			{
				while (enumerator2.MoveNext())
				{
					int current2 = enumerator2.Current;
					foreign.Remove(current2);
				}
			}
			finally
			{
				((System.IDisposable)enumerator2/*cast due to .constrained prefix*/).Dispose();
			}
		}

		[HideFromIl2Cpp]
		private Color SampleLighting(FlatLit state, Vector3 chest, float spacing, Transform ignoreRoot)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: 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_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: 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_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)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: 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_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			int nextProbe = state.NextProbe;
			state.NextProbe = (nextProbe + 1) % 3;
			state.ProbeLight[nextProbe] = EvaluateLighting(chest + Vector3.up * nextProbe switch
			{
				1 => spacing, 
				0 => 0f, 
				_ => 0f - spacing, 
			}, ignoreRoot);
			if (state.ProbesFilled < 3)
			{
				state.ProbesFilled++;
			}
			Color val = Color.clear;
			for (int i = 0; i < state.ProbesFilled; i++)
			{
				val += state.ProbeLight[i];
			}
			val /= (float)state.ProbesFilled;
			val.r = BrightnessCurve(val.r);
			val.g = BrightnessCurve(val.g);
			val.b = BrightnessCurve(val.b);
			val.a = 1f;
			return val;
		}

		[HideFromIl2Cpp]
		private Color EvaluateLighting(Vector3 samplePosition, Transform ignoreRoot)
		{
			//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_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Invalid comparison between Unknown and I4
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Invalid comparison between Unknown and I4
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			Color val = ReadGameAmbient();
			System.Array.Clear((System.Array)bestLights, 0, bestLights.Length);
			System.Array.Clear((System.Array)bestLightValues, 0, bestLightValues.Length);
			int num = 32;
			for (int i = 0; i < lights.Count; i++)
			{
				Light val2 = lights[i];
				if (IsNull((Object)(object)val2) || !((Behaviour)val2).isActiveAndEnabled || val2.intensity <= 0f)
				{
					continue;
				}
				LightType type = val2.type;
				if ((int)type != 1 && (int)type != 2 && (int)type != 0)
				{
					continue;
				}
				float num2 = PotentialLightContribution(val2, samplePosition);
				if (num2 <= 0f)
				{
					continue;
				}
				int num3 = 0;
				for (int j = 1; j < num; j++)
				{
					if (bestLightValues[j] < bestLightValues[num3])
					{
						num3 = j;
					}
				}
				if (num2 > bestLightValues[num3])
				{
					bestLights[num3] = val2;
					bestLightValues[num3] = num2;
				}
			}
			for (int k = 0; k < num; k++)
			{
				Light val3 = bestLights[k];
				if (!IsNull((Object)(object)val3) && (!Plugin.LightingOcclusion.Value || !IsBlockedByWorld(ignoreRoot, val3, samplePosition)))
				{
					val += val3.color * (bestLightValues[k] * 0.6f);
				}
			}
			return val;
		}

		private static float BrightnessCurve(float value)
		{
			float num = 0.1f;
			float num2 = 1.05f;
			float num3 = 0.95f;
			float num4 = 0.5f;
			if (value <= num)
			{
				return num;
			}
			if (value < num3)
			{
				float num5 = (value - num) / (num3 - num);
				float num6 = (num4 - 1f) * num5 * num5 + (2f - num4) * num5;
				return num + (num3 - num) * num6;
			}
			float num7 = num2 - num3;
			if (num7 <= 0f)
			{
				return num2;
			}
			return num3 + num7 * (1f - Mathf.Exp((0f - (value - num3)) * num4 / num7));
		}

		[HideFromIl2Cpp]
		private static void AdvanceLighting(FlatLit state)
		{
			//IL_0038: 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_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			if (state.LastSmoothedFrame != Time.frameCount)
			{
				state.LastSmoothedFrame = Time.frameCount;
				float num = 0.1f;
				if (num <= 0f || !state.HasLight)
				{
					state.HasLight = true;
					state.Light = state.TargetLight;
				}
				else
				{
					float num2 = 1f - Mathf.Exp((0f - Time.unscaledDeltaTime) / num);
					state.Light = Color.Lerp(state.Light, state.TargetLight, num2);
				}
			}
		}

		[HideFromIl2Cpp]
		private static float PotentialLightContribution(Light light, Vector3 samplePosition)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			if ((int)light.type == 1)
			{
				return Mathf.Max(0f, light.intensity);
			}
			Vector3 val = samplePosition - ((Component)light).transform.position;
			float magnitude = ((Vector3)(ref val)).magnitude;
			if (light.range <= 0f || magnitude >= light.range)
			{
				return 0f;
			}
			float num = Mathf.Clamp01(1f - magnitude / Mathf.Max(light.range, 0.01f));
			num *= num;
			if ((int)light.type == 0)
			{
				Vector3 normalized = ((Vector3)(ref val)).normalized;
				float num2 = Mathf.InverseLerp(Mathf.Cos(light.spotAngle * 0.5f * ((float)Math.PI / 180f)), 1f, Vector3.Dot(((Component)light).transform.forward, normalized));
				num *= Mathf.Clamp01(num2);
			}
			if (num <= 0f)
			{
				return 0f;
			}
			return light.intensity * num;
		}

		[HideFromIl2Cpp]
		private static bool BelongsToLight(Collider collider, Light light)
		{
			if (!((Component)collider).transform.IsChildOf(((Component)light).transform))
			{
				return ((Component)light).transform.IsChildOf(((Component)collider).transform);
			}
			return true;
		}

		[HideFromIl2Cpp]
		private bool IsBlockedByWorld(Transform ignoreRoot, Light light, Vector3 samplePosition)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: 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_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val;
			float num;
			if ((int)light.type == 1)
			{
				val = -((Component)light).transform.forward;
				num = 200f;
			}
			else
			{
				Vector3 val2 = ((Component)light).transform.position - samplePosition;
				num = ((Vector3)(ref val2)).magnitude;
				if (num <= 0.4f)
				{
					return false;
				}
				val = ((Vector3)(ref val2)).normalized;
				num -= 0.4f;
			}
			if (num <= 0f)
			{
				return false;
			}
			int num2 = Physics.RaycastNonAlloc(samplePosition + val * 0.05f, val, raycastHits, num, -5, (QueryTriggerInteraction)1);
			for (int i = 0; i < num2; i++)
			{
				RaycastHit val3 = ((Il2CppArrayBase<RaycastHit>)(object)raycastHits)[i];
				Collider collider = ((RaycastHit)(ref val3)).collider;
				if (!IsNull((Object)(object)collider) && (IsNull((Object)(object)ignoreRoot) || !((Component)collider).transform.IsChildOf(ignoreRoot)) && !((Object)(object)((Component)collider).GetComponentInParent<PlayerCharacter>() != (Object)null) && !BelongsToLight(collider, light))
				{
					return true;
				}
			}
			return false;
		}

		[HideFromIl2Cpp]
		private static Color ReadGameAmbient()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			Color val = RenderSettings.ambientLight * RenderSettings.ambientIntensity;
			try
			{
				if (!IsNull((Object)(object)LobbyLighting.instance))
				{
					Color playerLightColor = LobbyLighting.instance.GetCombinedSettings().playerLightColor;
					if (((Color)(ref playerLightColor)).maxColorComponent > 0.001f)
					{
						val *= playerLightColor;
					}
				}
			}
			catch
			{
			}
			return val;
		}

		[HideFromIl2Cpp]
		private bool IsDrawnEye(Material material)
		{
			if (!IsNull((Object)(object)eyeTemplate) && !IsNull((Object)(object)material))
			{
				return (Object)(object)material.shader == (Object)(object)eyeTemplate.shader;
			}
			return false;
		}

		[HideFromIl2Cpp]
		private static void SyncEyeMaterial(PlayerEyes eyes, Renderer renderer, Material source, Material target)
		{
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			Il2CppReferenceArray<Renderer> val = ((eyes != null) ? eyes.renderers : null);
			Il2CppReferenceArray<Material> val2 = ((eyes != null) ? eyes.materialInstances : null);
			if (val != null && val2 != null && ((Il2CppArrayBase<Renderer>)(object)val).Length == ((Il2CppArrayBase<Material>)(object)val2).Length)
			{
				for (int i = 0; i < ((Il2CppArrayBase<Renderer>)(object)val).Length; i++)
				{
					if ((Object)(object)((Il2CppArrayBase<Renderer>)(object)val)[i] == (Object)(object)renderer && !IsNull((Object)(object)((Il2CppArrayBase<Material>)(object)val2)[i]))
					{
						source = ((Il2CppArrayBase<Material>)(object)val2)[i];
						break;
					}
				}
			}
			if (IsNull((Object)(object)source) || (Object)(object)source == (Object)(object)target)
			{
				return;
			}
			target.SetTexture(ShaderIds.MainTex, source.GetTexture(ShaderIds.MainTex));
			int[] eyeVectors = EyeVectors;
			foreach (int num in eyeVectors)
			{
				if (source.HasProperty(num))
				{
					target.SetVector(num, source.GetVector(num));
				}
			}
		}

		[HideFromIl2Cpp]
		private void Apply(FlatPlayer state)
		{
			//IL_000b: 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_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: 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_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			Enumerator<int, FlatRenderer> enumerator = state.Renderers.Values.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					FlatRenderer current = enumerator.Current;
					if (IsNull((Object)(object)current.Renderer) || current.FlatMaterials == null)
					{
						continue;
					}
					current.EyesOwner = state.Player.playerEyes;
					EnsureMaterials(current, current.DefaultPart);
					if (current.FlatMaterials == null)
					{
						continue;
					}
					if (current.DefaultPart == FlatPart.Equipment)
					{
						current.Renderer.GetPropertyBlock(rendererPropertyBlock);
					}
					for (int i = 0; i < current.FlatMaterials.Length; i++)
					{
						Material val = current.FlatMaterials[i];
						FlatRenderer.Slot slot = current.Slots[i];
						if (current.Parts[i] == FlatPart.Eye && !slot.DrawnEye)
						{
							continue;
						}
						if (current.Parts[i] == FlatPart.Eye)
						{
							SyncEyeMaterial(state.Player.playerEyes, current.Renderer, current.OriginalMaterials[i], val);
						}
						if (!IsNull((Object)(object)val) && slot.Compatible)
						{
							SetFloatIfPresent(val, "_ReceiveShadows", Plugin.ReceiveShadows.Value ? 1f : 0f);
							if (Plugin.ReceiveShadows.Value)
							{
								val.DisableKeyword("_RECEIVE_SHADOWS_OFF");
							}
							else
							{
								val.EnableKeyword("_RECEIVE_SHADOWS_OFF");
							}
							continue;
						}
						bool shiny;
						Color val2 = BaseColorFor(state.Player, current, i, out shiny);
						current.Renderer.GetPropertyBlock(propertyBlock, i);
						bool num = current.Parts[i] == FlatPart.Equipment && slot.VertexColors && CopyEquipmentTints(slot);
						val2.a = 1f;
						Color val3 = ((current.Parts[i] == FlatPart.Eye) ? EyeLight(state.Light) : state.Light);
						if (num || !CanReusePropertyBlock(slot.AppliedRevision, val3, val2))
						{
							propertyBlock.SetColor(ShaderIds.FlatColor, val2);
							propertyBlock.SetColor(ShaderIds.FlatLight, val3);
							propertyBlock.SetFloat(ShaderIds.FlatReceiveShadows, Plugin.ReceiveShadows.Value ? 1f : 0f);
							propertyBlock.SetFloat(ShaderIds.FlatShadowStrength, 0.2f);
							propertyBlock.SetFloat(ShaderIds.FlatBaseSaturation, 1f);
							propertyBlock.SetFloat(ShaderIds.FlatHighlightSaturation, 0.1f);
							float num2 = ((current.Parts[i] != FlatPart.Equipment) ? 0.0055f : 0f);
							propertyBlock.SetFloat(ShaderIds.DrawnStrength, num2);
							propertyBlock.SetFloat(ShaderIds.DrawnBumpScale, 0.035f);
							propertyBlock.SetFloat(ShaderIds.DrawnFineDetail, 0.525f);
							propertyBlock.SetFloat(ShaderIds.DrawnLimbStrength, 0.025f);
							propertyBlock.SetFloat(ShaderIds.DrawnProtectEyes, current.ProtectOriginalEyes ? 1f : 0f);
							propertyBlock.SetFloat(ShaderIds.FlatShiny, shiny ? 1f : 0f);
							propertyBlock.SetFloat(ShaderIds.FlatShineGleamDelay, ShineGleamDelayFor(current.Parts[i]));
							if (slot.Nose)
							{
								propertyBlock.SetFloat(ShaderIds.NoseOcclusion, 0.1f);
								propertyBlock.SetFloat(ShaderIds.NoseOcclusionStart, 0f);
								propertyBlock.SetFloat(ShaderIds.NoseOcclusionEnd, 0.8f);
							}
							current.Renderer.SetPropertyBlock(propertyBlock, i);
							slot.AppliedRevision = Plugin.SettingsRevision;
						}
					}
					ApplyDrawnBounds(current);
					if (current.Renderer.receiveShadows != Plugin.ReceiveShadows.Value)
					{
						current.Renderer.receiveShadows = Plugin.ReceiveShadows.Value;
					}
				}
			}
			finally
			{
				((System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
			}
		}

		private bool CopyEquipmentTints(FlatRenderer.Slot slot)
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			bool result = false;
			for (int i = 0; i < EquipmentTintIds.Length; i++)
			{
				int num = EquipmentTintIds[i];
				if (!rendererPropertyBlock.HasColor(num))
				{
					continue;
				}
				int num2 = 1 << i;
				if ((slot.CopiedRendererTints & num2) == 0 && propertyBlock.HasColor(num))
				{
					continue;
				}
				Color color = rendererPropertyBlock.GetColor(num);
				if (propertyBlock.HasColor(num))
				{
					Color color2 = propertyBlock.GetColor(num);
					if (((Color)(ref color2)).Equals(color))
					{
						goto IL_0083;
					}
				}
				propertyBlock.SetColor(num, color);
				result = true;
				goto IL_0083;
				IL_0083:
				slot.CopiedRendererTints |= num2;
			}
			return result;
		}

		[HideFromIl2Cpp]
		private static Color EyeLight(Color light)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: 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_0030: Unknown result type (might be due to invalid IL or missing references)
			float num = 0.65f;
			return new Color(Mathf.Max(light.r, num), Mathf.Max(light.g, num), Mathf.Max(light.b, num), light.a);
		}

		private bool CanReusePropertyBlock(int appliedRevision, Color light, Color color)
		{
			//IL_0013: 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_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			if (appliedRevision == Plugin.SettingsRevision)
			{
				Color color2 = propertyBlock.GetColor(ShaderIds.FlatLight);
				if (((Color)(ref color2)).Equals(light))
				{
					color2 = propertyBlock.GetColor(ShaderIds.FlatColor);
					return ((Color)(ref color2)).Equals(color);
				}
			}
			return false;
		}

		[HideFromIl2Cpp]
		private static void ApplyDrawnBounds(FlatRenderer flat)
		{
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: 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_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			float num = 0f;
			for (int i = 0; i < flat.FlatMaterials.Length; i++)
			{
				Material val = flat.FlatMaterials[i];
				if (flat.Parts[i] != FlatPart.Equipment && !IsNull((Object)(object)val) && val.HasProperty(ShaderIds.DrawnStrength))
				{
					num = Mathf.Max(num, 0.0055f);
					if (val.HasProperty(ShaderIds.LimbRadius))
					{
						num = Mathf.Max(num, Mathf.Abs(val.GetFloat(ShaderIds.LimbRadius)) * Mathf.Min(1.8333333f, 2f) * 0.025f);
					}
				}
			}
			if (num <= 0f)
			{
				RestoreDrawnBounds(flat);
				return;
			}
			Bounds localBounds = flat.Renderer.localBounds;
			if (IsNull((Object)(object)flat.DrawnMeshFilter))
			{
				flat.DrawnMeshFilter = ((Component)flat.Renderer).GetComponent<MeshFilter>();
			}
			if (!IsNull((Object)(object)flat.DrawnMeshFilter) && !IsNull((Object)(object)flat.DrawnMeshFilter.sharedMesh))
			{
				Bounds bounds = flat.DrawnMeshFilter.sharedMesh.bounds;
				if (!flat.DrawnBoundsCaptured || localBounds != flat.DrawnExpandedBounds)
				{
					flat.DrawnOriginalBounds = localBounds;
					flat.DrawnUsesMeshBounds = localBounds == bounds;
				}
				if (flat.DrawnUsesMeshBounds)
				{
					flat.DrawnOriginalBounds = bounds;
				}
				flat.DrawnBoundsCaptured = true;
				Bounds drawnOriginalBounds = flat.DrawnOriginalBounds;
				((Bounds)(ref drawnOriginalBounds)).Expand(num * 2f);
				flat.DrawnExpandedBounds = drawnOriginalBounds;
				if (localBounds != drawnOriginalBounds)
				{
					flat.Renderer.localBounds = drawnOriginalBounds;
				}
			}
		}

		[HideFromIl2Cpp]
		private static void RestoreDrawnBounds(FlatRenderer flat)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			if (!flat.DrawnBoundsCaptured)
			{
				return;
			}
			if (!IsNull((Object)(object)flat.Renderer) && flat.Renderer.localBounds == flat.DrawnExpandedBounds)
			{
				if (flat.DrawnUsesMeshBounds)
				{
					flat.Renderer.ResetLocalBounds();
				}
				else
				{
					flat.Renderer.localBounds = flat.DrawnOriginalBounds;
				}
			}
			flat.DrawnBoundsCaptured = false;
		}

		[HideFromIl2Cpp]
		private static bool ForeignBounds(FlatForeign group, out Bounds bounds)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			bounds = default(Bounds);
			bool flag = false;
			for (int i = 0; i < group.Renderers.Count; i++)
			{
				Renderer renderer = group.Renderers[i].Renderer;
				if (!IsNull((Object)(object)renderer) && renderer.enabled && ((Component)renderer).gameObject.activeInHierarchy)
				{
					if (flag)
					{
						((Bounds)(ref bounds)).Encapsulate(renderer.bounds);
						continue;
					}
					bounds = renderer.bounds;
					flag = true;
				}
			}
			return flag;
		}

		[HideFromIl2Cpp]
		private void ApplyForeign(FlatForeign group)
		{
			//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_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: 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_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			Vector4 val = default(Vector4);
			((Vector4)(ref val))..ctor(Plugin.ReceiveShadows.Value ? 1f : 0f, 0.2f, 1f, 0.1f);
			bool flag = Time.unscaledTime >= group.NextForcedApply;
			if (!flag && group.Applied && group.Light == group.AppliedLight && val == group.AppliedSettings)
			{
				return;
			}
			if (flag)
			{
				group.NextForcedApply = Time.unscaledTime + 0.5f;
			}
			group.Applied = true;
			group.AppliedLight = group.Light;
			group.AppliedSettings = val;
			for (int i = 0; i < group.Renderers.Count; i++)
			{
				FlatForeignRenderer flatForeignRenderer = group.Renderers[i];
				if (!IsNull((Object)(object)flatForeignRenderer.Renderer) && flatForeignRenderer.Slots != null)
				{
					for (int j = 0; j < flatForeignRenderer.Slots.Length; j++)
					{
						int num = flatForeignRenderer.Slots[j];
						flatForeignRenderer.Renderer.GetPropertyBlock(propertyBlock, num);
						propertyBlock.SetColor(ShaderIds.FlatLight, group.Light);
						propertyBlock.SetFloat(ShaderIds.FlatReceiveShadows, val.x);
						propertyBlock.SetFloat(ShaderIds.FlatShadowStrength, val.y);
						propertyBlock.SetFloat(ShaderIds.FlatBaseSaturation, val.z);
						propertyBlock.SetFloat(ShaderIds.FlatHighlightSaturation, val.w);
						flatForeignRenderer.Renderer.SetPropertyBlock(propertyBlock, num);
					}
				}
			}
		}

		[HideFromIl2Cpp]
		private static Color BaseColorFor(PlayerCharacter player, FlatRenderer flat, int materialIndex, out bool shiny)
		{
			//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_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: 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_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			LookColor val;
			switch (flat.Parts[materialIndex])
			{
			case FlatPart.Head:
				val = player.looks.headColor;
				break;
			case FlatPart.Torso:
				val = player.looks.torsoColor;
				break;
			case FlatPart.Legs:
				val = player.looks.legsColor;
				break;
			default:
				shiny = false;
				return flat.SourceColors[materialIndex];
			}
			shiny = val.rewardOnly;
			return val.color;
		}

		[HideFromIl2Cpp]
		private static float ShineGleamDelayFor(FlatPart part)
		{
			return part switch
			{
				FlatPart.Torso => 0.75f, 
				FlatPart.Head => 1.5f, 
				_ => 0f, 
			};
		}

		[HideFromIl2Cpp]
		private static Color ReadBaseColor(Material material)
		{
			//IL_0008: 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_003a: 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_0053: Unknown result type (might be due to invalid IL or missing references)
			if (IsNull((Object)(object)material))
			{
				return Color.white;
			}
			if (material.HasProperty(ShaderIds.BaseColor))
			{
				return material.GetColor(ShaderIds.BaseColor);
			}
			if (material.HasProperty(ShaderIds.Color0))
			{
				return material.GetColor(ShaderIds.Color0);
			}
			if (material.HasProperty(ShaderIds.Color))
			{
				return material.GetColor(ShaderIds.Color);
			}
			return Color.white;
		}

		[HideFromIl2Cpp]
		private static bool IsEyeSlot(HashSet<int> eyeSlots, int materialIndex)
		{
			if (eyeSlots != null)
			{
				if (!eyeSlots.Contains(-1))
				{
					return eyeSlots.Contains(materialIndex);
				}
				return true;
			}
			return false;
		}

		[HideFromIl2Cpp]
		private static bool SameMaterials(Il2CppReferenceArray<Material> actual, Material[] expected)
		{
			if (actual == null || expected == null || ((Il2CppArrayBase<Material>)(object)actual).Length != expected.Length)
			{
				return false;
			}
			for (int i = 0; i < expected.Length; i++)
			{
				if ((Object)(object)((Il2CppArrayBase<Material>)(object)actual)[i] != (Object)(object)expected[i])
				{
					return false;
				}
			}
			return true;
		}

		[HideFromIl2Cpp]
		private static bool SameMaterials(List<Material> actual, Material[] expected)
		{
			if (expected == null || actual.Count != expected.Length)
			{
				return false;
			}
			for (int i = 0; i < expected.Length; i++)
			{
				if ((Object)(object)actual[i] != (Object)(object)expected[i])
				{
					return false;
				}
			}
			return true;
		}

		[HideFromIl2Cpp]
		private void RestoreEverything()
		{
			//IL_000b: 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)
			Enumerator<int, FlatPlayer> enumerator = players.Values.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					Restore(enumerator.Current);
				}
			}
			finally
			{
				((System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
			}
			players.Clear();
			foreign.Clear();
			classifiedRenderers.Clear();
			scannedRoots.Clear();
			foreignScene = null;
			pendingForeignNodes.Clear();
			pendingForeignFallback.Clear();
		}

		[HideFromIl2Cpp]
		private void OnHbaoSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			hbaoDiscoveryPending = true;
		}

		[HideFromIl2Cpp]
		private void OnHbaoPipelineCreated()
		{
			hbaoDiscoveryPending = true;
		}

		[HideFromIl2Cpp]
		private void UpdateHbaoIntensities()
		{
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			if (Plugin.HBAOEnabled.Value)
			{
				if (originalHbaoIntensities.Count > 0)
				{
					RestoreHbaoIntensities();
				}
				return;
			}
			float unscaledTime = Time.unscaledTime;
			if (unscaledTime < nextHbaoRefresh && !hbaoDiscoveryPending)
			{
				return;
			}
			nextHbaoRefresh = unscaledTime + 0.5f;
			if (hbaoDiscoveryPending || unscaledTime >= nextHbaoDiscovery)
			{
				hbaoDiscoveryPending = false;
				nextHbaoDiscovery = unscaledTime + 10f;
				HBAO[] array = Il2CppArrayBase<HBAO>.op_Implicit(Resources.FindObjectsOfTypeAll<HBAO>());
				OriginalHbaoIntensity originalHbaoIntensity = default(OriginalHbaoIntensity);
				foreach (HBAO val in array)
				{
					if (!IsNull((Object)(object)val) && val.intensity != null)
					{
						int instanceID = ((Object)val).GetInstanceID();
						if (!originalHbaoIntensities.TryGetValue(instanceID, ref originalHbaoIntensity) || IsNull((Object)(object)originalHbaoIntensity.Component))
						{
							originalHbaoIntensities[instanceID] = new OriginalHbaoIntensity(val);
						}
					}
				}
			}
			staleHbao.Clear();
			Enumerator<int, OriginalHbaoIntensity> enumerator = originalHbaoIntensities.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					KeyValuePair<int, OriginalHbaoIntensity> current = enumerator.Current;
					HBAO component = current.Value.Component;
					if (IsNull((Object)(object)component) || component.intensity == null)
					{
						staleHbao.Add(current.Key);
					}
					else if (((VolumeParameter<float>)(object)component.intensity).value != 0f || !((VolumeParameter)component.intensity).overrideState)
					{
						((VolumeParameter)component.intensity).overrideState = true;
						((VolumeParameter<float>)(object)component.intensity).value = 0f;
					}
				}
			}
			finally
			{
				((System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
			}
			Enumerator<int> enumerator2 = staleHbao.GetEnumerator();
			try
			{
				while (enumerator2.MoveNext())
				{
					int current2 = enumerator2.Current;
					originalHbaoIntensities.Remove(current2);
				}
			}
			finally
			{
				((System.IDisposable)enumerator2/*cast due to .constrained prefix*/).Dispose();
			}
		}

		[HideFromIl2Cpp]
		private void RestoreHbaoIntensities()
		{
			//IL_000b: 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)
			Enumerator<int, OriginalHbaoIntensity> enumerator = originalHbaoIntensities.Values.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					OriginalHbaoIntensity current = enumerator.Current;
					HBAO component = current.Component;
					if (!IsNull((Object)(object)component) && component.intensity != null)
					{
						((VolumeParameter<float>)(object)component.intensity).value = current.Intensity;
						((VolumeParameter)component.intensity).overrideState = current.OverrideState;
					}
				}
			}
			finally
			{
				((System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
			}
			originalHbaoIntensities.Clear();
			hbaoDiscoveryPending = true;
			nextHbaoRefresh = 0f;
			nextHbaoDiscovery = 0f;
		}

		[HideFromIl2Cpp]
		private static void Restore(FlatPlayer state)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			bool flag = false;
			Enumerator<int, FlatRenderer> enumerator = state.Renderers.Values.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					FlatRenderer current = enumerator.Current;
					flag |= current.FlatMaterials != null && !IsNull((Object)(object)current.Renderer);
					Restore(current);
				}
			}
			finally
			{
				((System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
			}
			state.Renderers.Clear();
			if (flag)
			{
				WriteLookColours(state.Player);
			}
		}

		[HideFromIl2Cpp]
		private static void Restore(FlatRenderer flat)
		{
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			RestoreDrawnBounds(flat);
			if (flat.FlatMaterials == null)
			{
				return;
			}
			PlayerEyes eyesOwner = flat.EyesOwner;
			if (eyesOwner != null && eyesOwner.renderers != null && eyesOwner.materialInstances != null && ((Il2CppArrayBase<Renderer>)(object)eyesOwner.renderers).Length == ((Il2CppArrayBase<Material>)(object)eyesOwner.materialInstances).Length && flat.OriginalMaterials != null)
			{
				for (int i = 0; i < ((Il2CppArrayBase<Renderer>)(object)eyesOwner.renderers).Length; i++)
				{
					if ((Object)(object)((Il2CppArrayBase<Renderer>)(object)eyesOwner.renderers)[i] != (Object)(object)flat.Renderer)
					{
						continue;
					}
					Material val = ((Il2CppArrayBase<Material>)(object)eyesOwner.materialInstances)[i];
					if (IsNull((Object)(object)val))
					{
						continue;
					}
					for (int j = 0; j < flat.FlatMaterials.Length; j++)
					{
						if (flat.Parts[j] != FlatPart.Eye || (Object)(object)val != (Object)(object)flat.FlatMaterials[j] || !flat.OwnedMaterials.Contains(val))
						{
							continue;
						}
						Material val2 = flat.OriginalMaterials[j];
						if (!IsNull((Object)(object)val2))
						{
							val2.SetTexture(ShaderIds.MainTex, val.GetTexture(ShaderIds.MainTex));
							int[] eyeVectors = EyeVectors;
							foreach (int num in eyeVectors)
							{
								val2.SetVector(num, val.GetVector(num));
							}
							((Il2CppArrayBase<Material>)(object)eyesOwner.materialInstances)[i] = val2;
						}
					}
				}
			}
			if (!IsNull((Object)(object)flat.Renderer) && flat.OriginalMaterials != null && SameMaterials(flat.Renderer.sharedMaterials, flat.FlatMaterials))
			{
				flat.Renderer.sharedMaterials = new Il2CppReferenceArray<Material>(flat.OriginalMaterials);
			}
			if (!IsNull((Object)(object)flat.Renderer) && flat.OriginalReceiveShadowsCaptured)
			{
				flat.Renderer.receiveShadows = flat.OriginalReceiveShadows;
			}
			ClearCachedInstances(flat);
			if (!IsNull((Object)(object)flat.Renderer))
			{
				for (int l = 0; l < flat.Splines.Count; l++)
				{
					LimbSpline val3 = flat.Splines[l];
					if (!IsNull((Object)(object)val3))
					{
						SafeSplineMaterial(val3);
					}
				}
				for (int m = 0; m < flat.Helpers.Count; m++)
				{
					PropertyBlockHelper val4 = flat.Helpers[m];
					if (!IsNull((Object)(object)val4))
					{
						SafeHelperMaterial(val4);
					}
				}
				for (int n = 0; n < flat.LooksOwners.Count; n++)
				{
					LooksRenderer val5 = flat.LooksOwners[n];
					if (val5 != null)
					{
						SafeLooksMaterial(val5);
					}
				}
			}
			for (int num2 = 0; num2 < flat.OwnedMaterials.Count; num2++)
			{
				Material val6 = flat.OwnedMaterials[num2];
				if (!IsNull((Object)(object)val6))
				{
					instance?.originalByFlatMaterial.Remove(((Object)val6).GetInstanceID());
					Object.Destroy((Object)(object)val6);
				}
			}
			flat.OwnedMaterials.Clear();
			flat.OriginalMaterials = null;
			flat.FlatMaterials = null;
			flat.Parts = null;
			flat.SourceColors = null;
		}

		[HideFromIl2Cpp]
		private static bool IsNull(Object value)
		{
			return value == (Object)null;
		}
	}
	[HarmonyPatch(typeof(PlayerCharacter), "LateUpdate")]
	internal static class PlayerCharacterLateUpdatePatch
	{
		[HarmonyPostfix]
		private static void AfterPlayerLateUpdate(PlayerCharacter __instance)
		{
			FlatWalkController.ApplyAfterPlayerLateUpdate(__instance);
		}
	}
	[HarmonyPatch(typeof(PlayerArms), "LateUpdate")]
	internal static class PlayerArmsLateUpdatePatch
	{
		[HarmonyPostfix]
		private static void AfterArms(PlayerArms __instance)
		{
			if (__instance != null && !IsNull((Object)(object)__instance.playerCharacter))
			{
				FlatWalkController.ApplyAfterPlayerLateUpdate(__instance.playerCharacter);
			}
		}

		private static bool IsNull(Object value)
		{
			return value == (Object)null;
		}
	}
	[BepInPlugin("com.xanderfrangos.bigwalk.flatwalk", "Flat Walk", "1.3.0")]
	public sealed class Plugin : BasePlugin
	{
		internal const string PluginGuid = "com.xanderfrangos.bigwalk.flatwalk";

		internal const string PluginName = "Flat Walk";

		internal const string PluginVersion = "1.3.0";

		public const string OriginalMaterialKey = "FlatWalk.OriginalMaterial.v1";

		internal static ManualLogSource Log;

		internal static ConfigEntry<bool> Enabled;

		internal static ConfigEntry<bool> ReceiveShadows;

		internal const float ShadowStrength = 0.2f;

		internal const float BaseSaturation = 1f;

		internal const float HighlightSaturation = 0.1f;

		internal const float NoseOcclusion = 0.1f;

		internal const float NoseOcclusionStart = 0f;

		internal const float NoseOcclusionEnd = 0.8f;

		internal const float LampStrength = 0.6f;

		internal const float MinimumBrightness = 0.1f;

		internal const float MaximumBrightness = 1.05f;

		internal const float MinimumEyeBrightness = 0.65f;

		internal const float BrightnessPivot = 0.95f;

		internal const float BrightnessPivotSlope = 0.5f;

		internal const float LightSmoothing = 0.1f;

		internal static ConfigEntry<bool> HBAOEnabled;

		internal const bool SkipUnchangedProperties = true;

		internal const float ForeignDiscoveryBudgetMs = 0.25f;

		internal static int SettingsRevision;

		internal const float RendererDiscoveryInterval = 0.1f;

		internal const float LightingSampleInterval = 0.05f;

		internal const int LightingLightBudget = 32;

		internal static ConfigEntry<bool> LightingOcclusion;

		internal const bool DrawnEnabled = true;

		internal const bool DrawnEyes = true;

		internal const float DrawnStrength = 0.0055f;

		internal const float DrawnBumpScale = 0.035f;

		internal const float DrawnFineDetail = 0.525f;

		internal const float DrawnLimbStrength = 0.025f;

		private static void OnSettingChanged(object sender, SettingChangedEventArgs args)
		{
			SettingsRevision++;
		}

		public override void Load()
		{
			//IL_00d6: 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_00e1: Expected O, but got Unknown
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BasePlugin)this).Log;
			Enabled = ((BasePlugin)this).Config.Bind<bool>("General", "Enabled", true, "Flatten player bodies, backpacks, and belt equipment while preserving equipment colours.");
			ReceiveShadows = ((BasePlugin)this).Config.Bind<bool>("General", "ReceiveShadows", false, "Allow flat characters to receive real-time shadows from the main light.");
			HBAOEnabled = ((BasePlugin)this).Config.Bind<bool>("General",