Decompiled source of RootboundWitch v0.4.11

plugins/ADARC-RootboundWitch/ADARC.RootboundWitch.dll

Decompiled 14 minutes ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn.Entities;
using Jotunn.Managers;
using Microsoft.CodeAnalysis;
using SoftReferenceableAssets;
using UnityEngine;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("Rootbound Witch")]
[assembly: AssemblyDescription("A restriction-led moss witch transformation for Valheim.")]
[assembly: AssemblyCompany("ADARC")]
[assembly: AssemblyProduct("Rootbound Witch")]
[assembly: ComVisible(false)]
[assembly: Guid("6e7899d2-9912-4d93-956b-6ead18e4fd18")]
[assembly: AssemblyFileVersion("0.4.11.0")]
[assembly: AssemblyVersion("0.4.11.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace ADARC.RootboundWitch
{
	internal static class BogWitchBackGrowth
	{
		private static readonly string[] GrowthTokens = new string[8] { "branch", "root", "twig", "bark", "vine", "growth", "wood", "stick" };

		private static GameObject _upperTemplate;

		private static GameObject _lowerTemplate;

		private static GameObject _upperInstance;

		private static GameObject _lowerInstance;

		private static Player _owner;

		private static Bounds _combinedBounds;

		private static Material[] _ordinaryMaterials;

		private static Material[] _permafrostMaterials;

		private static float _nextResolveAt;

		private static bool _loggedFailure;

		private static bool _materialStateKnown;

		private static bool _lastPermafrost;

		internal static void Prepare()
		{
			//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_02c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02df: Expected O, but got Unknown
			//IL_02f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0304: Unknown result type (might be due to invalid IL or missing references)
			//IL_0309: Unknown result type (might be due to invalid IL or missing references)
			//IL_030d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0319: Unknown result type (might be due to invalid IL or missing references)
			//IL_031e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0322: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_020e: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)_upperTemplate) || Time.realtimeSinceStartup < _nextResolveAt)
			{
				return;
			}
			_nextResolveAt = Time.realtimeSinceStartup + 5f;
			GameObject val = RootboundContent.FindPrefab("BogWitch");
			if (!Object.op_Implicit((Object)(object)val))
			{
				if (!_loggedFailure)
				{
					RootboundWitchPlugin.Log.LogWarning((object)"Bog Witch back-growth experiment is waiting for the live BogWitch prefab.");
					_loggedFailure = true;
				}
				return;
			}
			try
			{
				List<CombineInstance> list = new List<CombineInstance>();
				List<Material> list2 = new List<Material>();
				List<string> list3 = new List<string>();
				List<string> list4 = new List<string>();
				Matrix4x4 worldToLocalMatrix = val.transform.worldToLocalMatrix;
				Renderer[] componentsInChildren = val.GetComponentsInChildren<Renderer>(true);
				foreach (Renderer val2 in componentsInChildren)
				{
					Mesh val3 = SourceMesh(val2);
					if (!Object.op_Implicit((Object)(object)val3) || val3.subMeshCount <= 0)
					{
						continue;
					}
					Material[] array = (Material[])(((object)val2.sharedMaterials) ?? ((object)new Material[0]));
					string text = RelativePath(((Component)val2).transform, val.transform);
					bool flag = ContainsGrowthToken(((Object)val2).name);
					list4.Add(text + " :: " + string.Join(", ", from material in array
						where Object.op_Implicit((Object)(object)material)
						select ((Object)material).name));
					for (int num = 0; num < val3.subMeshCount; num++)
					{
						Material val4 = ((array.Length == 0) ? null : array[Math.Min(num, array.Length - 1)]);
						string text2 = ((Object.op_Implicit((Object)(object)val4) && Object.op_Implicit((Object)(object)val4.mainTexture)) ? ((Object)val4.mainTexture).name : string.Empty);
						string identity = (Object.op_Implicit((Object)(object)val4) ? ((Object)val4).name : string.Empty) + " " + text2;
						if (flag || ContainsGrowthToken(identity))
						{
							CombineInstance item = default(CombineInstance);
							((CombineInstance)(ref item)).mesh = val3;
							((CombineInstance)(ref item)).subMeshIndex = num;
							((CombineInstance)(ref item)).transform = worldToLocalMatrix * ((Component)val2).transform.localToWorldMatrix;
							list.Add(item);
							list2.Add(val4);
							list3.Add(text + "[" + num + "] / " + (Object.op_Implicit((Object)(object)val4) ? ((Object)val4).name : "<no material>"));
						}
					}
				}
				if (list.Count == 0)
				{
					if (!_loggedFailure)
					{
						RootboundWitchPlugin.Log.LogWarning((object)("Bog Witch branch extraction found no named growth geometry. Live renderer inventory: " + string.Join(" | ", list4)));
						_loggedFailure = true;
					}
					return;
				}
				Mesh val5 = new Mesh
				{
					name = "Rootbound_BogWitchBranchCrownMesh",
					indexFormat = (IndexFormat)1
				};
				val5.CombineMeshes(list.ToArray(), false, true, false);
				val5.RecalculateBounds();
				_combinedBounds = val5.bounds;
				Bounds bounds = val5.bounds;
				float y = ((Bounds)(ref bounds)).min.y;
				bounds = val5.bounds;
				float splitY = y + ((Bounds)(ref bounds)).size.y * 0.38f;
				Mesh mesh = SplitMesh(val5, splitY, lower: false);
				Mesh mesh2 = SplitMesh(val5, splitY, lower: true);
				_ordinaryMaterials = list2.ToArray();
				_permafrostMaterials = PermafrostVisuals.BuildExternalWhiteMaterials(_ordinaryMaterials);
				_upperTemplate = CreateTemplate("Rootbound_BogWitchBranchCrownUpperTemplate", mesh);
				_lowerTemplate = CreateTemplate("Rootbound_BogWitchBranchCrownLowerTemplate", mesh2);
				_loggedFailure = false;
				RootboundWitchPlugin.Log.LogInfo((object)("Bog Witch back-growth extracted " + list.Count + " exact branch submeshes: " + string.Join(" | ", list3)));
			}
			catch (Exception ex)
			{
				if (!_loggedFailure)
				{
					RootboundWitchPlugin.Log.LogWarning((object)("Bog Witch branch-only extraction failed safely; gameplay content remains intact: " + ex.GetBaseException().Message));
					_loggedFailure = true;
				}
			}
		}

		internal static void Update(Player player, bool active)
		{
			if (!RootboundWitchPlugin.EnableBogWitchBackGrowth.Value || !active || (Object)(object)player == (Object)null)
			{
				ClearInstance();
				return;
			}
			if (!Object.op_Implicit((Object)(object)_upperTemplate) || !Object.op_Implicit((Object)(object)_lowerTemplate))
			{
				Prepare();
				if (!Object.op_Implicit((Object)(object)_upperTemplate) || !Object.op_Implicit((Object)(object)_lowerTemplate))
				{
					return;
				}
			}
			if (!Object.op_Implicit((Object)(object)_upperInstance) || !Object.op_Implicit((Object)(object)_lowerInstance) || (Object)(object)_owner != (Object)(object)player)
			{
				ClearInstance();
				_owner = player;
				_upperInstance = CreateInstance(_upperTemplate, "Rootbound_BogWitchBranchCrownUpper", player);
				_lowerInstance = CreateInstance(_lowerTemplate, "Rootbound_BogWitchBranchCrownLower", player);
				AttachToAnimatedTorso(_upperInstance, player, lower: false);
				AttachToAnimatedTorso(_lowerInstance, player, lower: true);
				_upperInstance.SetActive(true);
				_lowerInstance.SetActive(true);
				_materialStateKnown = false;
			}
			bool flag = RootboundState.IsPermafrost(player);
			if (!_materialStateKnown || _lastPermafrost != flag)
			{
				Material[] materials = (flag ? _permafrostMaterials : _ordinaryMaterials);
				ApplyMaterials(_upperInstance, materials);
				ApplyMaterials(_lowerInstance, materials);
				_lastPermafrost = flag;
				_materialStateKnown = true;
			}
		}

		internal static void Clear()
		{
			ClearInstance();
			if (Object.op_Implicit((Object)(object)_upperTemplate))
			{
				Object.Destroy((Object)(object)_upperTemplate);
			}
			if (Object.op_Implicit((Object)(object)_lowerTemplate))
			{
				Object.Destroy((Object)(object)_lowerTemplate);
			}
			_upperTemplate = null;
			_lowerTemplate = null;
			_ordinaryMaterials = null;
			_permafrostMaterials = null;
		}

		private static void ClearInstance()
		{
			if (Object.op_Implicit((Object)(object)_upperInstance))
			{
				Object.Destroy((Object)(object)_upperInstance);
			}
			if (Object.op_Implicit((Object)(object)_lowerInstance))
			{
				Object.Destroy((Object)(object)_lowerInstance);
			}
			_upperInstance = null;
			_lowerInstance = null;
			_owner = null;
			_materialStateKnown = false;
		}

		private static GameObject CreateInstance(GameObject template, string name, Player player)
		{
			GameObject obj = Object.Instantiate<GameObject>(template, ((Component)player).transform, false);
			((Object)obj).name = name;
			((Object)obj).hideFlags = (HideFlags)52;
			PositionOnBack(obj);
			return obj;
		}

		private static void PositionOnBack(GameObject crown)
		{
			//IL_0005: 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_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: 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_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: 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)
			Vector3 size = ((Bounds)(ref _combinedBounds)).size;
			Bounds val = (Bounds)((((Vector3)(ref size)).sqrMagnitude > 0f) ? _combinedBounds : new Bounds(Vector3.zero, Vector3.one));
			float num = Mathf.Max(0.5f, RootboundWitchPlugin.BogWitchGrowthWidth.Value);
			float num2 = Mathf.Max(0.5f, RootboundWitchPlugin.BogWitchGrowthHeight.Value);
			float num3 = Mathf.Min(num / Mathf.Max(0.05f, ((Bounds)(ref val)).size.x), num2 / Mathf.Max(0.05f, ((Bounds)(ref val)).size.y));
			num3 = Mathf.Clamp(num3, 0.05f, 12f);
			crown.transform.localRotation = Quaternion.identity;
			crown.transform.localScale = Vector3.one * num3;
			Vector3 val2 = default(Vector3);
			((Vector3)(ref val2))..ctor(0f, RootboundWitchPlugin.BogWitchGrowthVerticalOffset.Value, RootboundWitchPlugin.BogWitchGrowthBackOffset.Value);
			crown.transform.localPosition = val2 - ((Bounds)(ref val)).center * num3;
		}

		private static void AttachToAnimatedTorso(GameObject crown, Player player, bool lower)
		{
			Transform val = (lower ? FindLowerBackAttachment(player) : FindBackAttachment(player));
			if (!Object.op_Implicit((Object)(object)val) || (Object)(object)val == (Object)(object)((Component)player).transform)
			{
				RootboundWitchPlugin.Log.LogWarning((object)"Bog Witch branch crown found no animated torso anchor; retaining player-root attachment.");
				return;
			}
			crown.transform.SetParent(val, true);
			RootboundWitchPlugin.Log.LogInfo((object)("Bog Witch branch crown " + (lower ? "lower" : "upper") + " section bound to animated anchor: " + HierarchyPath(val, ((Component)player).transform)));
		}

		private static Transform FindLowerBackAttachment(Player player)
		{
			//IL_0051: 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)
			if ((Object)(object)player == (Object)null)
			{
				return null;
			}
			Animator val = ((IEnumerable<Animator>)((Component)player).GetComponentsInChildren<Animator>(true)).FirstOrDefault((Func<Animator, bool>)((Animator candidate) => Object.op_Implicit((Object)(object)candidate) && candidate.isHuman));
			if (Object.op_Implicit((Object)(object)val))
			{
				HumanBodyBones[] array = (HumanBodyBones[])(object)new HumanBodyBones[2]
				{
					default(HumanBodyBones),
					(HumanBodyBones)7
				};
				foreach (HumanBodyBones val2 in array)
				{
					Transform boneTransform = val.GetBoneTransform(val2);
					if (Object.op_Implicit((Object)(object)boneTransform))
					{
						return boneTransform;
					}
				}
			}
			Transform[] componentsInChildren = ((Component)player).GetComponentsInChildren<Transform>(true);
			string[] array2 = new string[5] { "pelvis", "hips", "hip", "spine1", "spine" };
			foreach (string token in array2)
			{
				Transform val3 = ((IEnumerable<Transform>)componentsInChildren).FirstOrDefault((Func<Transform, bool>)((Transform transform) => Normalize(((Object)transform).name).Contains(token)));
				if (Object.op_Implicit((Object)(object)val3))
				{
					return val3;
				}
			}
			return ((Component)player).transform;
		}

		private static GameObject CreateTemplate(string name, Mesh mesh)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Expected O, but got Unknown
			GameObject val = new GameObject(name);
			val.SetActive(false);
			((Object)val).hideFlags = (HideFlags)61;
			MeshFilter val2 = val.AddComponent<MeshFilter>();
			MeshRenderer obj = val.AddComponent<MeshRenderer>();
			val2.sharedMesh = mesh;
			((Renderer)obj).sharedMaterials = _ordinaryMaterials;
			((Renderer)obj).shadowCastingMode = (ShadowCastingMode)1;
			((Renderer)obj).receiveShadows = true;
			return val;
		}

		private static void ApplyMaterials(GameObject instance, Material[] materials)
		{
			if (Object.op_Implicit((Object)(object)instance))
			{
				MeshRenderer component = instance.GetComponent<MeshRenderer>();
				if (Object.op_Implicit((Object)(object)component))
				{
					((Renderer)component).sharedMaterials = materials;
				}
			}
		}

		private static Mesh SplitMesh(Mesh source, float splitY, bool lower)
		{
			//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_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: 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_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: 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_009e: Expected O, but got Unknown
			Mesh val = new Mesh
			{
				name = ((Object)source).name + (lower ? "_Lower" : "_Upper"),
				indexFormat = source.indexFormat,
				vertices = source.vertices,
				normals = source.normals,
				tangents = source.tangents,
				colors32 = source.colors32,
				uv = source.uv,
				uv2 = source.uv2,
				uv3 = source.uv3,
				uv4 = source.uv4,
				subMeshCount = source.subMeshCount
			};
			Vector3[] vertices = source.vertices;
			int num = 0;
			for (int i = 0; i < source.subMeshCount; i++)
			{
				int[] triangles = source.GetTriangles(i);
				List<int> list = new List<int>(triangles.Length);
				for (int j = 0; j + 2 < triangles.Length; j += 3)
				{
					float num2 = (vertices[triangles[j]].y + vertices[triangles[j + 1]].y + vertices[triangles[j + 2]].y) / 3f;
					if (lower ? (num2 <= splitY) : (num2 > splitY))
					{
						list.Add(triangles[j]);
						list.Add(triangles[j + 1]);
						list.Add(triangles[j + 2]);
						num++;
					}
				}
				val.SetTriangles(list, i, false);
			}
			if (num == 0)
			{
				Object.Destroy((Object)(object)val);
				throw new InvalidOperationException("Bog Witch branch crown split produced an empty " + (lower ? "lower" : "upper") + " section.");
			}
			val.RecalculateBounds();
			return val;
		}

		private static Transform FindBackAttachment(Player player)
		{
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)player == (Object)null)
			{
				return null;
			}
			string[] obj = new string[5] { "attach_back", "attachback", "back_attach", "attach_backtool", "backtool" };
			Transform[] componentsInChildren = ((Component)player).GetComponentsInChildren<Transform>(true);
			string[] array = obj;
			foreach (string target in array)
			{
				Transform val = ((IEnumerable<Transform>)componentsInChildren).FirstOrDefault((Func<Transform, bool>)((Transform transform) => string.Equals(Normalize(((Object)transform).name), target, StringComparison.OrdinalIgnoreCase)));
				if (Object.op_Implicit((Object)(object)val))
				{
					return val;
				}
			}
			Animator val2 = ((IEnumerable<Animator>)((Component)player).GetComponentsInChildren<Animator>(true)).FirstOrDefault((Func<Animator, bool>)((Animator candidate) => Object.op_Implicit((Object)(object)candidate) && candidate.isHuman));
			if (Object.op_Implicit((Object)(object)val2))
			{
				HumanBodyBones[] array2 = new HumanBodyBones[3];
				RuntimeHelpers.InitializeArray(array2, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
				HumanBodyBones[] array3 = (HumanBodyBones[])(object)array2;
				foreach (HumanBodyBones val3 in array3)
				{
					Transform boneTransform = val2.GetBoneTransform(val3);
					if (Object.op_Implicit((Object)(object)boneTransform))
					{
						return boneTransform;
					}
				}
			}
			return ((IEnumerable<Transform>)componentsInChildren).FirstOrDefault((Func<Transform, bool>)((Transform transform) => Normalize(((Object)transform).name).Contains("spine2"))) ?? ((IEnumerable<Transform>)componentsInChildren).FirstOrDefault((Func<Transform, bool>)((Transform transform) => Normalize(((Object)transform).name).Contains("spine1")));
		}

		private static string Normalize(string value)
		{
			return (value ?? string.Empty).Replace(" ", string.Empty).Replace("-", string.Empty).ToLowerInvariant();
		}

		private static string HierarchyPath(Transform transform, Transform root)
		{
			List<string> list = new List<string>();
			Transform val = transform;
			while ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)root)
			{
				list.Add(((Object)val).name);
				val = val.parent;
			}
			list.Reverse();
			return string.Join("/", list);
		}

		private static Mesh SourceMesh(Renderer renderer)
		{
			SkinnedMeshRenderer val = (SkinnedMeshRenderer)(object)((renderer is SkinnedMeshRenderer) ? renderer : null);
			if ((Object)(object)val != (Object)null)
			{
				return val.sharedMesh;
			}
			MeshFilter component = ((Component)renderer).GetComponent<MeshFilter>();
			if (!Object.op_Implicit((Object)(object)component))
			{
				return null;
			}
			return component.sharedMesh;
		}

		private static bool ContainsGrowthToken(string identity)
		{
			string text = (identity ?? string.Empty).ToLowerInvariant();
			return GrowthTokens.Any(text.Contains);
		}

		private static string RelativePath(Transform transform, Transform root)
		{
			List<string> list = new List<string>();
			Transform val = transform;
			while ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)root)
			{
				list.Add(((Object)val).name);
				val = val.parent;
			}
			list.Reverse();
			return string.Join("/", list);
		}
	}
	internal static class DraugrRotVisuals
	{
		private const string ProjectilePrefabName = "RootboundCrook_DraugrRotProjectile";

		private static readonly Color RotDark = new Color(0.006f, 0.022f, 0.01f, 0.1f);

		private static readonly Color RotLight = new Color(0.045f, 0.115f, 0.038f, 0.26f);

		private static readonly string[] ColourProperties = new string[3] { "_Color", "_BaseColor", "_TintColor" };

		private static GameObject _projectile;

		internal static void ApplyToAttack(Attack attack)
		{
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Expected O, but got Unknown
			if (attack != null && Object.op_Implicit((Object)(object)attack.m_attackProjectile))
			{
				if (!Object.op_Implicit((Object)(object)_projectile))
				{
					_projectile = PrefabManager.Instance.CreateClonedPrefab("RootboundCrook_DraugrRotProjectile", attack.m_attackProjectile);
					_projectile.AddComponent<RootboundTriangleProjectile>();
					Recolour(_projectile);
					PrefabManager.Instance.AddPrefab(new CustomPrefab(_projectile, true));
					RootboundWitchPlugin.Log.LogInfo((object)("Rootbound Crook projectile recoloured to the draugr-rot palette from " + ((Object)attack.m_attackProjectile).name + "."));
				}
				attack.m_attackProjectile = _projectile;
			}
		}

		internal static void Recolour(GameObject visual)
		{
			//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_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: 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)
			if (!Object.op_Implicit((Object)(object)visual))
			{
				return;
			}
			ParticleSystem[] componentsInChildren = visual.GetComponentsInChildren<ParticleSystem>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				MainModule main = componentsInChildren[i].main;
				Color rotDark = RotDark;
				Color rotLight = RotLight;
				((MainModule)(ref main)).startColor = new MinMaxGradient(rotDark, rotLight);
			}
			Light[] componentsInChildren2 = visual.GetComponentsInChildren<Light>(true);
			foreach (Light obj in componentsInChildren2)
			{
				((Behaviour)obj).enabled = false;
				obj.intensity = 0f;
			}
			Renderer[] componentsInChildren3 = visual.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren3)
			{
				Material[] array = ((IEnumerable<Material>)val.sharedMaterials).Select((Func<Material, Material>)((Material material) => Object.op_Implicit((Object)(object)material) ? new Material(material) : ((Material)null))).ToArray();
				Material[] array2 = array;
				for (int num = 0; num < array2.Length; num++)
				{
					Tint(array2[num], val is ParticleSystemRenderer || val is TrailRenderer);
				}
				val.sharedMaterials = array;
			}
		}

		private static void Tint(Material material, bool airborne)
		{
			//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_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: 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)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)material))
			{
				return;
			}
			((Object)material).name = ((Object)material).name + "_DraugrRot";
			string[] colourProperties = ColourProperties;
			foreach (string text in colourProperties)
			{
				if (material.HasProperty(text))
				{
					Color color = material.GetColor(text);
					Color val = Color.Lerp(RotDark, RotLight, Mathf.Clamp01(((Color)(ref color)).grayscale));
					val.a = (airborne ? 0.2f : Mathf.Min(0.42f, Mathf.Max(0.22f, color.a * 0.38f)));
					material.SetColor(text, val);
				}
			}
			if (material.HasProperty("_EmissionColor"))
			{
				material.SetColor("_EmissionColor", Color.black);
			}
			material.DisableKeyword("_EMISSION");
			if (airborne)
			{
				if (material.HasProperty("_Surface"))
				{
					material.SetFloat("_Surface", 1f);
				}
				if (material.HasProperty("_Mode"))
				{
					material.SetFloat("_Mode", 3f);
				}
				if (material.HasProperty("_SrcBlend"))
				{
					material.SetInt("_SrcBlend", 5);
				}
				if (material.HasProperty("_DstBlend"))
				{
					material.SetInt("_DstBlend", 10);
				}
				if (material.HasProperty("_ZWrite"))
				{
					material.SetInt("_ZWrite", 0);
				}
				material.EnableKeyword("_SURFACE_TYPE_TRANSPARENT");
				material.EnableKeyword("_ALPHABLEND_ON");
				material.DisableKeyword("_ALPHATEST_ON");
				material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
				material.renderQueue = 3000;
			}
		}
	}
	internal sealed class RootboundTriangleProjectile : MonoBehaviour
	{
		private static readonly FieldRef<Projectile, Character> Owner = AccessTools.FieldRefAccess<Projectile, Character>("m_owner");

		private static readonly FieldRef<Projectile, Vector3> Velocity = AccessTools.FieldRefAccess<Projectile, Vector3>("m_vel");

		private static readonly FieldRef<Projectile, Vector3> StartPoint = AccessTools.FieldRefAccess<Projectile, Vector3>("m_startPoint");

		private static int _sequence;

		private Projectile _projectile;

		private bool _placed;

		private void Awake()
		{
			_projectile = ((Component)this).GetComponent<Projectile>();
		}

		private void Update()
		{
			//IL_006b: 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_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)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: 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_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			if (!_placed && !((Object)(object)_projectile == (Object)null) && !((Object)(object)Owner.Invoke(_projectile) == (Object)null) && !(((Vector3)(ref Velocity.Invoke(_projectile))).sqrMagnitude < 0.01f))
			{
				int num = (Interlocked.Increment(ref _sequence) - 1) % 3;
				Vector3 val = Vector3.ProjectOnPlane(((Vector3)(ref Velocity.Invoke(_projectile))).normalized, Vector3.up);
				Vector3 normalized = ((Vector3)(ref val)).normalized;
				if (((Vector3)(ref normalized)).sqrMagnitude < 0.01f)
				{
					val = Vector3.ProjectOnPlane(((Component)Owner.Invoke(_projectile)).transform.forward, Vector3.up);
					normalized = ((Vector3)(ref val)).normalized;
				}
				val = Vector3.Cross(Vector3.up, normalized);
				Vector3 normalized2 = ((Vector3)(ref val)).normalized;
				float num2 = (float)num * (float)Math.PI * 2f / 3f + (float)Math.PI / 2f;
				Vector3 val2 = normalized2 * (Mathf.Cos(num2) * 1.9f) + normalized * (Mathf.Sin(num2) * 1.9f);
				Transform transform = ((Component)this).transform;
				transform.position += val2;
				StartPoint.Invoke(_projectile) = StartPoint.Invoke(_projectile) + val2;
				_placed = true;
			}
		}
	}
	internal static class FrostedRootAttacks
	{
		private static GameObject _moderProjectile;

		private static GameObject _elderProjectile;

		internal static Attack BuildPrimary(Attack architecture)
		{
			Attack obj = CloneArchitecture(architecture);
			obj.m_attackProjectile = GetModerProjectile();
			obj.m_projectiles = 6;
			obj.m_projectileBursts = 1;
			obj.m_burstInterval = 0f;
			obj.m_projectileAccuracy = 0f;
			obj.m_projectileAccuracyMin = 0f;
			obj.m_randomVelocity = false;
			obj.m_damageMultiplier = 1f;
			return obj;
		}

		internal static Attack BuildSecondary(Attack architecture)
		{
			Attack obj = CloneArchitecture(architecture);
			obj.m_attackProjectile = GetElderProjectile();
			obj.m_projectiles = 1;
			obj.m_projectileBursts = 1;
			obj.m_burstInterval = 0f;
			obj.m_perBurstResourceUsage = false;
			obj.m_projectileAccuracy = 0f;
			obj.m_projectileAccuracyMin = 0f;
			obj.m_randomVelocity = false;
			obj.m_damageMultiplier = 1f;
			obj.m_attackEitr = Mathf.Max(obj.m_attackEitr, 45f);
			return obj;
		}

		private static Attack CloneArchitecture(Attack architecture)
		{
			if (architecture == null)
			{
				throw new InvalidOperationException("The live Deep North staff has no projectile attack architecture.");
			}
			return architecture.Clone();
		}

		private static GameObject GetModerProjectile()
		{
			if (!Object.op_Implicit((Object)(object)_moderProjectile))
			{
				_moderProjectile = CloneSkyProjectile("FrostedRoot_ModerSkyShard", "dragon_ice_projectile", "staff_iceshard_projectile", 20f, 3.4f, 102f);
			}
			return _moderProjectile;
		}

		private static GameObject GetElderProjectile()
		{
			if (!Object.op_Implicit((Object)(object)_elderProjectile))
			{
				_elderProjectile = CloneSkyProjectile("FrostedRoot_ElderSkyRoot", "gdking_root_projectile", "staff_greenroots_projectile", 20f, 0.35f, 102f);
			}
			return _elderProjectile;
		}

		private static GameObject CloneSkyProjectile(string cloneName, string bossPrefab, string fallbackPrefab, float height, float spread, float speed)
		{
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Expected O, but got Unknown
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = RootboundContent.FindPrefab(bossPrefab);
			bool flag = false;
			if (!Object.op_Implicit((Object)(object)val))
			{
				val = RootboundContent.FindPrefab(fallbackPrefab);
				flag = true;
			}
			if (!Object.op_Implicit((Object)(object)val) || (Object)(object)val.GetComponent<Projectile>() == (Object)null)
			{
				throw new InvalidOperationException("Neither " + bossPrefab + " nor " + fallbackPrefab + " resolved to a live Projectile prefab.");
			}
			GameObject val2 = PrefabManager.Instance.CreateClonedPrefab(cloneName, val);
			val2.AddComponent<FrostedRootSkyRedirect>().Configure(height, spread, speed);
			if (cloneName == "FrostedRoot_ElderSkyRoot")
			{
				val2.transform.localScale = Vector3.Scale(val2.transform.localScale, new Vector3(0.055f, 0.055f, 0.32f));
				MakeElderProjectileWhite(val2);
				val2.AddComponent<FrostedRootElderBurstSeed>();
			}
			PrefabManager.Instance.AddPrefab(new CustomPrefab(val2, true));
			RootboundWitchPlugin.Log.LogInfo((object)("Frosted Root projectile " + cloneName + " cloned from " + ((Object)val).name + (flag ? " (boss prefab unavailable; live staff fallback)." : ".")));
			return val2;
		}

		private static void MakeElderProjectileWhite(GameObject projectile)
		{
			//IL_0225: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: Unknown result type (might be due to invalid IL or missing references)
			//IL_022e: Unknown result type (might be due to invalid IL or missing references)
			//IL_022f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0268: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_009a: Expected O, but got Unknown
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: 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_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			Color val = default(Color);
			((Color)(ref val))..ctor(0.88f, 0.95f, 1f, 1f);
			Renderer[] componentsInChildren = projectile.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val2 in componentsInChildren)
			{
				if (val2 is TrailRenderer || val2 is LineRenderer)
				{
					val2.enabled = false;
					continue;
				}
				Material[] sharedMaterials = val2.sharedMaterials;
				Material[] array = (Material[])(object)new Material[sharedMaterials.Length];
				for (int j = 0; j < sharedMaterials.Length; j++)
				{
					if (Object.op_Implicit((Object)(object)sharedMaterials[j]))
					{
						Material val3 = new Material(sharedMaterials[j])
						{
							name = ((Object)sharedMaterials[j]).name + "_FrostedRootWhiteProjectile"
						};
						if (val3.HasProperty("_MainTex"))
						{
							val3.SetTexture("_MainTex", (Texture)(object)Texture2D.whiteTexture);
						}
						if (val3.HasProperty("_BaseMap"))
						{
							val3.SetTexture("_BaseMap", (Texture)(object)Texture2D.whiteTexture);
						}
						if (val3.HasProperty("_Color"))
						{
							val3.SetColor("_Color", val);
						}
						if (val3.HasProperty("_BaseColor"))
						{
							val3.SetColor("_BaseColor", val);
						}
						if (val3.HasProperty("_TintColor"))
						{
							val3.SetColor("_TintColor", val);
						}
						if (val3.HasProperty("_EmissionColor"))
						{
							val3.SetColor("_EmissionColor", val * 0.22f);
						}
						if (val3.HasProperty("_Hue"))
						{
							val3.SetFloat("_Hue", 0.55f);
						}
						if (val3.HasProperty("_Saturation"))
						{
							val3.SetFloat("_Saturation", 0.08f);
						}
						if (val3.HasProperty("_Value"))
						{
							val3.SetFloat("_Value", 1f);
						}
						array[j] = val3;
					}
				}
				val2.sharedMaterials = array;
				TrailRenderer val4 = (TrailRenderer)(object)((val2 is TrailRenderer) ? val2 : null);
				if (Object.op_Implicit((Object)(object)val4))
				{
					val4.startColor = val;
					val4.endColor = new Color(val.r, val.g, val.b, 0f);
				}
			}
			ParticleSystem[] componentsInChildren2 = projectile.GetComponentsInChildren<ParticleSystem>(true);
			for (int i = 0; i < componentsInChildren2.Length; i++)
			{
				MainModule main = componentsInChildren2[i].main;
				((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(val);
				((MainModule)(ref main)).startSizeMultiplier = ((MainModule)(ref main)).startSizeMultiplier * 0.12f;
			}
			Light[] componentsInChildren3 = projectile.GetComponentsInChildren<Light>(true);
			for (int i = 0; i < componentsInChildren3.Length; i++)
			{
				componentsInChildren3[i].color = val;
			}
		}

		internal static void BeginElderContinuation(Projectile seed)
		{
			if (Object.op_Implicit((Object)(object)seed) && Object.op_Implicit((Object)(object)RootboundWitchPlugin.Instance))
			{
				((MonoBehaviour)RootboundWitchPlugin.Instance).StartCoroutine(EmitElderContinuation(seed));
			}
		}

		private static IEnumerator EmitElderContinuation(Projectile seed)
		{
			Character owner = FrostedRootProjectileState.Owner(seed);
			HitData hitData = FrostedRootProjectileState.HitData(seed);
			ItemData weapon = FrostedRootProjectileState.Weapon(seed);
			ItemData ammo = FrostedRootProjectileState.Ammo(seed);
			float hitNoise = seed.m_hitNoise;
			int index = 1;
			while (index < 15)
			{
				yield return (object)new WaitForSeconds(0.5f);
				if (!Object.op_Implicit((Object)(object)owner) || !Object.op_Implicit((Object)(object)GetElderProjectile()))
				{
					break;
				}
				Vector3 lookDir = owner.GetLookDir();
				Vector3 val = ((Vector3)(ref lookDir)).normalized * 10f;
				GameObject obj = Object.Instantiate<GameObject>(GetElderProjectile(), owner.GetEyePoint(), Quaternion.LookRotation(val));
				FrostedRootElderBurstSeed component = obj.GetComponent<FrostedRootElderBurstSeed>();
				if (Object.op_Implicit((Object)(object)component))
				{
					component.MarkContinuation();
				}
				obj.GetComponent<Projectile>().Setup(owner, val, hitNoise, (HitData)((hitData != null) ? ((object)hitData.Clone()) : ((object)new HitData())), weapon, ammo);
				int num = index + 1;
				index = num;
			}
		}
	}
	internal static class FrostedRootProjectileState
	{
		private static readonly FieldRef<Projectile, Character> OwnerField = AccessTools.FieldRefAccess<Projectile, Character>("m_owner");

		private static readonly FieldRef<Projectile, HitData> HitDataField = AccessTools.FieldRefAccess<Projectile, HitData>("m_originalHitData");

		private static readonly FieldRef<Projectile, ItemData> WeaponField = AccessTools.FieldRefAccess<Projectile, ItemData>("m_weapon");

		private static readonly FieldRef<Projectile, ItemData> AmmoField = AccessTools.FieldRefAccess<Projectile, ItemData>("m_ammo");

		internal static Character Owner(Projectile projectile)
		{
			return OwnerField.Invoke(projectile);
		}

		internal static HitData HitData(Projectile projectile)
		{
			return HitDataField.Invoke(projectile);
		}

		internal static ItemData Weapon(Projectile projectile)
		{
			return WeaponField.Invoke(projectile);
		}

		internal static ItemData Ammo(Projectile projectile)
		{
			return AmmoField.Invoke(projectile);
		}
	}
	internal sealed class FrostedRootElderBurstSeed : MonoBehaviour
	{
		private bool _continuation;

		internal void MarkContinuation()
		{
			_continuation = true;
		}

		private void Start()
		{
			if (!_continuation)
			{
				Projectile component = ((Component)this).GetComponent<Projectile>();
				Character obj = (Object.op_Implicit((Object)(object)component) ? FrostedRootProjectileState.Owner(component) : null);
				Player val = (Player)(object)((obj is Player) ? obj : null);
				if (Object.op_Implicit((Object)(object)component) && ((Object)(object)val == (Object)null || (Object)(object)val == (Object)(object)Player.m_localPlayer))
				{
					FrostedRootAttacks.BeginElderContinuation(component);
				}
			}
		}
	}
	internal sealed class FrostedRootSkyRedirect : MonoBehaviour
	{
		private static readonly FieldRef<Projectile, Character> Owner = AccessTools.FieldRefAccess<Projectile, Character>("m_owner");

		private static readonly FieldRef<Projectile, Vector3> Velocity = AccessTools.FieldRefAccess<Projectile, Vector3>("m_vel");

		private static readonly FieldRef<Projectile, Vector3> StartPoint = AccessTools.FieldRefAccess<Projectile, Vector3>("m_startPoint");

		private static readonly FieldRef<Projectile, bool> HaveStartPoint = AccessTools.FieldRefAccess<Projectile, bool>("m_haveStartPoint");

		private float _height;

		private float _spread;

		private float _speed;

		private Projectile _projectile;

		private bool _redirected;

		internal void Configure(float height, float spread, float speed)
		{
			_height = height;
			_spread = spread;
			_speed = speed;
		}

		private void Awake()
		{
			_projectile = ((Component)this).GetComponent<Projectile>();
		}

		private void Start()
		{
			RedirectNow();
		}

		private void Update()
		{
			if (!_redirected)
			{
				RedirectNow();
			}
		}

		internal void RedirectNow()
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: 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)
			//IL_0054: 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)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: 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_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00ed: 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)
			if (!_redirected && !((Object)(object)_projectile == (Object)null))
			{
				Character val = Owner.Invoke(_projectile);
				if (!((Object)(object)val == (Object)null))
				{
					Vector3 val2 = FindTargetPoint(val);
					Vector2 val3 = Random.insideUnitCircle * Mathf.Max(0f, _spread);
					Vector3 val4 = val2 + new Vector3(val3.x, 0f, val3.y) + Vector3.up * Mathf.Max(3f, _height);
					Vector3 down = Vector3.down;
					((Component)this).transform.position = val4;
					((Component)this).transform.rotation = Quaternion.LookRotation(down);
					Velocity.Invoke(_projectile) = down * Mathf.Max(8f, _speed);
					StartPoint.Invoke(_projectile) = val4;
					HaveStartPoint.Invoke(_projectile) = true;
					_redirected = true;
				}
			}
		}

		private static Vector3 FindTargetPoint(Character owner)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: 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_0017: 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_003e: 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)
			//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)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: 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_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: 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_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			Vector3 eyePoint = owner.GetEyePoint();
			Vector3 lookDir = owner.GetLookDir();
			Vector3 normalized = ((Vector3)(ref lookDir)).normalized;
			RaycastHit val2 = default(RaycastHit);
			Vector3 val = (Physics.Raycast(eyePoint, normalized, ref val2, 4096f, -1, (QueryTriggerInteraction)1) ? ((RaycastHit)(ref val2)).point : (eyePoint + normalized * 512f));
			RaycastHit val3 = default(RaycastHit);
			if (Physics.Raycast(val + Vector3.up * 30f, Vector3.down, ref val3, 180f, -1, (QueryTriggerInteraction)1))
			{
				val = ((RaycastHit)(ref val3)).point + Vector3.up * 0.1f;
			}
			return val;
		}
	}
	[HarmonyPatch(typeof(Projectile), "Setup")]
	internal static class FrostedRootImmediateRedirectPatch
	{
		private static void Postfix(Projectile __instance)
		{
			FrostedRootSkyRedirect frostedRootSkyRedirect = (((Object)(object)__instance != (Object)null) ? ((Component)__instance).GetComponent<FrostedRootSkyRedirect>() : null);
			if (Object.op_Implicit((Object)(object)frostedRootSkyRedirect))
			{
				frostedRootSkyRedirect.RedirectNow();
			}
		}
	}
	internal static class FrostedStaffVisual
	{
		private static Texture2D _snowTexture;

		internal static void Apply(GameObject itemPrefab)
		{
			//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_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Expected O, but got Unknown
			if (!Object.op_Implicit((Object)(object)itemPrefab))
			{
				return;
			}
			Light[] componentsInChildren = itemPrefab.GetComponentsInChildren<Light>(true);
			foreach (Light obj in componentsInChildren)
			{
				((Behaviour)obj).enabled = false;
				obj.intensity = 0f;
			}
			ParticleSystem[] componentsInChildren2 = itemPrefab.GetComponentsInChildren<ParticleSystem>(true);
			foreach (ParticleSystem obj2 in componentsInChildren2)
			{
				obj2.Stop(true, (ParticleSystemStopBehavior)0);
				EmissionModule emission = obj2.emission;
				((EmissionModule)(ref emission)).enabled = false;
			}
			Renderer[] componentsInChildren3 = itemPrefab.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren3)
			{
				Material[] sharedMaterials = val.sharedMaterials;
				bool flag = false;
				bool flag2 = true;
				for (int j = 0; j < sharedMaterials.Length; j++)
				{
					if (Object.op_Implicit((Object)(object)sharedMaterials[j]))
					{
						flag = true;
						if (!IsDeadCore(sharedMaterials[j]))
						{
							flag2 = false;
						}
					}
				}
				if (flag && flag2)
				{
					val.enabled = false;
					((Component)val).gameObject.SetActive(false);
					RootboundWitchPlugin.Log.LogInfo((object)("Frosted Root removed dead Surtling-core renderer " + ((Object)((Component)val).gameObject).name + "."));
					continue;
				}
				Material[] array = (Material[])(object)new Material[sharedMaterials.Length];
				for (int k = 0; k < sharedMaterials.Length; k++)
				{
					if (Object.op_Implicit((Object)(object)sharedMaterials[k]))
					{
						Material val2 = new Material(sharedMaterials[k])
						{
							name = ((Object)sharedMaterials[k]).name + "_FrostedRoot"
						};
						if (IsDeadCore(val2))
						{
							MakeInvisible(val2);
						}
						else
						{
							ApplySnow(val2);
						}
						KillEmission(val2);
						array[k] = val2;
					}
				}
				val.sharedMaterials = array;
			}
		}

		internal static void RemoveDeadCoreOnly(GameObject itemPrefab, string visualName)
		{
			//IL_0113: 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_0131: Expected O, but got Unknown
			if (!Object.op_Implicit((Object)(object)itemPrefab))
			{
				return;
			}
			Renderer[] componentsInChildren = itemPrefab.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren)
			{
				Material[] sharedMaterials = val.sharedMaterials;
				bool num = IsDeadCoreName(((Object)((Component)val).gameObject).name);
				bool flag = sharedMaterials.Any((Material material) => Object.op_Implicit((Object)(object)material)) && sharedMaterials.Where((Material material) => Object.op_Implicit((Object)(object)material)).All(IsDeadCore);
				if (num || flag)
				{
					val.enabled = false;
					((Component)val).gameObject.SetActive(false);
					RootboundWitchPlugin.Log.LogInfo((object)(visualName + " removed dead Surtling-core renderer " + ((Object)((Component)val).gameObject).name + "."));
					continue;
				}
				Material[] array = (Material[])(object)new Material[sharedMaterials.Length];
				bool flag2 = false;
				for (int num2 = 0; num2 < sharedMaterials.Length; num2++)
				{
					Material val2 = sharedMaterials[num2];
					if (Object.op_Implicit((Object)(object)val2))
					{
						Material val3 = val2;
						if (IsDeadCore(val2))
						{
							val3 = new Material(val2)
							{
								name = ((Object)val2).name + "_RemovedCore"
							};
							MakeInvisible(val3);
							KillEmission(val3);
							flag2 = true;
						}
						array[num2] = val3;
					}
				}
				if (flag2)
				{
					val.sharedMaterials = array;
				}
			}
		}

		private static bool IsDeadCore(Material material)
		{
			if ((Object)(object)material != (Object)null)
			{
				return IsDeadCoreName(((Object)material).name);
			}
			return false;
		}

		private static bool IsDeadCoreName(string name)
		{
			if (!string.IsNullOrEmpty(name))
			{
				if (name.IndexOf("RootboundDeadCore", StringComparison.OrdinalIgnoreCase) < 0 && name.IndexOf("Rootbound_DeadCore", StringComparison.OrdinalIgnoreCase) < 0 && name.IndexOf("surtling", StringComparison.OrdinalIgnoreCase) < 0 && name.IndexOf("ember", StringComparison.OrdinalIgnoreCase) < 0 && name.IndexOf("firecore", StringComparison.OrdinalIgnoreCase) < 0)
				{
					return name.IndexOf("flames", StringComparison.OrdinalIgnoreCase) >= 0;
				}
				return true;
			}
			return false;
		}

		private static void ApplySnow(Material material)
		{
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			Texture2D snowTexture = GetSnowTexture();
			if (material.HasProperty("_MainTex"))
			{
				material.SetTexture("_MainTex", (Texture)(object)snowTexture);
			}
			if (material.HasProperty("_BaseMap"))
			{
				material.SetTexture("_BaseMap", (Texture)(object)snowTexture);
			}
			if (material.HasProperty("_BumpMap"))
			{
				material.SetTexture("_BumpMap", (Texture)null);
			}
			if (material.HasProperty("_MetallicGlossMap"))
			{
				material.SetTexture("_MetallicGlossMap", (Texture)null);
			}
			SetColour(material, Color.white);
		}

		private static Texture2D GetSnowTexture()
		{
			//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_0028: 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_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Expected O, but got Unknown
			//IL_00db: 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)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)_snowTexture))
			{
				return _snowTexture;
			}
			_snowTexture = new Texture2D(16, 16, (TextureFormat)4, false)
			{
				name = "FrostedRoot_SnowedWoodTexture",
				filterMode = (FilterMode)0,
				wrapMode = (TextureWrapMode)0,
				hideFlags = (HideFlags)61
			};
			Color val = default(Color);
			((Color)(ref val))..ctor(0.72f, 0.82f, 0.84f, 1f);
			Color val2 = default(Color);
			((Color)(ref val2))..ctor(0.9f, 0.95f, 0.96f, 1f);
			Color val3 = default(Color);
			((Color)(ref val3))..ctor(0.47f, 0.59f, 0.61f, 1f);
			Color[] array = (Color[])(object)new Color[256];
			for (int i = 0; i < 16; i++)
			{
				for (int j = 0; j < 16; j++)
				{
					int num = (j * 19 + i * 31 + (j ^ i) * 7) % 17;
					array[i * 16 + j] = ((num < 3) ? val3 : ((num > 12) ? val2 : val));
				}
			}
			_snowTexture.SetPixels(array);
			_snowTexture.Apply(false, true);
			return _snowTexture;
		}

		private static void MakeInvisible(Material material)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			SetColour(material, new Color(0f, 0f, 0f, 0f));
			if (material.HasProperty("_Surface"))
			{
				material.SetFloat("_Surface", 1f);
			}
			if (material.HasProperty("_Mode"))
			{
				material.SetFloat("_Mode", 3f);
			}
			if (material.HasProperty("_SrcBlend"))
			{
				material.SetInt("_SrcBlend", 5);
			}
			if (material.HasProperty("_DstBlend"))
			{
				material.SetInt("_DstBlend", 10);
			}
			if (material.HasProperty("_ZWrite"))
			{
				material.SetInt("_ZWrite", 0);
			}
			material.EnableKeyword("_SURFACE_TYPE_TRANSPARENT");
			material.EnableKeyword("_ALPHABLEND_ON");
			material.renderQueue = 3000;
		}

		private static void SetColour(Material material, Color colour)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			if (material.HasProperty("_Color"))
			{
				material.SetColor("_Color", colour);
			}
			if (material.HasProperty("_BaseColor"))
			{
				material.SetColor("_BaseColor", colour);
			}
			if (material.HasProperty("_TintColor"))
			{
				material.SetColor("_TintColor", colour);
			}
		}

		private static void KillEmission(Material material)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			if (material.HasProperty("_EmissionColor"))
			{
				material.SetColor("_EmissionColor", Color.black);
			}
			if (material.HasProperty("_EmissionMap"))
			{
				material.SetTexture("_EmissionMap", (Texture)null);
			}
			material.DisableKeyword("_EMISSION");
			material.globalIlluminationFlags = (MaterialGlobalIlluminationFlags)4;
		}
	}
	internal static class PermafrostVisuals
	{
		private static readonly FieldRef<Humanoid, VisEquipment> Equipment = AccessTools.FieldRefAccess<Humanoid, VisEquipment>("m_visEquipment");

		private static readonly FieldRef<VisEquipment, SkinnedMeshRenderer> BodyModel = AccessTools.FieldRefAccess<VisEquipment, SkinnedMeshRenderer>("m_bodyModel");

		private static readonly FieldRef<VisEquipment, GameObject> HelmetInstance = AccessTools.FieldRefAccess<VisEquipment, GameObject>("m_helmetItemInstance");

		private static readonly FieldRef<VisEquipment, List<GameObject>> ChestInstances = AccessTools.FieldRefAccess<VisEquipment, List<GameObject>>("m_chestItemInstances");

		private static readonly FieldRef<VisEquipment, List<GameObject>> LegInstances = AccessTools.FieldRefAccess<VisEquipment, List<GameObject>>("m_legItemInstances");

		private static readonly Dictionary<Renderer, MaterialPropertyBlock> Previous = new Dictionary<Renderer, MaterialPropertyBlock>();

		private static readonly Dictionary<Renderer, Material[]> PreviousMaterials = new Dictionary<Renderer, Material[]>();

		private static readonly Dictionary<Texture, Texture2D> FrostedTextures = new Dictionary<Texture, Texture2D>();

		private static readonly Color Permafrost = new Color(0.82f, 0.89f, 0.94f, 1f);

		private static readonly int ChestTexture = Shader.PropertyToID("_ChestTex");

		private static readonly int LegsTexture = Shader.PropertyToID("_LegsTex");

		private static readonly int SkinColor = Shader.PropertyToID("_SkinColor");

		private static readonly Color DvergerBlue = new Color(0.35f, 0.5f, 0.72f, 1f);

		private static Material _bodyMaterial;

		private static SkinnedMeshRenderer _bodyRenderer;

		private static MaterialPropertyBlock _originalBodyBlock;

		private static bool _bodyBlockCaptured;

		private static Texture _originalChest;

		private static Texture _originalLegs;

		private static Texture _frostedChest;

		private static Texture _frostedLegs;

		private static Color _originalSkinColor;

		private static bool _skinColorCaptured;

		private static readonly Dictionary<Material, Color> PreviousSkinColours = new Dictionary<Material, Color>();

		private static MethodInfo _getEquippedBackpack;

		private static MethodInfo _getBackpackVisual;

		private static bool _backpackApiFailed;

		private static readonly List<GameObject> CrystalAccents = new List<GameObject>();

		private static readonly List<GameObject> CrystalHosts = new List<GameObject>();

		private static Material _crystalMaterial;

		internal static void BindBackpackApi(Assembly assembly)
		{
			Type type = ((assembly != null) ? assembly.GetType("Backpacks.API", throwOnError: false) : null);
			_getEquippedBackpack = ((type != null) ? type.GetMethod("GetEquippedBackpack", BindingFlags.Static | BindingFlags.Public, null, Type.EmptyTypes, null) : null);
			_getBackpackVisual = ((type != null) ? type.GetMethod("GetBackpackVisual", BindingFlags.Static | BindingFlags.Public, null, new Type[1] { typeof(Player) }, null) : null);
			_backpackApiFailed = false;
		}

		internal static void Update(Player player, bool active)
		{
			VisEquipment val = (((Object)(object)player != (Object)null) ? Equipment.Invoke((Humanoid)(object)player) : null);
			if (!active || (Object)(object)player == (Object)null || (Object)(object)val == (Object)null)
			{
				Clear();
				return;
			}
			HashSet<Renderer> hashSet = new HashSet<Renderer>();
			ApplyBodyTextures(val);
			List<GameObject> list = new List<GameObject>(GetSetVisuals(val));
			foreach (GameObject item in list)
			{
				ApplyWhiteVisual(item, hashSet);
			}
			foreach (GameObject rootboundSatchelVisual in GetRootboundSatchelVisuals(player))
			{
				ApplyWhiteVisual(rootboundSatchelVisual, hashSet);
			}
			UpdateCrystalAccents(player, list);
			foreach (Renderer item2 in new List<Renderer>(Previous.Keys))
			{
				if (!hashSet.Contains(item2))
				{
					Restore(item2);
				}
			}
		}

		internal static void Clear()
		{
			RestoreBodyTextures();
			foreach (Renderer item in new List<Renderer>(Previous.Keys))
			{
				Restore(item);
			}
			Previous.Clear();
			PreviousMaterials.Clear();
			ClearCrystalAccents();
		}

		internal static void ReapplyDvergerSkin(VisEquipment equipment)
		{
			SkinnedMeshRenderer val = (((Object)(object)equipment != (Object)null) ? BodyModel.Invoke(equipment) : null);
			if (Object.op_Implicit((Object)(object)val))
			{
				Material material = ((Renderer)val).material;
				if ((Object)(object)_bodyRenderer != (Object)(object)val || (Object)(object)_bodyMaterial != (Object)(object)material)
				{
					ApplyBodyTextures(equipment);
				}
				else
				{
					ApplyDvergerSkin(Player.m_localPlayer, val);
				}
			}
		}

		internal static Material[] BuildExternalWhiteMaterials(Material[] source)
		{
			return BuildWhiteMaterials((Material[])(((object)source) ?? ((object)new Material[0])));
		}

		private static IEnumerable<GameObject> GetSetVisuals(VisEquipment equipment)
		{
			GameObject val = HelmetInstance.Invoke(equipment);
			if (Object.op_Implicit((Object)(object)val))
			{
				yield return val;
			}
			List<GameObject> list = ChestInstances.Invoke(equipment);
			if (list != null)
			{
				foreach (GameObject item in list)
				{
					yield return item;
				}
			}
			List<GameObject> list2 = LegInstances.Invoke(equipment);
			if (list2 == null)
			{
				yield break;
			}
			foreach (GameObject item2 in list2)
			{
				yield return item2;
			}
		}

		private static IEnumerable<GameObject> GetRootboundSatchelVisuals(Player player)
		{
			if (_backpackApiFailed || _getEquippedBackpack == null || _getBackpackVisual == null || (Object)(object)player != (Object)(object)Player.m_localPlayer)
			{
				yield break;
			}
			object obj;
			object obj2;
			try
			{
				obj = _getEquippedBackpack.Invoke(null, null);
				obj2 = _getBackpackVisual.Invoke(null, new object[1] { player });
			}
			catch (Exception ex)
			{
				_backpackApiFailed = true;
				RootboundWitchPlugin.Log.LogWarning((object)("Rootbound Satchel permafrost bridge disabled: " + ex.GetBaseException().Message));
				yield break;
			}
			ItemData val = (ItemData)((obj is ItemData) ? obj : null);
			string obj3 = RootboundState.PrefabName(val) ?? string.Empty;
			string text = ((val != null && val.m_shared != null) ? (val.m_shared.m_name ?? string.Empty) : string.Empty);
			if ((obj3 + text).Replace(" ", string.Empty).Replace("_", string.Empty).IndexOf("RootboundSatchel", StringComparison.OrdinalIgnoreCase) < 0 || val.m_quality < 4 || !(obj2 is IEnumerable enumerable))
			{
				yield break;
			}
			foreach (object item in enumerable)
			{
				GameObject val2 = (GameObject)((item is GameObject) ? item : null);
				if (Object.op_Implicit((Object)(object)val2))
				{
					yield return val2;
				}
			}
		}

		private static void ApplyWhiteVisual(GameObject visual, HashSet<Renderer> current)
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Expected O, but got Unknown
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Expected O, but got Unknown
			//IL_00a0: 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_00c0: 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)
			if (!Object.op_Implicit((Object)(object)visual))
			{
				return;
			}
			Renderer[] componentsInChildren = visual.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren)
			{
				if (!((Object)(object)((Component)val).GetComponentInParent<RootboundPermafrostCrystalMarker>() != (Object)null))
				{
					current.Add(val);
					if (!Previous.ContainsKey(val))
					{
						MaterialPropertyBlock val2 = new MaterialPropertyBlock();
						val.GetPropertyBlock(val2);
						Previous[val] = val2;
					}
					if (!PreviousMaterials.ContainsKey(val))
					{
						Material[] sharedMaterials = val.sharedMaterials;
						PreviousMaterials[val] = sharedMaterials;
						val.sharedMaterials = BuildWhiteMaterials(sharedMaterials);
					}
					MaterialPropertyBlock val3 = new MaterialPropertyBlock();
					val.GetPropertyBlock(val3);
					val3.SetColor("_Color", Permafrost);
					val3.SetColor("_BaseColor", Permafrost);
					val3.SetColor("_TintColor", Permafrost);
					val3.SetColor("_EmissionColor", Color.black);
					val.SetPropertyBlock(val3);
				}
			}
		}

		private static void Restore(Renderer renderer)
		{
			if (Object.op_Implicit((Object)(object)renderer) && Previous.TryGetValue(renderer, out var value))
			{
				renderer.SetPropertyBlock(value);
			}
			Previous.Remove(renderer);
			if (Object.op_Implicit((Object)(object)renderer) && PreviousMaterials.TryGetValue(renderer, out var value2))
			{
				renderer.sharedMaterials = value2;
			}
			PreviousMaterials.Remove(renderer);
		}

		private static void UpdateCrystalAccents(Player player, List<GameObject> hosts)
		{
			//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_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			bool flag = hosts.Count == CrystalHosts.Count;
			if (flag)
			{
				for (int i = 0; i < hosts.Count; i++)
				{
					if ((Object)(object)hosts[i] != (Object)(object)CrystalHosts[i])
					{
						flag = false;
						break;
					}
				}
			}
			if (flag && CrystalAccents.All((GameObject accent) => Object.op_Implicit((Object)(object)accent)))
			{
				return;
			}
			ClearCrystalAccents();
			CrystalHosts.AddRange(hosts);
			for (int num = 0; num < hosts.Count; num++)
			{
				GameObject val = hosts[num];
				Renderer val2 = (Object.op_Implicit((Object)(object)val) ? val.GetComponentsInChildren<Renderer>(true).OrderByDescending(delegate(Renderer candidate)
				{
					//IL_0001: Unknown result type (might be due to invalid IL or missing references)
					//IL_0006: Unknown result type (might be due to invalid IL or missing references)
					//IL_0009: Unknown result type (might be due to invalid IL or missing references)
					//IL_000e: Unknown result type (might be due to invalid IL or missing references)
					Bounds bounds2 = candidate.bounds;
					Vector3 size = ((Bounds)(ref bounds2)).size;
					return ((Vector3)(ref size)).sqrMagnitude;
				}).FirstOrDefault() : null);
				if (!((Object)(object)val2 == (Object)null))
				{
					float scale = num switch
					{
						1 => 0.18f, 
						0 => 0.15f, 
						_ => 0.13f, 
					};
					Bounds bounds = val2.bounds;
					Vector3 val3 = ((Bounds)(ref bounds)).center - ((Component)player).transform.position;
					val3.y = 0f;
					if (((Vector3)(ref val3)).sqrMagnitude < 0.01f)
					{
						val3 = ((Component)player).transform.right * ((num % 2 == 0) ? 1f : (-1f));
					}
					bounds = val2.bounds;
					Vector3 worldPosition = ((Bounds)(ref bounds)).center + ((Vector3)(ref val3)).normalized * ((num == 0) ? 0.1f : 0.07f);
					GameObject val4 = BuildCrystalCluster(((Component)player).transform, worldPosition, scale, (float)num * 37f);
					if (Object.op_Implicit((Object)(object)val4))
					{
						CrystalAccents.Add(val4);
					}
				}
			}
		}

		private static GameObject BuildCrystalCluster(Transform parent, Vector3 worldPosition, float scale, float yaw)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//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_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: 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_0055: 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)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: 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_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Expected O, but got Unknown
			Material crystalMaterial = GetCrystalMaterial();
			if (!Object.op_Implicit((Object)(object)crystalMaterial))
			{
				return null;
			}
			GameObject val = new GameObject("Rootbound_PermafrostCrystalAccent");
			val.AddComponent<RootboundPermafrostCrystalMarker>();
			val.transform.SetParent(parent, true);
			val.transform.position = worldPosition;
			val.transform.rotation = Quaternion.Euler(0f, yaw, 0f);
			AddCrystal(val.transform, new Vector3(0f, 0f, 0f), Quaternion.Euler(8f, 0f, -8f), scale, crystalMaterial);
			AddCrystal(val.transform, new Vector3(scale * 0.72f, (0f - scale) * 0.16f, scale * 0.12f), Quaternion.Euler(-12f, 28f, 18f), scale * 0.68f, crystalMaterial);
			AddCrystal(val.transform, new Vector3((0f - scale) * 0.58f, (0f - scale) * 0.2f, (0f - scale) * 0.08f), Quaternion.Euler(15f, -30f, -22f), scale * 0.56f, crystalMaterial);
			return val;
		}

		private static void AddCrystal(Transform parent, Vector3 position, Quaternion rotation, float scale, Material material)
		{
			//IL_0005: 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_0017: 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_0023: 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)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("IceStaffTipCrystal");
			val.transform.SetParent(parent, false);
			val.transform.localPosition = position;
			val.transform.localRotation = rotation;
			val.transform.localScale = new Vector3(scale, scale * 2.4f, scale);
			MeshFilter val2 = val.AddComponent<MeshFilter>();
			MeshRenderer obj = val.AddComponent<MeshRenderer>();
			val2.sharedMesh = BuildCrystalMesh();
			((Renderer)obj).sharedMaterial = material;
		}

		private static Mesh BuildCrystalMesh()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Expected O, but got Unknown
			Vector3[] vertices = (Vector3[])(object)new Vector3[6]
			{
				new Vector3(0f, 0.65f, 0f),
				new Vector3(0.42f, 0f, 0f),
				new Vector3(0f, 0f, 0.42f),
				new Vector3(-0.42f, 0f, 0f),
				new Vector3(0f, 0f, -0.42f),
				new Vector3(0f, -0.35f, 0f)
			};
			int[] triangles = new int[24]
			{
				0, 1, 2, 0, 2, 3, 0, 3, 4, 0,
				4, 1, 5, 2, 1, 5, 3, 2, 5, 4,
				3, 5, 1, 4
			};
			Mesh val = new Mesh
			{
				name = "Rootbound_IceStaffTipCrystalMesh",
				vertices = vertices,
				triangles = triangles
			};
			val.RecalculateNormals();
			val.RecalculateBounds();
			return val;
		}

		private static Material GetCrystalMaterial()
		{
			//IL_00d7: 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)
			//IL_00ec: Expected O, but got Unknown
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)_crystalMaterial))
			{
				return _crystalMaterial;
			}
			GameObject val = RootboundContent.FindPrefab("StaffIce") ?? RootboundContent.FindPrefab("StaffIceShards") ?? RootboundContent.FindPrefab("StaffFrostOrbs");
			Material val2 = (Object.op_Implicit((Object)(object)val) ? (from material in val.GetComponentsInChildren<Renderer>(true).SelectMany((Renderer renderer) => renderer.sharedMaterials)
				where Object.op_Implicit((Object)(object)material)
				select material).OrderByDescending(delegate(Material material)
			{
				string text = ((Object)material).name.ToLowerInvariant();
				return (text.Contains("ice") || text.Contains("frost") || text.Contains("crystal")) ? 1 : 0;
			}).FirstOrDefault() : null);
			if (!Object.op_Implicit((Object)(object)val2))
			{
				RootboundWitchPlugin.Log.LogWarning((object)"No live vanilla ice-staff material was available for tier-four crystal accents.");
				return null;
			}
			_crystalMaterial = new Material(val2)
			{
				name = "Rootbound_VanillaIceStaffAccent"
			};
			Color val3 = default(Color);
			((Color)(ref val3))..ctor(0.58f, 0.82f, 1f, 0.92f);
			if (_crystalMaterial.HasProperty("_Color"))
			{
				_crystalMaterial.SetColor("_Color", val3);
			}
			if (_crystalMaterial.HasProperty("_BaseColor"))
			{
				_crystalMaterial.SetColor("_BaseColor", val3);
			}
			if (_crystalMaterial.HasProperty("_EmissionColor"))
			{
				_crystalMaterial.SetColor("_EmissionColor", val3 * 0.65f);
			}
			return _crystalMaterial;
		}

		private static void ClearCrystalAccents()
		{
			foreach (GameObject crystalAccent in CrystalAccents)
			{
				if (Object.op_Implicit((Object)(object)crystalAccent))
				{
					Object.Destroy((Object)(object)crystalAccent);
				}
			}
			CrystalAccents.Clear();
			CrystalHosts.Clear();
		}

		private static Material[] BuildWhiteMaterials(Material[] source)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Expected O, but got Unknown
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			Material[] array = (Material[])(object)new Material[source.Length];
			for (int i = 0; i < source.Length; i++)
			{
				Material val = source[i];
				if (Object.op_Implicit((Object)(object)val))
				{
					Material val2 = new Material(val)
					{
						name = ((Object)val).name + "_RootboundPermafrostWhite"
					};
					FrostTextureProperty(val2, "_MainTex");
					FrostTextureProperty(val2, "_BaseMap");
					SetMaterialColour(val2, "_Color", Permafrost);
					SetMaterialColour(val2, "_BaseColor", Permafrost);
					SetMaterialColour(val2, "_TintColor", Permafrost);
					SetMaterialColour(val2, "_EmissionColor", Color.black);
					val2.DisableKeyword("_EMISSION");
					val2.globalIlluminationFlags = (MaterialGlobalIlluminationFlags)4;
					array[i] = val2;
				}
			}
			return array;
		}

		private static void FrostTextureProperty(Material material, string property)
		{
			if (material.HasProperty(property))
			{
				Texture2D val = BuildFrostedTexture(material.GetTexture(property), ((Object)material).name + property + "White");
				if (Object.op_Implicit((Object)(object)val))
				{
					material.SetTexture(property, (Texture)(object)val);
				}
			}
		}

		private static void SetMaterialColour(Material material, string property, Color colour)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			if (material.HasProperty(property))
			{
				material.SetColor(property, colour);
			}
		}

		private static void ApplyBodyTextures(VisEquipment equipment)
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected O, but got Unknown
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			SkinnedMeshRenderer val = BodyModel.Invoke(equipment);
			if (!Object.op_Implicit((Object)(object)val))
			{
				RestoreBodyTextures();
				return;
			}
			Material material = ((Renderer)val).material;
			if ((Object)(object)_bodyRenderer != (Object)(object)val || (Object)(object)_bodyMaterial != (Object)(object)material)
			{
				RestoreBodyTextures();
				_bodyRenderer = val;
				_bodyMaterial = material;
				_originalBodyBlock = new MaterialPropertyBlock();
				((Renderer)val).GetPropertyBlock(_originalBodyBlock);
				_bodyBlockCaptured = true;
				_originalChest = material.GetTexture(ChestTexture);
				_originalLegs = material.GetTexture(LegsTexture);
				if (material.HasProperty(SkinColor))
				{
					_originalSkinColor = material.GetColor(SkinColor);
					_skinColorCaptured = true;
				}
				_frostedChest = (Texture)(object)BuildFrostedTexture(_originalChest, "Rootbound_PermafrostChest");
				_frostedLegs = (Texture)(object)BuildFrostedTexture(_originalLegs, "Rootbound_PermafrostLegs");
			}
			RefreshSlot(material, ChestTexture, ref _originalChest, ref _frostedChest, "Rootbound_PermafrostChest");
			RefreshSlot(material, LegsTexture, ref _originalLegs, ref _frostedLegs, "Rootbound_PermafrostLegs");
			ApplyDvergerSkin(Player.m_localPlayer, val);
		}

		private static void ApplyDvergerSkin(Player player, SkinnedMeshRenderer body)
		{
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Expected O, but got Unknown
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)body))
			{
				return;
			}
			foreach (Renderer item in (IEnumerable<Renderer>)(((Object)(object)player != (Object)null) ? ((Array)((Component)player).GetComponentsInChildren<Renderer>(true)) : ((Array)new Renderer[1] { (Renderer)body })))
			{
				Material[] materials = item.materials;
				foreach (Material val in materials)
				{
					if (Object.op_Implicit((Object)(object)val) && val.HasProperty(SkinColor))
					{
						if (!PreviousSkinColours.ContainsKey(val))
						{
							PreviousSkinColours[val] = val.GetColor(SkinColor);
						}
						val.SetColor(SkinColor, DvergerBlue);
					}
				}
			}
			MaterialPropertyBlock val2 = new MaterialPropertyBlock();
			((Renderer)body).GetPropertyBlock(val2);
			val2.SetColor(SkinColor, DvergerBlue);
			((Renderer)body).SetPropertyBlock(val2);
		}

		private static void RefreshSlot(Material material, int property, ref Texture original, ref Texture frosted, string name)
		{
			Texture texture = material.GetTexture(property);
			if (Object.op_Implicit((Object)(object)texture) && (Object)(object)texture != (Object)(object)frosted && (Object)(object)texture != (Object)(object)original)
			{
				original = texture;
				frosted = (Texture)(object)BuildFrostedTexture(texture, name);
			}
			if (Object.op_Implicit((Object)(object)frosted))
			{
				material.SetTexture(property, frosted);
			}
		}

		private static Texture2D BuildFrostedTexture(Texture source, string name)
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: 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_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Expected O, but got Unknown
			//IL_009f: 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_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)source))
			{
				return null;
			}
			if (FrostedTextures.TryGetValue(source, out var value) && Object.op_Implicit((Object)(object)value))
			{
				return value;
			}
			RenderTexture active = RenderTexture.active;
			RenderTexture temporary = RenderTexture.GetTemporary(source.width, source.height, 0, (RenderTextureFormat)0, (RenderTextureReadWrite)1);
			try
			{
				Graphics.Blit(source, temporary);
				RenderTexture.active = temporary;
				Texture2D val = new Texture2D(source.width, source.height, (TextureFormat)4, false)
				{
					name = name,
					filterMode = source.filterMode,
					wrapMode = source.wrapMode,
					hideFlags = (HideFlags)61
				};
				val.ReadPixels(new Rect(0f, 0f, (float)source.width, (float)source.height), 0, 0, false);
				Color[] pixels = val.GetPixels();
				for (int i = 0; i < pixels.Length; i++)
				{
					Color val2 = pixels[i];
					float num = Mathf.Clamp01(val2.r * 0.2126f + val2.g * 0.7152f + val2.b * 0.0722f);
					float num2 = Mathf.Lerp(0.4f, 1f, Mathf.Pow(num, 0.76f));
					pixels[i] = new Color(num2 * 0.78f, num2 * 0.9f, num2, val2.a);
				}
				val.SetPixels(pixels);
				val.Apply(false, true);
				FrostedTextures[source] = val;
				return val;
			}
			catch (Exception ex)
			{
				RootboundWitchPlugin.Log.LogWarning((object)("Could not build the quality-four permafrost texture: " + ex.Message));
				return null;
			}
			finally
			{
				RenderTexture.active = active;
				RenderTexture.ReleaseTemporary(temporary);
			}
		}

		private static void RestoreBodyTextures()
		{
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)_bodyMaterial))
			{
				if (Object.op_Implicit((Object)(object)_frostedChest) && (Object)(object)_bodyMaterial.GetTexture(ChestTexture) == (Object)(object)_frostedChest)
				{
					_bodyMaterial.SetTexture(ChestTexture, _originalChest);
				}
				if (Object.op_Implicit((Object)(object)_frostedLegs) && (Object)(object)_bodyMaterial.GetTexture(LegsTexture) == (Object)(object)_frostedLegs)
				{
					_bodyMaterial.SetTexture(LegsTexture, _originalLegs);
				}
				if (_skinColorCaptured && _bodyMaterial.HasProperty(SkinColor))
				{
					_bodyMaterial.SetColor(SkinColor, _originalSkinColor);
				}
			}
			if (Object.op_Implicit((Object)(object)_bodyRenderer) && _bodyBlockCaptured && _originalBodyBlock != null)
			{
				((Renderer)_bodyRenderer).SetPropertyBlock(_originalBodyBlock);
			}
			KeyValuePair<Material, Color>[] array = PreviousSkinColours.ToArray();
			for (int i = 0; i < array.Length; i++)
			{
				KeyValuePair<Material, Color> keyValuePair = array[i];
				if (Object.op_Implicit((Object)(object)keyValuePair.Key) && keyValuePair.Key.HasProperty(SkinColor))
				{
					keyValuePair.Key.SetColor(SkinColor, keyValuePair.Value);
				}
			}
			PreviousSkinColours.Clear();
			_bodyMaterial = null;
			_bodyRenderer = null;
			_originalBodyBlock = null;
			_bodyBlockCaptured = false;
			_originalChest = null;
			_originalLegs = null;
			_frostedChest = null;
			_frostedLegs = null;
			_skinColorCaptured = false;
		}
	}
	internal sealed class RootboundPermafrostCrystalMarker : MonoBehaviour
	{
	}
	[HarmonyPatch(typeof(VisEquipment), "UpdateColors")]
	internal static class RootboundPermafrostSkinRefreshPatch
	{
		private static void Postfix(VisEquipment __instance)
		{
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer != (Object)null && RootboundWitchPlugin.EnablePermafrostTint.Value && RootboundState.IsPermafrost(localPlayer))
			{
				PermafrostVisuals.ReapplyDvergerSkin(__instance);
			}
		}
	}
	internal static class PetrifiedToolVisuals
	{
		private enum Treatment
		{
			WalnutAntler,
			CorewoodBlade
		}

		private static readonly Color Walnut = new Color(0.22f, 0.105f, 0.04f, 1f);

		private static readonly Color Corewood = new Color(0.3f, 0.155f, 0.06f, 1f);

		internal static void ApplyPick(GameObject prefab)
		{
			Apply(prefab, Treatment.WalnutAntler);
		}

		internal static void ApplyAxe(GameObject prefab)
		{
			Apply(prefab, Treatment.CorewoodBlade);
		}

		private static void Apply(GameObject prefab, Treatment treatment)
		{
			if (!Object.op_Implicit((Object)(object)prefab))
			{
				return;
			}
			Dictionary<Material, Material> dictionary = new Dictionary<Material, Material>();
			Dictionary<Texture, Texture2D> textureCopies = new Dictionary<Texture, Texture2D>();
			Renderer[] componentsInChildren = prefab.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren)
			{
				Material[] sharedMaterials = val.sharedMaterials;
				bool flag = false;
				for (int j = 0; j < sharedMaterials.Length; j++)
				{
					Material val2 = sharedMaterials[j];
					if (Object.op_Implicit((Object)(object)val2))
					{
						if (!dictionary.TryGetValue(val2, out var value))
						{
							value = (dictionary[val2] = BuildMaterial(val2, treatment, textureCopies));
						}
						sharedMaterials[j] = value;
						flag = true;
					}
				}
				if (flag)
				{
					val.sharedMaterials = sharedMaterials;
				}
			}
			RootboundWitchPlugin.Log.LogInfo((object)(((Object)prefab).name + " received the " + ((treatment == Treatment.WalnutAntler) ? "walnut-antler" : "corewood-grain") + " non-metal visual treatment."));
		}

		private static Material BuildMaterial(Material source, Treatment treatment, Dictionary<Texture, Texture2D> textureCopies)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			Material val = new Material(source)
			{
				name = ((Object)source).name + ((treatment == Treatment.WalnutAntler) ? "_PetrifiedWalnut" : "_PetrifiedCorewood")
			};
			RecolourTextureProperty(val, "_MainTex", treatment, textureCopies);
			RecolourTextureProperty(val, "_BaseMap", treatment, textureCopies);
			if (val.HasProperty("_Metallic"))
			{
				val.SetFloat("_Metallic", 0f);
			}
			if (val.HasProperty("_Glossiness"))
			{
				val.SetFloat("_Glossiness", 0.22f);
			}
			if (val.HasProperty("_Smoothness"))
			{
				val.SetFloat("_Smoothness", 0.22f);
			}
			if (val.HasProperty("_EmissionColor"))
			{
				val.SetColor("_EmissionColor", Color.black);
			}
			val.DisableKeyword("_EMISSION");
			val.globalIlluminationFlags = (MaterialGlobalIlluminationFlags)4;
			return val;
		}

		private static void RecolourTextureProperty(Material material, string property, Treatment treatment, Dictionary<Texture, Texture2D> textureCopies)
		{
			if (!material.HasProperty(property))
			{
				return;
			}
			Texture texture = material.GetTexture(property);
			if (Object.op_Implicit((Object)(object)texture))
			{
				if (!textureCopies.TryGetValue(texture, out var value))
				{
					value = (textureCopies[texture] = BuildTexture(texture, treatment));
				}
				if (Object.op_Implicit((Object)(object)value))
				{
					material.SetTexture(property, (Texture)(object)value);
				}
			}
		}

		private static Texture2D BuildTexture(Texture source, Treatment treatment)
		{
			//IL_0036: 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_005b: 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_0067: 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_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Expected O, but got Unknown
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: 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_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0292: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b2: Unknown result type (might be due to invalid IL or missing references)
			RenderTexture active = RenderTexture.active;
			RenderTexture temporary = RenderTexture.GetTemporary(source.width, source.height, 0, (RenderTextureFormat)0, (RenderTextureReadWrite)1);
			try
			{
				Graphics.Blit(source, temporary);
				RenderTexture.active = temporary;
				Texture2D val = new Texture2D(source.width, source.height, (TextureFormat)4, false)
				{
					name = ((Object)source).name + ((treatment == Treatment.WalnutAntler) ? "_PetrifiedWalnutTexture" : "_PetrifiedCorewoodTexture"),
					filterMode = source.filterMode,
					wrapMode = source.wrapMode,
					hideFlags = (HideFlags)61
				};
				val.ReadPixels(new Rect(0f, 0f, (float)source.width, (float)source.height), 0, 0, false);
				Color[] pixels = val.GetPixels();
				int num = Mathf.Max(1, ((Texture)val).width);
				Color val3 = default(Color);
				for (int i = 0; i < pixels.Length; i++)
				{
					Color val2 = pixels[i];
					if (!(val2.a <= 0.001f))
					{
						float num2 = Mathf.Max(val2.r, Mathf.Max(val2.g, val2.b));
						float num3 = Mathf.Min(val2.r, Mathf.Min(val2.g, val2.b));
						float num4 = ((num2 <= 0.001f) ? 0f : ((num2 - num3) / num2));
						float num5 = val2.r * 0.2126f + val2.g * 0.7152f + val2.b * 0.0722f;
						float num6;
						if (treatment == Treatment.WalnutAntler)
						{
							num6 = Mathf.Clamp01((num5 - 0.24f) / 0.48f) * Mathf.Clamp01((0.6f - num4) / 0.45f);
							float num7 = Mathf.Lerp(0.58f, 1.32f, num5);
							((Color)(ref val3))..ctor(Walnut.r * num7, Walnut.g * num7, Walnut.b * num7, val2.a);
						}
						else
						{
							float num8 = Mathf.Clamp01((val2.r - val2.b - 0.025f) * 5.5f);
							float num9 = Mathf.Clamp01((num5 - 0.18f) / 0.52f);
							num6 = num8 * num9;
							int num10 = i % num;
							int num11 = i / num;
							float num12 = 0.88f + 0.12f * Mathf.Sin((float)num11 * 0.31f + Mathf.Sin((float)num10 * 0.13f) * 2.4f);
							float num13 = Mathf.Lerp(0.62f, 1.28f, num5) * num12;
							((Color)(ref val3))..ctor(Corewood.r * num13, Corewood.g * num13, Corewood.b * num13, val2.a);
						}
						pixels[i] = Color.Lerp(val2, val3, num6 * 0.97f);
					}
				}
				val.SetPixels(pixels);
				val.Apply(false, true);
				return val;
			}
			catch (Exception ex)
			{
				RootboundWitchPlugin.Log.LogWarning((object)("Could not build the petrified tool texture from " + ((Object)source).name + ": " + ex.Message));
				return null;
			}
			finally
			{
				RenderTexture.active = active;
				RenderTexture.ReleaseTemporary(temporary);
			}
		}
	}
	internal static class ReclaimedStaffVisual
	{
		internal sealed class SourceVisualSnapshot
		{
			private sealed class TransformState
			{
				private readonly Transform _target;

				private readonly string _name;

				private readonly bool _active;

				internal TransformState(Transform target)
				{
					_target = target;
					_name = ((Object)target).name;
					_active = ((Component)target).gameObject.activeSelf;
				}

				internal bool Restore()
				{
					if (!Object.op_Implicit((Object)(object)_target))
					{
						return false;
					}
					bool result = ((Object)_target).name != _name || ((Component)_target).gameObject.activeSelf != _active;
					((Object)_target).name = _name;
					((Component)_target).gameObject.SetActive(_active);
					return result;
				}
			}

			private sealed class RendererState
			{
				private readonly Renderer _target;

				private readonly bool _enabled;

				private readonly Material[] _materials;

				internal RendererState(Renderer target)
				{
					_target = target;
					_enabled = target.enabled;
					_materials = target.sharedMaterials;
				}

				internal bool Restore()
				{
					if (!Object.op_Implicit((Object)(object)_target))
					{
						return false;
					}
					bool result = _target.enabled != _enabled || !_target.sharedMaterials.SequenceEqual(_materials);
					_target.enabled = _enabled;
					_target.sharedMaterials = _materials;
					return result;
				}
			}

			private sealed class LightState
			{
				private readonly Light _target;

				private readonly bool _enabled;

				private readonly Color _colour;

				private readonly float _intensity;

				private readonly float _range;

				private readonly LightShadows _shadows;

				internal LightState(Light target)
				{
					//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_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)
					_target = target;
					_enabled = ((Behaviour)target).enabled;
					_colour = target.color;
					_intensity = target.intensity;
					_range = target.range;
					_shadows = target.shadows;
				}

				internal bool