Decompiled source of SwampCapes v1.0.0

BepInEx/plugins/SwampCapes/SwampCapes.dll

Decompiled 3 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Microsoft.CodeAnalysis;
using UnityEngine;

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace SwampCapes
{
	internal static class Appearance
	{
		internal static void Cape(GameObject prefab, bool guck)
		{
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Expected O, but got Unknown
			//IL_00f0: 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_021d: Unknown result type (might be due to invalid IL or missing references)
			//IL_024a: 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_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_0285: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: 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)
			Renderer[] componentsInChildren = prefab.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren)
			{
				Renderer obj = ((val is SkinnedMeshRenderer) ? val : null);
				object obj2 = ((obj != null) ? ((SkinnedMeshRenderer)obj).sharedMesh : null);
				if (obj2 == null)
				{
					MeshFilter component = ((Component)val).GetComponent<MeshFilter>();
					obj2 = ((component != null) ? component.sharedMesh : null);
				}
				Mesh mesh = (Mesh)obj2;
				Material[] sharedMaterials = val.sharedMaterials;
				for (int j = 0; j < sharedMaterials.Length; j++)
				{
					if (!Object.op_Implicit((Object)(object)sharedMaterials[j]))
					{
						continue;
					}
					Material val2 = Object.Instantiate<Material>(sharedMaterials[j]);
					if (val2.HasProperty("_MainTex") && Object.op_Implicit((Object)(object)val2.GetTexture("_MainTex")))
					{
						Texture2D val3 = ReadTexture(val2.GetTexture("_MainTex"));
						Color[] pixels = val3.GetPixels();
						float[] array = Heights(mesh, j, ((Texture)val3).width, ((Texture)val3).height);
						Texture2D val4 = new Texture2D(((Texture)val3).width, ((Texture)val3).height, (TextureFormat)4, false);
						Color[] array2 = (Color[])(object)new Color[pixels.Length];
						for (int k = 0; k < pixels.Length; k++)
						{
							Color val5 = pixels[k];
							float num = ((array != null && array[k] >= 0f) ? array[k] : ((float)(k / ((Texture)val3).width) / (float)(((Texture)val3).height - 1)));
							float num2 = 1f - Mathf.SmoothStep(0f, 0.48f, num);
							pixels[k] = Recolor(val5, guck, num2);
							array2[k] = (guck ? (new Color(0.32f, 0.56f, 0.035f, 1f) * (num2 * val5.a * (0.5f + ((Color)(ref val5)).grayscale * 0.5f))) : (new Color(0.4f, 0.025f, 0.018f, 1f) * ((1f - Mathf.SmoothStep(0.12f, 0.52f, ((Color)(ref val5)).grayscale)) * val5.a)));
						}
						val3.SetPixels(pixels);
						val3.Apply();
						val4.SetPixels(array2);
						val4.Apply();
						((Texture)val3).wrapMode = val2.GetTexture("_MainTex").wrapMode;
						val2.SetTexture("_MainTex", (Texture)(object)val3);
						if (val2.HasProperty("_Color"))
						{
							val2.SetColor("_Color", Color.white);
						}
						if (val2.HasProperty("_EmissionMap"))
						{
							val2.SetTexture("_EmissionMap", (Texture)(object)val4);
						}
						if (val2.HasProperty("_EmissionColor"))
						{
							val2.SetColor("_EmissionColor", Color.white * (guck ? Plugin.GuckGlowStrength.Value : Plugin.LeechGlowStrength.Value));
						}
						val2.EnableKeyword("_EMISSION");
						sharedMaterials[j] = val2;
					}
				}
				val.sharedMaterials = sharedMaterials;
			}
		}

		private static Color Recolor(Color original, bool guck, float hem)
		{
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: 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_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: 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_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: 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)
			float num = Mathf.Clamp01(((Color)(ref original)).grayscale);
			Color val;
			if (guck)
			{
				val = Color.Lerp(new Color(0.045f, 0.048f, 0.043f), new Color(0.3f, 0.48f, 0.04f), hem);
			}
			else
			{
				float num2 = 1f - Mathf.SmoothStep(0.12f, 0.52f, num);
				val = Color.Lerp(new Color(0.19f, 0.23f, 0.15f), new Color(0.6f, 0.075f, 0.06f), num2);
			}
			Color result = val * (0.3f + num * 1.1f);
			result.a = original.a;
			return result;
		}

		private static Texture2D ReadTexture(Texture source)
		{
			//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_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Expected O, but got Unknown
			RenderTexture temporary = RenderTexture.GetTemporary(source.width, source.height, 0, (RenderTextureFormat)0, (RenderTextureReadWrite)2);
			RenderTexture active = RenderTexture.active;
			try
			{
				Graphics.Blit(source, temporary);
				RenderTexture.active = temporary;
				Texture2D val = new Texture2D(source.width, source.height, (TextureFormat)4, false);
				val.ReadPixels(new Rect(0f, 0f, (float)source.width, (float)source.height), 0, 0);
				val.Apply();
				return val;
			}
			finally
			{
				RenderTexture.active = active;
				RenderTexture.ReleaseTemporary(temporary);
			}
		}

		private static float[] Heights(Mesh mesh, int slot, int width, int height)
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: 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_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: 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_00fc: 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_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: 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_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			//IL_0221: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			//IL_0232: Unknown result type (might be due to invalid IL or missing references)
			//IL_023b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0242: Unknown result type (might be due to invalid IL or missing references)
			//IL_024c: Unknown result type (might be due to invalid IL or missing references)
			//IL_028d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0299: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)mesh) || !mesh.isReadable || slot >= mesh.subMeshCount)
			{
				return null;
			}
			Vector2[] uv = mesh.uv;
			Vector3[] vertices = mesh.vertices;
			if (uv.Length != vertices.Length)
			{
				return null;
			}
			float[] array = new float[width * height];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = -1f;
			}
			int[] triangles = mesh.GetTriangles(slot);
			Bounds bounds = mesh.bounds;
			for (int j = 0; j + 2 < triangles.Length; j += 3)
			{
				int num = triangles[j];
				int num2 = triangles[j + 1];
				int num3 = triangles[j + 2];
				Vector2 val = uv[num];
				Vector2 val2 = uv[num2];
				Vector2 val3 = uv[num3];
				float num4 = (val2.y - val3.y) * (val.x - val3.x) + (val3.x - val2.x) * (val.y - val3.y);
				if (Mathf.Abs(num4) < 1E-06f)
				{
					continue;
				}
				int num5 = Mathf.Clamp(Mathf.FloorToInt(Mathf.Min(val.x, Mathf.Min(val2.x, val3.x)) * (float)width), 0, width - 1);
				int num6 = Mathf.Clamp(Mathf.CeilToInt(Mathf.Max(val.x, Mathf.Max(val2.x, val3.x)) * (float)width), 0, width - 1);
				int num7 = Mathf.Clamp(Mathf.FloorToInt(Mathf.Min(val.y, Mathf.Min(val2.y, val3.y)) * (float)height), 0, height - 1);
				int num8 = Mathf.Clamp(Mathf.CeilToInt(Mathf.Max(val.y, Mathf.Max(val2.y, val3.y)) * (float)height), 0, height - 1);
				for (int k = num7; k <= num8; k++)
				{
					for (int l = num5; l <= num6; l++)
					{
						float num9 = ((float)l + 0.5f) / (float)width;
						float num10 = ((float)k + 0.5f) / (float)height;
						float num11 = ((val2.y - val3.y) * (num9 - val3.x) + (val3.x - val2.x) * (num10 - val3.y)) / num4;
						float num12 = ((val3.y - val.y) * (num9 - val3.x) + (val.x - val3.x) * (num10 - val3.y)) / num4;
						float num13 = 1f - num11 - num12;
						if (!(num11 < -0.001f) && !(num12 < -0.001f) && !(num13 < -0.001f))
						{
							array[k * width + l] = Mathf.InverseLerp(((Bounds)(ref bounds)).min.z, ((Bounds)(ref bounds)).max.z, vertices[num].z * num11 + vertices[num2].z * num12 + vertices[num3].z * num13);
						}
					}
				}
			}
			return array;
		}

		internal static Sprite RubberIcon()
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Expected O, but got Unknown
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			using Stream stream = typeof(Appearance).Assembly.GetManifestResourceStream("SwampCapes.RubberIcon.png");
			if (stream == null)
			{
				throw new InvalidOperationException("Rubber icon asset is missing.");
			}
			using MemoryStream memoryStream = new MemoryStream();
			stream.CopyTo(memoryStream);
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
			if (!ImageConversion.LoadImage(val, memoryStream.ToArray()))
			{
				throw new InvalidOperationException("Cannot decode Rubber icon.");
			}
			return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f));
		}

		internal static Sprite CapeIcon(Sprite source, bool guck)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			//IL_005d: 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_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = ReadTexture((Texture)(object)source.texture);
			Rect textureRect = source.textureRect;
			Texture2D val2 = new Texture2D((int)((Rect)(ref textureRect)).width, (int)((Rect)(ref textureRect)).height, (TextureFormat)4, false);
			Color[] pixels = val.GetPixels((int)((Rect)(ref textureRect)).x, (int)((Rect)(ref textureRect)).y, (int)((Rect)(ref textureRect)).width, (int)((Rect)(ref textureRect)).height);
			for (int i = 0; i < pixels.Length; i++)
			{
				pixels[i] = Recolor(pixels[i], guck, 1f - Mathf.SmoothStep(0f, 0.4f, (float)(i / ((Texture)val2).width) / (float)((Texture)val2).height));
			}
			val2.SetPixels(pixels);
			val2.Apply();
			Object.Destroy((Object)(object)val);
			return Sprite.Create(val2, new Rect(0f, 0f, (float)((Texture)val2).width, (float)((Texture)val2).height), new Vector2(0.5f, 0.5f));
		}

		internal static void RubberRoll(GameObject prefab)
		{
			//IL_00bb: 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_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Expected O, but got Unknown
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Expected O, but got Unknown
			//IL_0206: Unknown result type (might be due to invalid IL or missing references)
			Renderer[] componentsInChildren = prefab.GetComponentsInChildren<Renderer>(true);
			Material val = null;
			Renderer[] array = componentsInChildren;
			for (int i = 0; i < array.Length; i++)
			{
				Material[] sharedMaterials = array[i].sharedMaterials;
				foreach (Material val2 in sharedMaterials)
				{
					if (Object.op_Implicit((Object)(object)val2) && Object.op_Implicit((Object)(object)val2.shader))
					{
						val = val2;
						break;
					}
				}
			}
			if (!Object.op_Implicit((Object)(object)val))
			{
				throw new InvalidOperationException("No loaded material on Rubber's source prefab.");
			}
			Material val3 = Object.Instantiate<Material>(val);
			if (val3.HasProperty("_MainTex"))
			{
				val3.SetTexture("_MainTex", (Texture)(object)Texture2D.whiteTexture);
			}
			if (val3.HasProperty("_Color"))
			{
				val3.SetColor("_Color", new Color(0.045f, 0.045f, 0.05f));
			}
			if (val3.HasProperty("_EmissionColor"))
			{
				val3.SetColor("_EmissionColor", Color.black);
			}
			if (val3.HasProperty("_EmissionMap"))
			{
				val3.SetTexture("_EmissionMap", (Texture)(object)Texture2D.blackTexture);
			}
			if (val3.HasProperty("_BumpMap"))
			{
				val3.SetTexture("_BumpMap", (Texture)null);
			}
			if (val3.HasProperty("_Glossiness"))
			{
				val3.SetFloat("_Glossiness", 0.3f);
			}
			val3.DisableKeyword("_EMISSION");
			Transform val4 = prefab.transform.Find("attach") ?? prefab.transform;
			GameObject val5 = new GameObject("RubberRoll");
			val5.transform.SetParent(val4, false);
			val5.transform.localRotation = Quaternion.Euler(0f, 0f, 75f);
			Mesh val6 = new Mesh();
			List<Vector3> list = new List<Vector3>();
			List<int> list2 = new List<int>();
			for (int k = 0; k < 4; k++)
			{
				for (int l = 0; l <= 48; l++)
				{
					float num = (float)l * MathF.PI * 2f / 48f;
					float num2 = ((k < 2) ? 0.055f : 0.043f);
					list.Add(new Vector3(Mathf.Cos(num) * num2, (k % 2 == 0) ? (-0.16f) : 0.16f, Mathf.Sin(num) * num2));
				}
			}
			for (int m = 0; m < 48; m++)
			{
				Quad(list2, m, m + 1, 49 + m + 1, 49 + m);
				int num3 = 98;
				Quad(list2, num3 + m, num3 + 48 + 1 + m, num3 + 48 + 1 + m + 1, num3 + m + 1);
				Quad(list2, m, num3 + m, num3 + m + 1, m + 1);
				Quad(list2, 49 + m, 49 + m + 1, num3 + 48 + 1 + m + 1, num3 + 48 + 1 + m);
			}
			val6.SetVertices(list);
			val6.SetTriangles(list2, 0);
			val6.RecalculateNormals();
			val6.RecalculateBounds();
			val5.AddComponent<MeshFilter>().sharedMesh = val6;
			((Renderer)val5.AddComponent<MeshRenderer>()).sharedMaterial = val3;
			AddRollDetails(val5.transform, val3);
			array = componentsInChildren;
			for (int i = 0; i < array.Length; i++)
			{
				array[i].enabled = false;
			}
		}

		private static void AddRollDetails(Transform parent, Material rubber)
		{
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0273: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			List<Vector3> list = new List<Vector3>();
			List<int> list2 = new List<int>();
			for (int i = 0; i < 2; i++)
			{
				int count = list.Count;
				for (int j = 0; j <= 240; j++)
				{
					float num = (float)j / 240f * MathF.PI * 8f;
					float num2 = 0.006f + 0.047f * (float)j / 240f;
					float num3 = ((i == 0) ? (-0.162f) : 0.162f);
					list.Add(new Vector3(Mathf.Cos(num) * (num2 - 0.0015f), num3, Mathf.Sin(num) * (num2 - 0.0015f)));
					list.Add(new Vector3(Mathf.Cos(num) * (num2 + 0.0015f), num3, Mathf.Sin(num) * (num2 + 0.0015f)));
					if (j > 0)
					{
						int num4 = count + (j - 1) * 2;
						int num5 = num4 + 1;
						int num6 = num4 + 3;
						int num7 = num4 + 2;
						Quad(list2, num4, num5, num6, num7);
						Quad(list2, num7, num6, num5, num4);
					}
				}
			}
			Material val = Object.Instantiate<Material>(rubber);
			if (val.HasProperty("_Color"))
			{
				val.SetColor("_Color", new Color(0.11f, 0.11f, 0.12f));
			}
			AddMesh(parent, "RolledEdges", list, list2, val);
			list = new List<Vector3>();
			list2 = new List<int>();
			for (int k = 0; k <= 48; k++)
			{
				for (int l = 0; l <= 8; l++)
				{
					float num8 = (float)k * MathF.PI * 2f / 48f;
					float num9 = (float)l * MathF.PI * 2f / 8f;
					float num10 = 0.057f + 0.0025f * Mathf.Cos(num9);
					list.Add(new Vector3(Mathf.Cos(num8) * num10, 0.0025f * Mathf.Sin(num9), Mathf.Sin(num8) * num10));
					if (k < 48 && l < 8)
					{
						int num11 = k * 9 + l;
						Quad(list2, num11, num11 + 1, num11 + 8 + 2, num11 + 8 + 1);
						Quad(list2, num11 + 8 + 1, num11 + 8 + 2, num11 + 1, num11);
					}
				}
			}
			Material val2 = Object.Instantiate<Material>(rubber);
			if (val2.HasProperty("_Color"))
			{
				val2.SetColor("_Color", new Color(0.23f, 0.23f, 0.24f));
			}
			AddMesh(parent, "BindingCord", list, list2, val2);
		}

		private static void AddMesh(Transform parent, string name, List<Vector3> vertices, List<int> triangles, Material material)
		{
			//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_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name);
			val.transform.SetParent(parent, false);
			Mesh val2 = new Mesh();
			val2.SetVertices(vertices);
			val2.SetTriangles(triangles, 0);
			val2.RecalculateNormals();
			val2.RecalculateBounds();
			val.AddComponent<MeshFilter>().sharedMesh = val2;
			((Renderer)val.AddComponent<MeshRenderer>()).sharedMaterial = material;
		}

		private static void Quad(List<int> t, int a, int b, int c, int d)
		{
			t.Add(a);
			t.Add(c);
			t.Add(b);
			t.Add(a);
			t.Add(d);
			t.Add(c);
		}
	}
	[BepInPlugin("joshu.swampcapes", "SwampCapes", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class Plugin : BaseUnityPlugin
	{
		[HarmonyPatch(typeof(ItemData), "GetTooltip", new Type[]
		{
			typeof(ItemData),
			typeof(int),
			typeof(bool),
			typeof(float),
			typeof(int),
			typeof(bool)
		})]
		private static class CapeTooltip
		{
			private static void Postfix(ItemData item, int qualityLevel, bool crafting, ref string __result)
			{
				if (!IsCape(item) || string.IsNullOrEmpty(__result))
				{
					return;
				}
				string stats;
				if (Is(item, "SC_CapeLeech"))
				{
					stats = TooltipText.LifestealLine(qualityLevel, (crafting && qualityLevel > item.m_quality) ? item.m_quality : 0, LifestealMultiplier.Value);
					__result = __result.Replace(TooltipText.LeechDescription(), TooltipText.LeechDescription(LifestealMultiplier.Value));
				}
				else
				{
					stats = "Wet Immunity\nPoison Resistance";
					string damageModifiersTooltipString = SE_Stats.GetDamageModifiersTooltipString(item.m_shared.m_damageModifiers);
					if (!string.IsNullOrEmpty(damageModifiersTooltipString))
					{
						__result = __result.Replace(damageModifiersTooltipString, "");
					}
				}
				__result = TooltipText.InsertAfterWeight(__result, stats, Localization.instance.Localize("$item_weight"));
			}
		}

		[HarmonyPatch(typeof(Requirement), "GetAmount")]
		private static class UpgradeCost
		{
			private static bool Prefix(Requirement __instance, int __0, ref int __result)
			{
				if (__instance.m_upgraderResource || __0 <= 1)
				{
					return true;
				}
				ObjectDB instance = ObjectDB.instance;
				if (!Object.op_Implicit((Object)(object)instance) || !instance.m_recipes.Any((Recipe r) => Object.op_Implicit((Object)(object)r) && Object.op_Implicit((Object)(object)r.m_item) && IsCape(r.m_item.m_itemData) && r.m_resources.Contains(__instance)))
				{
					return true;
				}
				__result = ((__instance.m_amountPerLevel != 0) ? Rules.UpgradeCost(__0) : 0);
				return false;
			}
		}

		[HarmonyPatch(typeof(Character), "CustomFixedUpdate")]
		private static class CapeUpdate
		{
			private static void Postfix(Character __instance)
			{
				ZNetView component = ((Component)__instance).GetComponent<ZNetView>();
				if (!Object.op_Implicit((Object)(object)component) || !component.IsValid() || !component.IsOwner())
				{
					return;
				}
				Player val = (Player)(object)((__instance is Player) ? __instance : null);
				if (val != null)
				{
					ItemData val2 = EquippedCape((Humanoid)(object)val);
					float num = (Is(val2, "SC_CapeLeech") ? Rules.LifestealRate(val2.m_quality, LifestealMultiplier.Value) : 0f);
					if (component.GetZDO().GetFloat("SC_Lifesteal", 0f) != num)
					{
						component.GetZDO().Set("SC_Lifesteal", num);
					}
					if (Is(val2, "SC_CapeRubberGuck"))
					{
						__instance.GetSEMan().RemoveStatusEffect(SEMan.s_statusEffectWet, false);
					}
				}
			}
		}

		[HarmonyPatch(typeof(SEMan), "AddStatusEffect", new Type[]
		{
			typeof(StatusEffect),
			typeof(bool),
			typeof(int),
			typeof(float),
			typeof(short)
		})]
		private static class BlockWet
		{
			private static bool Prefix(SEMan __instance, StatusEffect statusEffect, Character ___m_character, ref StatusEffect __result)
			{
				if (!Object.op_Implicit((Object)(object)statusEffect) || ((Object)statusEffect).name != "Wet" || !Is(EquippedCape((Humanoid)(object)((___m_character is Humanoid) ? ___m_character : null)), "SC_CapeRubberGuck"))
				{
					return true;
				}
				__result = null;
				return false;
			}
		}

		[HarmonyPatch(typeof(Character), "ApplyDamage")]
		private static class Lifesteal
		{
			private static void Prefix(Character __instance, out float __state)
			{
				__state = __instance.GetHealth();
			}

			private static void Postfix(Character __instance, HitData hit, float __state)
			{
				float num = Rules.HealthLost(__state, __instance.GetHealth());
				if (num <= 0f)
				{
					return;
				}
				ZNetView component = ((Component)__instance).GetComponent<ZNetView>();
				if (component == null || !component.IsOwner())
				{
					return;
				}
				Character attacker = hit.GetAttacker();
				Player val = (Player)(object)((attacker is Player) ? attacker : null);
				if (Object.op_Implicit((Object)(object)val) && !((Object)(object)val == (Object)(object)__instance) && !((Character)val).IsDead())
				{
					ZNetView component2 = ((Component)val).GetComponent<ZNetView>();
					ItemData val2 = EquippedCape((Humanoid)(object)val);
					float num2 = ((Object.op_Implicit((Object)(object)component2) && component2.IsValid() && !component2.IsOwner()) ? component2.GetZDO().GetFloat("SC_Lifesteal", 0f) : (Is(val2, "SC_CapeLeech") ? Rules.LifestealRate(val2.m_quality, LifestealMultiplier.Value) : 0f));
					if (num2 > 0f)
					{
						((Character)val).Heal(num * num2, true);
					}
				}
			}
		}

		public const string Guid = "joshu.swampcapes";

		internal const string RubberCape = "SC_CapeRubberGuck";

		internal const string LeechCape = "SC_CapeLeech";

		internal const string Rubber = "SC_Rubber";

		internal const string RateKey = "SC_Lifesteal";

		internal static Plugin Instance;

		internal static ConfigEntry<float> GuckGlowStrength;

		internal static ConfigEntry<float> LeechGlowStrength;

		internal static ConfigEntry<float> LifestealMultiplier;

		private Harmony harmony;

		private static readonly HashSet<Requirement> CapeRequirements = new HashSet<Requirement>();

		private void Awake()
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Expected O, but got Unknown
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Expected O, but got Unknown
			Instance = this;
			GuckGlowStrength = ((BaseUnityPlugin)this).Config.Bind<float>("Appearance", "GuckGlowStrength", 1.6f, new ConfigDescription("Green hem glow intensity. Restart the game after changing this value.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 5f), Array.Empty<object>()));
			LeechGlowStrength = ((BaseUnityPlugin)this).Config.Bind<float>("Appearance", "LeechGlowStrength", 0.45f, new ConfigDescription("Subtle red-patch glow intensity for visibility in the swamp. Restart after changing this value; 0 disables glow.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 3f), Array.Empty<object>()));
			LifestealMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Gameplay", "LifestealMultiplier", 1f, "Multiplies Leech Cape lifesteal at every level. 1 = default (5% plus 2.5 percentage points per upgrade); 2 doubles it; 0.5 halves it; 0 disables it. Negative values act as 0; non-finite values use 1. Each player configures their own multiplier. Restart after editing the config file.");
			PrefabManager.OnVanillaPrefabsAvailable += Register;
			ItemManager.OnItemsRegistered += LinkIdols;
			harmony = new Harmony("joshu.swampcapes");
			harmony.PatchAll();
		}

		private void OnDestroy()
		{
			PrefabManager.OnVanillaPrefabsAvailable -= Register;
			ItemManager.OnItemsRegistered -= LinkIdols;
			Harmony obj = harmony;
			if (obj != null)
			{
				obj.UnpatchSelf();
			}
		}

		private void Register()
		{
			PrefabManager.OnVanillaPrefabsAvailable -= Register;
			CustomItem rubber = Add("SC_Rubber", "Resin", "Rubber", "A waterproof roll of black rubber, cured from guck and coal.", (RequirementConfig[])(object)new RequirementConfig[2]
			{
				Req("Guck", 2),
				Req("Coal", 5)
			});
			rubber.ItemDrop.m_itemData.m_shared.m_maxStackSize = 50;
			rubber.ItemDrop.m_itemData.m_shared.m_weight = 0.5f;
			rubber.ItemDrop.m_itemData.m_shared.m_icons = (Sprite[])(object)new Sprite[1] { Appearance.RubberIcon() };
			CustomItem guck = Add("SC_CapeRubberGuck", "CapeAsh", "Rubber Guck Cape", "You stink like fish... but at least you are dry!", (RequirementConfig[])(object)new RequirementConfig[2]
			{
				Req("SC_Rubber", 10, 2),
				Req("TrophyBlob", 1)
			});
			ConfigureCape(guck);
			StatusEffect consumeStatusEffect = PrefabManager.Instance.GetPrefab("MeadPoisonResist").GetComponent<ItemDrop>().m_itemData.m_shared.m_consumeStatusEffect;
			SE_Stats val = (SE_Stats)(object)((consumeStatusEffect is SE_Stats) ? consumeStatusEffect : null);
			if (!Object.op_Implicit((Object)(object)val))
			{
				throw new InvalidOperationException("Cannot resolve poison resistance mead's status effect.");
			}
			guck.ItemDrop.m_itemData.m_shared.m_damageModifiers = val.m_mods.Where((DamageModPair m) => (int)m.m_type == 256).ToList();
			if (guck.ItemDrop.m_itemData.m_shared.m_damageModifiers.Count == 0)
			{
				throw new InvalidOperationException("Poison resistance mead has no poison modifier.");
			}
			CustomItem leech = Add("SC_CapeLeech", "CapeAsksvin", "Leech Cape", "Suck the health off your enemies for 5% of damage dealt, increasing with each level", (RequirementConfig[])(object)new RequirementConfig[2]
			{
				Req("Bloodbag", 10, 2),
				Req("TrophyLeech", 1)
			});
			ConfigureCape(leech);
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Registered Rubber, Rubber Guck Cape and Leech Cape.");
			ApplyAppearance("Rubber Guck Cape icon", delegate
			{
				guck.ItemDrop.m_itemData.m_shared.m_icons = (Sprite[])(object)new Sprite[1] { Appearance.CapeIcon(guck.ItemDrop.m_itemData.m_shared.m_icons[0], guck: true) };
			});
			ApplyAppearance("Leech Cape icon", delegate
			{
				leech.ItemDrop.m_itemData.m_shared.m_icons = (Sprite[])(object)new Sprite[1] { Appearance.CapeIcon(leech.ItemDrop.m_itemData.m_shared.m_icons[0], guck: false) };
			});
			ApplyAppearance("Rubber", delegate
			{
				Appearance.RubberRoll(rubber.ItemPrefab);
			});
			ApplyAppearance("Rubber Guck Cape", delegate
			{
				Appearance.Cape(guck.ItemPrefab, guck: true);
			});
			ApplyAppearance("Leech Cape", delegate
			{
				Appearance.Cape(leech.ItemPrefab, guck: false);
			});
		}

		private void ApplyAppearance(string item, Action apply)
		{
			try
			{
				apply();
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("Appearance setup failed for " + item + "; its recipe is still registered. " + ex));
			}
		}

		private static RequirementConfig Req(string item, int amount, int upgrade = 0)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Expected O, but got Unknown
			return new RequirementConfig(item, amount, upgrade, true);
		}

		private static CustomItem Add(string id, string source, string name, string description, RequirementConfig[] costs)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: 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_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Expected O, but got Unknown
			CustomItem val = new CustomItem(id, source, new ItemConfig
			{
				Name = name,
				Description = description,
				CraftingStation = "piece_workbench",
				MinStationLevel = 1,
				Requirements = costs
			});
			if (!ItemManager.Instance.AddItem(val))
			{
				throw new InvalidOperationException("Could not register " + id);
			}
			return val;
		}

		private static void ConfigureCape(CustomItem cape)
		{
			SharedData shared = cape.ItemDrop.m_itemData.m_shared;
			shared.m_maxQuality = 5;
			shared.m_armor = 1f;
			shared.m_armorPerLevel = 1f;
			shared.m_equipStatusEffect = null;
			shared.m_setStatusEffect = null;
			shared.m_setName = "";
			shared.m_damageModifiers = new List<DamageModPair>();
			shared.m_movementModifier = 0f;
			shared.m_eitrRegenModifier = 0f;
			shared.m_heatResistanceModifier = 0f;
			shared.m_jumpStaminaModifier = 0f;
			shared.m_attackStaminaModifier = 0f;
			shared.m_blockStaminaModifier = 0f;
			shared.m_dodgeStaminaModifier = 0f;
			shared.m_swimStaminaModifier = 0f;
			shared.m_sneakStaminaModifier = 0f;
			shared.m_runStaminaModifier = 0f;
		}

		private void LinkIdols()
		{
			ObjectDB instance = ObjectDB.instance;
			if (!Object.op_Implicit((Object)(object)instance))
			{
				return;
			}
			CapeRequirements.Clear();
			foreach (Recipe item2 in instance.m_recipes.Where((Recipe r) => Object.op_Implicit((Object)(object)r) && Object.op_Implicit((Object)(object)r.m_item) && IsCape(r.m_item.m_itemData)))
			{
				Requirement[] resources = item2.m_resources;
				foreach (Requirement item in resources)
				{
					CapeRequirements.Add(item);
				}
			}
			Requirement[] array = ((IEnumerable<Recipe>)instance.m_recipes).FirstOrDefault((Func<Recipe, bool>)((Recipe r) => Object.op_Implicit((Object)(object)r) && Object.op_Implicit((Object)(object)r.m_item) && ((Object)((Component)r.m_item).gameObject).name == "ArmorIronChest"))?.m_resources.Where((Requirement r) => r.m_upgraderResource).ToArray();
			if (array == null || array.Length == 0)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)"Iron armor idol requirement missing; Forge of Potential integration could not be linked.");
				return;
			}
			foreach (Recipe item3 in instance.m_recipes.Where((Recipe r) => Object.op_Implicit((Object)(object)r) && Object.op_Implicit((Object)(object)r.m_item) && IsCape(r.m_item.m_itemData)))
			{
				if (!item3.m_resources.Any((Requirement r) => r.m_upgraderResource))
				{
					item3.m_resources = item3.m_resources.Concat(((IEnumerable<Requirement>)array).Select((Func<Requirement, Requirement>)((Requirement r) => new Requirement
					{
						m_resItem = r.m_resItem,
						m_amount = r.m_amount,
						m_amountPerLevel = r.m_amountPerLevel,
						m_upgraderResource = true,
						m_recover = r.m_recover
					}))).ToArray();
				}
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Linked both capes to the native iron protection idol requirements.");
		}

		internal static bool IsCape(ItemData item)
		{
			if (!Is(item, "SC_CapeRubberGuck"))
			{
				return Is(item, "SC_CapeLeech");
			}
			return true;
		}

		internal static bool Is(ItemData item, string id)
		{
			if (item != null)
			{
				if (!Object.op_Implicit((Object)(object)item.m_dropPrefab) || !(((Object)item.m_dropPrefab).name == id))
				{
					return item.m_shared.m_name == ((id == "SC_CapeRubberGuck") ? "Rubber Guck Cape" : ((id == "SC_CapeLeech") ? "Leech Cape" : "Rubber"));
				}
				return true;
			}
			return false;
		}

		internal static ItemData EquippedCape(Humanoid player)
		{
			if (player == null)
			{
				return null;
			}
			Inventory inventory = player.GetInventory();
			if (inventory == null)
			{
				return null;
			}
			return ((IEnumerable<ItemData>)inventory.GetAllItems()).FirstOrDefault((Func<ItemData, bool>)((ItemData i) => i.m_equipped && IsCape(i)));
		}
	}
	internal static class Rules
	{
		internal static int UpgradeCost(int targetLevel)
		{
			if (targetLevel < 2 || targetLevel > 5)
			{
				return 0;
			}
			return 2 << targetLevel - 2;
		}

		internal static float ValidMultiplier(float multiplier)
		{
			if (!float.IsNaN(multiplier) && !float.IsInfinity(multiplier))
			{
				return Math.Max(0f, multiplier);
			}
			return 1f;
		}

		internal static float LifestealPercent(int level, float multiplier = 1f)
		{
			return (5f + (float)(Math.Max(1, level) - 1) * 2.5f) * ValidMultiplier(multiplier);
		}

		internal static float LifestealRate(int level, float multiplier = 1f)
		{
			return LifestealPercent(level, multiplier) / 100f;
		}

		internal static float HealthLost(float before, float after)
		{
			return Math.Max(0f, Math.Min(before, before - after));
		}
	}
	internal static class TooltipText
	{
		internal static string LifestealLine(int level, int previousLevel = 0, float multiplier = 1f)
		{
			string text = Rules.LifestealPercent(level, multiplier).ToString("0.##", CultureInfo.InvariantCulture);
			if (previousLevel > 0 && previousLevel < level)
			{
				return "Lifesteal: <color=orange>" + Rules.LifestealPercent(previousLevel, multiplier).ToString("0.##", CultureInfo.InvariantCulture) + "% → " + text + "%</color>";
			}
			return "Lifesteal: <color=orange>" + text + "%</color>";
		}

		internal static string LeechDescription(float multiplier = 1f)
		{
			return "Suck the health off your enemies for " + Rules.LifestealPercent(1, multiplier).ToString("0.##", CultureInfo.InvariantCulture) + "% of damage dealt, increasing with each level";
		}

		internal static string InsertAfterWeight(string tooltip, string stats, string translatedWeight)
		{
			int num = tooltip.IndexOf("$item_weight", StringComparison.Ordinal);
			if (num < 0 && !string.IsNullOrEmpty(translatedWeight))
			{
				num = tooltip.IndexOf(translatedWeight + ":", StringComparison.Ordinal);
			}
			if (num < 0)
			{
				return tooltip + "\n" + stats;
			}
			int num2 = tooltip.IndexOf('\n', num);
			if (num2 >= 0)
			{
				return tooltip.Insert(num2, "\n" + stats);
			}
			return tooltip + "\n" + stats;
		}
	}
}