Mods/Poop.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem;
using Il2CppSystem.Reflection;
using MelonLoader;
using MelonLoader.Preferences;
using Microsoft.CodeAnalysis;
using Poop;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(PoopMod), "Poop", "1.0.0", "Zooks", null)]
[assembly: MelonGame("Boneloaf", "Gang Beasts")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("Poop")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Poop")]
[assembly: AssemblyTitle("Poop")]
[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 Poop
{
	internal static class LocalFlags
	{
		private const BindingFlags Flags = (BindingFlags)52;

		public static bool SaysLocal(Transform root)
		{
			foreach (Component componentsInChild in ((Component)root).GetComponentsInChildren<Component>(true))
			{
				if ((Object)(object)componentsInChild == (Object)null)
				{
					continue;
				}
				try
				{
					if (Check(componentsInChild))
					{
						return true;
					}
				}
				catch
				{
				}
			}
			return false;
		}

		private static bool Check(Component c)
		{
			Type il2CppType = ((Object)c).GetIl2CppType();
			foreach (PropertyInfo item in (Il2CppArrayBase<PropertyInfo>)(object)il2CppType.GetProperties((BindingFlags)52))
			{
				if (!(item.PropertyType.FullName != "System.Boolean") && Interesting(((MemberInfo)item).Name))
				{
					Object value = item.GetValue((Object)(object)c, (Il2CppReferenceArray<Object>)null);
					if (value != null && ((Il2CppObjectBase)value).Unbox<bool>())
					{
						return true;
					}
				}
			}
			foreach (FieldInfo item2 in (Il2CppArrayBase<FieldInfo>)(object)il2CppType.GetFields((BindingFlags)52))
			{
				if (!(item2.FieldType.FullName != "System.Boolean") && Interesting(((MemberInfo)item2).Name))
				{
					Object value2 = item2.GetValue((Object)(object)c);
					if (value2 != null && ((Il2CppObjectBase)value2).Unbox<bool>())
					{
						return true;
					}
				}
			}
			return false;
		}

		private static bool Interesting(string name)
		{
			string text = name.ToLowerInvariant().Replace("_", "").Replace("<", "")
				.Replace(">k__backingfield", "");
			if (text.StartsWith("m"))
			{
				text = text.Substring(1);
			}
			if (!text.Contains("islocal"))
			{
				switch (text)
				{
				default:
					return text == "isowned";
				case "isowner":
				case "ismine":
				case "hasauthority":
					break;
				}
			}
			return true;
		}
	}
	internal static class PoopAudio
	{
		public static float Volume = 1f;

		private static AudioSource _normal;

		private static AudioSource _slow;

		private static bool _checkedListener;

		private static bool _moaned;

		private static void Ensure()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			//IL_0036: Expected O, but got Unknown
			if (!((Object)(object)_normal != (Object)null))
			{
				GameObject val = new GameObject("PoopSfx")
				{
					hideFlags = (HideFlags)61
				};
				Object.DontDestroyOnLoad((Object)val);
				_normal = MakeSource(val);
				_slow = MakeSource(val);
			}
		}

		private static AudioSource MakeSource(GameObject go)
		{
			AudioSource obj = go.AddComponent<AudioSource>();
			obj.playOnAwake = false;
			obj.loop = false;
			obj.spatialBlend = 0f;
			obj.priority = 0;
			obj.ignoreListenerPause = true;
			obj.bypassEffects = true;
			obj.bypassListenerEffects = true;
			obj.bypassReverbZones = true;
			return obj;
		}

		public static void Play(AudioClip clip, float pitch, float vol)
		{
			if ((Object)(object)clip == (Object)null)
			{
				if (!_moaned)
				{
					_moaned = true;
					MelonLogger.Warning("no clip to play, poop.wav didnt load (check the startup log for where it looked)");
				}
				return;
			}
			Ensure();
			if (!_checkedListener)
			{
				_checkedListener = true;
				if ((Object)(object)Object.FindObjectOfType<AudioListener>() == (Object)null)
				{
					MelonLogger.Warning("scene has no AudioListener, you wont hear anything");
				}
				if (AudioListener.volume <= 0.001f)
				{
					MelonLogger.Warning("AudioListener.volume is 0");
				}
			}
			AudioSource obj = ((pitch > 0.98f) ? _normal : _slow);
			obj.clip = clip;
			obj.pitch = pitch;
			obj.volume = Mathf.Clamp01(vol * Volume);
			obj.Play();
		}

		public static AudioClip LoadWav(string path)
		{
			byte[] array = File.ReadAllBytes(path);
			if (array.Length < 12 || Tag(array, 0) != "RIFF" || Tag(array, 8) != "WAVE")
			{
				throw new Exception("not a wav file");
			}
			int num = 0;
			int num2 = 0;
			int num3 = 0;
			int num4 = 0;
			int num5 = -1;
			int num6 = 0;
			int num7 = 12;
			while (num7 + 8 <= array.Length)
			{
				string text = Tag(array, num7);
				int num8 = BitConverter.ToInt32(array, num7 + 4);
				num7 += 8;
				if (text == "fmt ")
				{
					num = BitConverter.ToInt16(array, num7);
					num2 = BitConverter.ToInt16(array, num7 + 2);
					num3 = BitConverter.ToInt32(array, num7 + 4);
					num4 = BitConverter.ToInt16(array, num7 + 14);
					if (num == -2 && num8 >= 26)
					{
						num = BitConverter.ToInt16(array, num7 + 24);
					}
				}
				else if (text == "data")
				{
					num5 = num7;
					num6 = Math.Min(num8, array.Length - num7);
				}
				num7 += num8 + (num8 & 1);
			}
			if (num5 < 0)
			{
				throw new Exception("no data chunk");
			}
			if (num2 < 1 || num3 < 1)
			{
				throw new Exception("bad fmt chunk");
			}
			int num9 = num4 / 8;
			int num10 = num6 / num9 / num2;
			float[] array2 = new float[num10 * num2];
			for (int i = 0; i < array2.Length; i++)
			{
				int num11 = num5 + i * num9;
				float num12 = ((num == 3 && num4 == 32) ? BitConverter.ToSingle(array, num11) : (num4 switch
				{
					16 => (float)BitConverter.ToInt16(array, num11) / 32768f, 
					8 => (float)(array[num11] - 128) / 128f, 
					24 => (float)(((array[num11] << 8) | (array[num11 + 1] << 16) | (array[num11 + 2] << 24)) >> 8) / 8388608f, 
					32 => (float)BitConverter.ToInt32(array, num11) / 2.1474836E+09f, 
					_ => throw new Exception($"unsupported wav: fmt {num} {num4}bit"), 
				}));
				array2[i] = num12;
			}
			AudioClip obj = AudioClip.Create(Path.GetFileNameWithoutExtension(path), num10, num2, num3, false);
			obj.SetData(Il2CppStructArray<float>.op_Implicit(array2), 0);
			return obj;
		}

		private static string Tag(byte[] b, int at)
		{
			return Encoding.ASCII.GetString(b, at, 4);
		}
	}
	internal static class PoopLook
	{
		private const string UrpLit = "Universal Render Pipeline/Lit";

		private const string UrpSimple = "Universal Render Pipeline/Simple Lit";

		private static readonly Color Dark = new Color(0.2f, 0.1f, 0.04f);

		private static readonly Color Brown = new Color(0.36f, 0.2f, 0.08f);

		private static readonly Color Light = new Color(0.46f, 0.28f, 0.12f);

		public static string ShaderOverride = "";

		public static string Mode = "Auto";

		public static int DonorLayer = 0;

		private static bool? _urp;

		private static List<(Material mat, int layer, string from, int score)> _scan;

		public static string PipelineName
		{
			get
			{
				RenderPipelineAsset renderPipelineAsset = GraphicsSettings.renderPipelineAsset;
				if (!((Object)(object)renderPipelineAsset == (Object)null))
				{
					return ((MemberInfo)((Object)renderPipelineAsset).GetIl2CppType()).Name;
				}
				return "Built-in";
			}
		}

		public static bool IsUrp
		{
			get
			{
				if (!_urp.HasValue)
				{
					_urp = PipelineName.Contains("Universal");
				}
				return _urp.Value;
			}
		}

		public static void Forget()
		{
			_urp = null;
			_scan = null;
		}

		public static Material PoopMaterial()
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			return Setup(Base("poop"), Color.white, 0.62f);
		}

		public static Material SplatMaterial()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			return Setup(Base("splat"), new Color(0.7f, 0.6f, 0.55f), 0.75f);
		}

		private static Material Base(string name)
		{
			Material val = null;
			string how = "";
			if (!string.IsNullOrEmpty(ShaderOverride))
			{
				val = Fresh(ShaderOverride);
				how = "ShaderOverride";
				if ((Object)(object)val == (Object)null)
				{
					MelonLogger.Warning("ShaderOverride '" + ShaderOverride + "' isnt in the build");
				}
			}
			if ((Object)(object)val == (Object)null && IsUrp)
			{
				switch (Mode)
				{
				case "Lit":
					val = Fresh("Universal Render Pipeline/Lit");
					how = "fresh URP Lit";
					break;
				case "SimpleLit":
					val = Fresh("Universal Render Pipeline/Simple Lit");
					how = "fresh URP Simple Lit";
					break;
				case "Clone":
					val = Clone(null, out how);
					break;
				default:
					val = Clone("Universal Render Pipeline/Lit", out how);
					if ((Object)(object)val == (Object)null)
					{
						val = Fresh("Universal Render Pipeline/Lit");
						how = "fresh URP Lit";
					}
					if ((Object)(object)val == (Object)null)
					{
						val = Fresh("Universal Render Pipeline/Simple Lit");
						how = "fresh URP Simple Lit";
					}
					if ((Object)(object)val == (Object)null)
					{
						val = Clone(null, out how);
					}
					break;
				}
			}
			if ((Object)(object)val == (Object)null && !IsUrp)
			{
				val = Clone(null, out how);
				if ((Object)(object)val == (Object)null)
				{
					val = Fresh("Standard");
					how = "fresh Standard";
				}
				if ((Object)(object)val == (Object)null)
				{
					val = Fresh("Legacy Shaders/Diffuse");
					how = "fresh Legacy Diffuse";
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				val = Clone(null, out how);
				if ((Object)(object)val == (Object)null)
				{
					throw new Exception("could not build any material at all");
				}
			}
			((Object)val).name = name;
			MelonLogger.Msg($"{name} material: {how} -> shader '{((Object)val.shader).name}' (pipeline {PipelineName})");
			return val;
		}

		private static Material Fresh(string shaderName)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			Shader val = Shader.Find(shaderName);
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			Material val2 = new Material(val);
			Scan();
			foreach (var item in _scan)
			{
				if (!(((Object)item.mat.shader).name != shaderName))
				{
					val2.shaderKeywords = item.mat.shaderKeywords;
					break;
				}
			}
			return val2;
		}

		private static Material Clone(string wantShader, out string how)
		{
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Expected O, but got Unknown
			Scan();
			foreach (var item in _scan)
			{
				if ((wantShader == null || !(((Object)item.mat.shader).name != wantShader)) && item.score >= 0)
				{
					DonorLayer = item.layer;
					how = $"clone of '{((Object)item.mat).name}' off '{item.from}' (layer {item.layer}, score {item.score})";
					return new Material(item.mat);
				}
			}
			how = "";
			return null;
		}

		private static void Scan()
		{
			if (_scan != null)
			{
				return;
			}
			_scan = new List<(Material, int, string, int)>();
			HashSet<int> hashSet = new HashSet<int>();
			Dictionary<string, int> dictionary = new Dictionary<string, int>();
			foreach (Renderer item in Object.FindObjectsOfType<Renderer>())
			{
				if ((Object)(object)item == (Object)null || !item.enabled || !item.isVisible)
				{
					continue;
				}
				string name = ((MemberInfo)((Object)item).GetIl2CppType()).Name;
				int num = 0;
				if (name == "MeshRenderer")
				{
					num += 10;
				}
				else if (name == "SkinnedMeshRenderer")
				{
					num += 2;
				}
				else if (name.Contains("Particle") || name.Contains("Line") || name.Contains("Trail"))
				{
					num -= 100;
				}
				foreach (Material item2 in (Il2CppArrayBase<Material>)(object)item.sharedMaterials)
				{
					if ((Object)(object)item2 == (Object)null || (Object)(object)item2.shader == (Object)null)
					{
						continue;
					}
					string name2 = ((Object)item2.shader).name;
					dictionary[name2] = ((!dictionary.TryGetValue(name2, out var value)) ? 1 : (value + 1));
					if (!hashSet.Add(((Object)item2).GetInstanceID()) || item2.renderQueue > 2500)
					{
						continue;
					}
					int num2 = num;
					if (IsUrp)
					{
						if (name2 == "Universal Render Pipeline/Lit")
						{
							num2 += 50;
						}
						else if (name2 == "Universal Render Pipeline/Simple Lit")
						{
							num2 += 40;
						}
						else if (name2.StartsWith("Universal Render Pipeline/"))
						{
							num2 += 25;
						}
						else if (name2.Contains("Shader Graphs/"))
						{
							num2 += 10;
						}
						else if (name2 == "Standard" || name2.StartsWith("Legacy") || name2.Contains("Mobile/"))
						{
							num2 -= 100;
						}
					}
					else if (name2 == "Standard")
					{
						num2 += 30;
					}
					else if (name2.Contains("Standard"))
					{
						num2 += 15;
					}
					else if (name2.Contains("Diffuse"))
					{
						num2 += 5;
					}
					if (item2.HasProperty("_BaseMap") || item2.HasProperty("_MainTex"))
					{
						num2 += 5;
					}
					if (item2.HasProperty("_BaseColor") || item2.HasProperty("_Color"))
					{
						num2 += 3;
					}
					if (!item2.IsKeywordEnabled("_ALPHATEST_ON") && !item2.IsKeywordEnabled("_SURFACE_TYPE_TRANSPARENT") && !item2.IsKeywordEnabled("_ALPHABLEND_ON"))
					{
						num2 += 4;
					}
					if (name2.Contains("Skybox") || name2.Contains("Particle") || name2.Contains("UI") || name2.Contains("Sprite") || name2.Contains("Hidden") || name2.Contains("Terrain"))
					{
						num2 -= 100;
					}
					_scan.Add((item2, ((Component)item).gameObject.layer, ((Object)item).name, num2));
				}
			}
			_scan.Sort(((Material mat, int layer, string from, int score) a, (Material mat, int layer, string from, int score) b) => b.score.CompareTo(a.score));
			List<KeyValuePair<string, int>> list = new List<KeyValuePair<string, int>>(dictionary);
			list.Sort((KeyValuePair<string, int> a, KeyValuePair<string, int> b) => b.Value.CompareTo(a.Value));
			StringBuilder stringBuilder = new StringBuilder("shaders in scene:");
			for (int num3 = 0; num3 < list.Count && num3 < 12; num3++)
			{
				StringBuilder stringBuilder2 = stringBuilder;
				StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(5, 2, stringBuilder2);
				handler.AppendLiteral("  [");
				handler.AppendFormatted(list[num3].Value);
				handler.AppendLiteral("] ");
				handler.AppendFormatted(list[num3].Key);
				stringBuilder2.Append(ref handler);
			}
			MelonLogger.Msg(stringBuilder.ToString());
		}

		private static Material Setup(Material m, Color tint, float gloss)
		{
			//IL_0057: 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_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: 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_0099: 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_02b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_034b: Unknown result type (might be due to invalid IL or missing references)
			//IL_038a: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_040a: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0445: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = (Texture2D)(object)(m.mainTexture = (Texture)(object)PoopTexture(128));
			if (m.HasProperty("_BaseMap"))
			{
				m.SetTexture("_BaseMap", (Texture)(object)val);
			}
			if (m.HasProperty("_MainTex"))
			{
				m.SetTexture("_MainTex", (Texture)(object)val);
			}
			if (m.HasProperty("_BaseColor"))
			{
				m.SetColor("_BaseColor", tint);
			}
			if (m.HasProperty("_Color"))
			{
				m.SetColor("_Color", tint);
			}
			if (m.HasProperty("_BaseMap"))
			{
				m.SetTextureScale("_BaseMap", Vector2.one);
				m.SetTextureOffset("_BaseMap", Vector2.zero);
			}
			m.mainTextureScale = Vector2.one;
			m.mainTextureOffset = Vector2.zero;
			if (m.HasProperty("_Smoothness"))
			{
				m.SetFloat("_Smoothness", gloss);
			}
			if (m.HasProperty("_Glossiness"))
			{
				m.SetFloat("_Glossiness", gloss);
			}
			if (m.HasProperty("_Metallic"))
			{
				m.SetFloat("_Metallic", 0.05f);
			}
			if (m.HasProperty("_SpecColor"))
			{
				m.SetColor("_SpecColor", new Color(0.3f, 0.3f, 0.3f));
			}
			if (m.HasProperty("_Surface"))
			{
				m.SetFloat("_Surface", 0f);
			}
			if (m.HasProperty("_Blend"))
			{
				m.SetFloat("_Blend", 0f);
			}
			if (m.HasProperty("_AlphaClip"))
			{
				m.SetFloat("_AlphaClip", 0f);
			}
			if (m.HasProperty("_Mode"))
			{
				m.SetFloat("_Mode", 0f);
			}
			if (m.HasProperty("_SrcBlend"))
			{
				m.SetInt("_SrcBlend", 1);
			}
			if (m.HasProperty("_DstBlend"))
			{
				m.SetInt("_DstBlend", 0);
			}
			if (m.HasProperty("_ZWrite"))
			{
				m.SetInt("_ZWrite", 1);
			}
			if (m.HasProperty("_Cull"))
			{
				m.SetInt("_Cull", 2);
			}
			if (m.HasProperty("_Cutoff"))
			{
				m.SetFloat("_Cutoff", 0f);
			}
			if (m.HasProperty("_QueueOffset"))
			{
				m.SetFloat("_QueueOffset", 0f);
			}
			m.DisableKeyword("_SURFACE_TYPE_TRANSPARENT");
			m.DisableKeyword("_ALPHATEST_ON");
			m.DisableKeyword("_ALPHABLEND_ON");
			m.DisableKeyword("_ALPHAPREMULTIPLY_ON");
			m.DisableKeyword("_ALPHAMODULATE_ON");
			m.SetOverrideTag("RenderType", "Opaque");
			m.renderQueue = 2000;
			if (m.IsKeywordEnabled("_EMISSION") && m.HasProperty("_EmissionColor"))
			{
				m.SetColor("_EmissionColor", Color.black);
			}
			if (m.IsKeywordEnabled("_NORMALMAP") && m.HasProperty("_BumpMap"))
			{
				m.SetTexture("_BumpMap", (Texture)(object)BumpTexture(128));
				if (m.HasProperty("_BumpScale"))
				{
					m.SetFloat("_BumpScale", 1f);
				}
			}
			if ((m.IsKeywordEnabled("_METALLICSPECGLOSSMAP") || m.IsKeywordEnabled("_METALLICGLOSSMAP")) && m.HasProperty("_MetallicGlossMap"))
			{
				m.SetTexture("_MetallicGlossMap", (Texture)(object)Flat(new Color(0.05f, 0f, 0f, gloss)));
			}
			if (m.IsKeywordEnabled("_SPECGLOSSMAP") && m.HasProperty("_SpecGlossMap"))
			{
				m.SetTexture("_SpecGlossMap", (Texture)(object)Flat(new Color(0.3f, 0.3f, 0.3f, gloss)));
			}
			if (m.IsKeywordEnabled("_OCCLUSIONMAP") && m.HasProperty("_OcclusionMap"))
			{
				m.SetTexture("_OcclusionMap", (Texture)(object)Flat(Color.white));
			}
			if (m.IsKeywordEnabled("_PARALLAXMAP") && m.HasProperty("_ParallaxMap"))
			{
				m.SetTexture("_ParallaxMap", (Texture)(object)Flat(Color.black));
			}
			if (m.HasProperty("_DetailAlbedoMap"))
			{
				m.SetTexture("_DetailAlbedoMap", (Texture)(object)Flat(Color.gray));
			}
			if (m.HasProperty("_DetailNormalMap"))
			{
				m.SetTexture("_DetailNormalMap", (Texture)null);
			}
			if (m.HasProperty("_DetailMask"))
			{
				m.SetTexture("_DetailMask", (Texture)(object)Flat(Color.white));
			}
			return m;
		}

		public static string Keywords(Material m)
		{
			StringBuilder stringBuilder = new StringBuilder();
			foreach (string item in (Il2CppArrayBase<string>)(object)m.shaderKeywords)
			{
				if (stringBuilder.Length > 0)
				{
					stringBuilder.Append(' ');
				}
				stringBuilder.Append(item);
			}
			return stringBuilder.ToString();
		}

		private static Texture2D Flat(Color c)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Expected O, but got Unknown
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: 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_002b: 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)
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
			val.SetPixels(Il2CppStructArray<Color>.op_Implicit((Color[])(object)new Color[4] { c, c, c, c }));
			val.Apply();
			return val;
		}

		private static Texture2D PoopTexture(int size)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Expected O, but got Unknown
			//IL_0085: 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_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: 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_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(size, size, (TextureFormat)4, true);
			Color[] array = (Color[])(object)new Color[size * size];
			float num = Random.Range(0f, 100f);
			float num2 = Random.Range(0f, 100f);
			for (int i = 0; i < size; i++)
			{
				for (int j = 0; j < size; j++)
				{
					float num3 = (float)j / (float)size;
					float num4 = (float)i / (float)size;
					float num5 = Mathf.PerlinNoise(num3 * 6f + num, num4 * 6f + num2);
					float num6 = Mathf.PerlinNoise(num3 * 22f + num2, num4 * 22f + num);
					Color val2 = Color.Lerp(Dark, Light, num5);
					val2 = Color.Lerp(val2, Brown, num6 * 0.5f);
					if (Mathf.PerlinNoise(num3 * 60f + num, num4 * 60f) > 0.72f)
					{
						val2 *= 0.7f;
					}
					val2.a = 1f;
					array[i * size + j] = val2;
				}
			}
			val.SetPixels(Il2CppStructArray<Color>.op_Implicit(array));
			((Texture)val).wrapMode = (TextureWrapMode)0;
			val.Apply();
			return val;
		}

		private static Texture2D BumpTexture(int size)
		{
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Expected O, but got Unknown
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			float[] array = new float[size * size];
			float num = Random.Range(0f, 100f);
			for (int i = 0; i < size; i++)
			{
				for (int j = 0; j < size; j++)
				{
					array[i * size + j] = Mathf.PerlinNoise((float)j / (float)size * 10f + num, (float)i / (float)size * 10f) * 0.6f + Mathf.PerlinNoise((float)j / (float)size * 40f, (float)i / (float)size * 40f + num) * 0.4f;
				}
			}
			Texture2D val = new Texture2D(size, size, (TextureFormat)4, true);
			Color[] array2 = (Color[])(object)new Color[size * size];
			for (int k = 0; k < size; k++)
			{
				for (int l = 0; l < size; l++)
				{
					float num2 = array[k * size + (l + size - 1) % size];
					float num3 = array[k * size + (l + 1) % size];
					float num4 = array[(k + size - 1) % size * size + l];
					float num5 = array[(k + 1) % size * size + l];
					Vector3 val2 = new Vector3((num2 - num3) * 3f, (num4 - num5) * 3f, 1f);
					Vector3 normalized = ((Vector3)(ref val2)).normalized;
					array2[k * size + l] = new Color(1f, normalized.y * 0.5f + 0.5f, 1f, normalized.x * 0.5f + 0.5f);
				}
			}
			val.SetPixels(Il2CppStructArray<Color>.op_Implicit(array2));
			((Texture)val).wrapMode = (TextureWrapMode)0;
			val.Apply();
			return val;
		}
	}
	internal static class PoopMesh
	{
		public static Mesh BuildSwirl()
		{
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: 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)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: 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_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: 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_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b2: Expected O, but got Unknown
			//IL_0306: Unknown result type (might be due to invalid IL or missing references)
			//IL_030e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0313: Unknown result type (might be due to invalid IL or missing references)
			//IL_0318: Unknown result type (might be due to invalid IL or missing references)
			//IL_0323: Unknown result type (might be due to invalid IL or missing references)
			//IL_0328: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: 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_01ed: 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_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Unknown result type (might be due to invalid IL or missing references)
			Vector3[] array = (Vector3[])(object)new Vector3[120];
			float[] array2 = new float[120];
			for (int i = 0; i < 120; i++)
			{
				float num = (float)i / 119f;
				float num2 = num * 2.6f * (float)Math.PI * 2f;
				float num3 = Mathf.Lerp(0.13f, 0f, num * num);
				array[i] = new Vector3(Mathf.Cos(num2) * num3, num * 0.3f + 0.06f, Mathf.Sin(num2) * num3);
				float num4 = Mathf.Sin(Mathf.Clamp01(Mathf.Min(num * 10f, (1f - num) * 5f)) * (float)Math.PI * 0.5f);
				array2[i] = Mathf.Lerp(0.075f, 0.03f, num) * num4;
			}
			List<Vector3> list = new List<Vector3>();
			List<Vector2> list2 = new List<Vector2>();
			List<int> list3 = new List<int>();
			Vector3 val = Vector3.right;
			for (int j = 0; j < 120; j++)
			{
				Vector3 val2 = array[Mathf.Max(j - 1, 0)];
				Vector3 val3 = array[Mathf.Min(j + 1, 119)] - val2;
				Vector3 normalized = ((Vector3)(ref val3)).normalized;
				Vector3 val4 = Vector3.Cross(normalized, Vector3.up);
				if (((Vector3)(ref val4)).sqrMagnitude > 0.0001f)
				{
					val = ((Vector3)(ref val4)).normalized;
				}
				val3 = Vector3.Cross(val, normalized);
				Vector3 normalized2 = ((Vector3)(ref val3)).normalized;
				float num5 = (float)j / 119f;
				for (int k = 0; k <= 12; k++)
				{
					float num6 = (float)k / 12f * (float)Math.PI * 2f;
					float num7 = 1f + Mathf.PerlinNoise(num5 * 9f, (float)k * 0.4f) * 0.18f;
					Vector3 val5 = (val * Mathf.Cos(num6) + normalized2 * Mathf.Sin(num6)) * array2[j] * num7;
					list.Add(array[j] + val5);
					list2.Add(new Vector2((float)k / 12f, num5 * 5f));
				}
			}
			int num8 = 13;
			for (int l = 0; l < 119; l++)
			{
				for (int m = 0; m < 12; m++)
				{
					int num9 = l * num8 + m;
					int num10 = num9 + num8;
					list3.Add(num9);
					list3.Add(num10);
					list3.Add(num9 + 1);
					list3.Add(num9 + 1);
					list3.Add(num10);
					list3.Add(num10 + 1);
				}
			}
			Mesh val6 = new Mesh();
			((Object)val6).name = "poop";
			val6.vertices = Il2CppStructArray<Vector3>.op_Implicit(list.ToArray());
			val6.uv = Il2CppStructArray<Vector2>.op_Implicit(list2.ToArray());
			val6.triangles = Il2CppStructArray<int>.op_Implicit(list3.ToArray());
			val6.RecalculateNormals();
			int num11 = 60 * num8;
			Vector3 val7 = list[num11] - array[60];
			if (Vector3.Dot(((Il2CppArrayBase<Vector3>)(object)val6.normals)[num11], val7) < 0f)
			{
				Il2CppStructArray<int> triangles = val6.triangles;
				for (int n = 0; n < ((Il2CppArrayBase<int>)(object)triangles).Length; n += 3)
				{
					int num12 = ((Il2CppArrayBase<int>)(object)triangles)[n + 1];
					((Il2CppArrayBase<int>)(object)triangles)[n + 1] = ((Il2CppArrayBase<int>)(object)triangles)[n + 2];
					((Il2CppArrayBase<int>)(object)triangles)[n + 2] = num12;
				}
				val6.triangles = triangles;
				val6.RecalculateNormals();
			}
			val6.RecalculateBounds();
			val6.RecalculateTangents();
			return val6;
		}

		public static Mesh BuildBlob(int seed)
		{
			//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_003c: 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_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_0074: 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_0082: 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_00b1: 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_00bc: 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_00e9: 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_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Expected O, but got Unknown
			List<Vector3> verts = new List<Vector3>();
			List<Vector3> norms = new List<Vector3>();
			List<Vector2> uvs = new List<Vector2>();
			List<int> tris = new List<int>();
			State state = Random.state;
			Random.InitState(seed);
			Disc(Vector2.zero, 0.45f, 0.3f, 28);
			int num = Random.Range(3, 7);
			for (int i = 0; i < num; i++)
			{
				Vector2 val = Random.insideUnitCircle * 0.5f;
				Vector2 insideUnitCircle = Random.insideUnitCircle;
				Disc(val + ((Vector2)(ref insideUnitCircle)).normalized * 0.25f, Random.Range(0.04f, 0.11f), 0.25f, 10);
			}
			Random.state = state;
			Mesh val2 = new Mesh
			{
				name = "splat" + seed,
				vertices = Il2CppStructArray<Vector3>.op_Implicit(verts.ToArray()),
				normals = Il2CppStructArray<Vector3>.op_Implicit(norms.ToArray()),
				uv = Il2CppStructArray<Vector2>.op_Implicit(uvs.ToArray()),
				triangles = Il2CppStructArray<int>.op_Implicit(tris.ToArray())
			};
			val2.RecalculateBounds();
			return val2;
			void Disc(Vector2 centre, float radius, float wobble, int segs)
			{
				//IL_0014: 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_0025: 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_0051: Unknown result type (might be due to invalid IL or missing references)
				//IL_0056: Unknown result type (might be due to invalid IL or missing references)
				//IL_0057: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c3: 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_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_00e1: 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_00f1: Unknown result type (might be due to invalid IL or missing references)
				//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
				//IL_010e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0129: Unknown result type (might be due to invalid IL or missing references)
				//IL_012e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0130: Unknown result type (might be due to invalid IL or missing references)
				int count = verts.Count;
				verts.Add(new Vector3(centre.x, centre.y, 0f));
				norms.Add(Vector3.forward);
				uvs.Add(new Vector2(0.5f, 0.5f) + centre);
				float num2 = Random.Range(0f, 100f);
				for (int j = 0; j <= segs; j++)
				{
					float num3 = (float)j / (float)segs * (float)Math.PI * 2f;
					float num4 = Mathf.PerlinNoise(Mathf.Cos(num3) * 1.5f + num2, Mathf.Sin(num3) * 1.5f + num2);
					float num5 = radius * (1f - wobble + num4 * wobble * 2f);
					Vector2 val3 = centre + new Vector2(Mathf.Cos(num3), Mathf.Sin(num3)) * num5;
					verts.Add(new Vector3(val3.x, val3.y, 0f));
					norms.Add(Vector3.forward);
					uvs.Add(new Vector2(0.5f, 0.5f) + val3);
				}
				for (int k = 0; k < segs; k++)
				{
					tris.Add(count);
					tris.Add(count + 1 + k);
					tris.Add(count + 2 + k);
				}
			}
		}
	}
	public class PoopMod : MelonMod
	{
		private class Turd
		{
			public GameObject go;

			public Rigidbody rb;

			public Collider col;

			public Renderer mr;

			public float born;

			public float lastSplat = -99f;

			public Vector3 lastSplatPos;

			public Vector3 lastVel;

			public float lastThud = -99f;
		}

		private class Stain
		{
			public GameObject go;

			public float dies;
		}

		private MelonPreferences_Entry<string> _keyPref;

		private MelonPreferences_Entry<string> _bonePref;

		private MelonPreferences_Entry<int> _actorIndex;

		private MelonPreferences_Entry<float> _splatSecs;

		private MelonPreferences_Entry<float> _poopSecs;

		private MelonPreferences_Entry<float> _scale;

		private MelonPreferences_Entry<float> _launch;

		private MelonPreferences_Entry<float> _thudPitch;

		private MelonPreferences_Entry<float> _thudJolt;

		private MelonPreferences_Entry<float> _volume;

		private MelonPreferences_Entry<string> _shaderOverride;

		private MelonPreferences_Entry<string> _matMode;

		private MelonPreferences_Entry<int> _layerOverride;

		private MelonPreferences_Entry<bool> _debugCube;

		private Key _key = (Key)30;

		private readonly List<Turd> _turds = new List<Turd>();

		private readonly List<Stain> _stains = new List<Stain>();

		private Mesh _poopMesh;

		private Mesh[] _blobs;

		private Material _poopMat;

		private Material _splatMat;

		private AudioClip _sfx;

		private bool _built;

		private bool _sfxTried;

		private bool _diagDone;

		private int _layer;

		private Transform _butt;

		private Rigidbody[] _body = (Rigidbody[])(object)new Rigidbody[0];

		private float _nextButtSearch;

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

		public override void OnInitializeMelon()
		{
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_0225: Unknown result type (might be due to invalid IL or missing references)
			MelonPreferences_Category val = MelonPreferences.CreateCategory("Poop");
			_keyPref = val.CreateEntry<string>("Key", "P", (string)null, "Key name from UnityEngine.InputSystem.Key. Fn doesnt exist to the OS, pick something else.", false, false, (ValueValidator)null, (string)null);
			_bonePref = val.CreateEntry<string>("ButtBone", "hips", (string)null, "substring of the rigidbody name we poop out of", false, false, (ValueValidator)null, (string)null);
			_actorIndex = val.CreateEntry<int>("ActorIndex", -1, (string)null, "-1 = auto detect local player, otherwise force the nth character found", false, false, (ValueValidator)null, (string)null);
			_splatSecs = val.CreateEntry<float>("SplatSeconds", 20f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_poopSecs = val.CreateEntry<float>("PoopSeconds", 30f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_scale = val.CreateEntry<float>("Scale", 1f, (string)null, "poop size multiplier", false, false, (ValueValidator)null, (string)null);
			_launch = val.CreateEntry<float>("LaunchForce", 5f, (string)null, "how hard the player gets shoved upwards, 0 to disable", false, false, (ValueValidator)null, (string)null);
			_thudPitch = val.CreateEntry<float>("ImpactPitch", 0.55f, (string)null, "pitch of poop.wav when the poop hits something", false, false, (ValueValidator)null, (string)null);
			_thudJolt = val.CreateEntry<float>("ImpactJolt", 2.5f, (string)null, "how big a velocity change counts as a hit", false, false, (ValueValidator)null, (string)null);
			_volume = val.CreateEntry<float>("Volume", 1f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_shaderOverride = val.CreateEntry<string>("ShaderOverride", "", (string)null, "leave empty. otherwise a shader name eg 'Universal Render Pipeline/Simple Lit'", false, false, (ValueValidator)null, (string)null);
			_matMode = val.CreateEntry<string>("MaterialMode", "Auto", (string)null, "Auto, Lit, SimpleLit or Clone. Auto = clone a URP/Lit material from the level, else fresh Lit, else Simple Lit", false, false, (ValueValidator)null, (string)null);
			_layerOverride = val.CreateEntry<int>("LayerOverride", -1, (string)null, "-1 = auto pick a layer the camera renders. otherwise force a layer 0-31", false, false, (ValueValidator)null, (string)null);
			_debugCube = val.CreateEntry<bool>("DebugCube", false, (string)null, "also spawn two test cubes above every poop, for figuring out why its invisible", false, false, (ValueValidator)null, (string)null);
			if (Enum.TryParse<Key>(_keyPref.Value, ignoreCase: true, out Key result))
			{
				_key = result;
			}
			else
			{
				((MelonBase)this).LoggerInstance.Warning("'" + _keyPref.Value + "' isnt a key i know, using P");
			}
			PoopAudio.Volume = _volume.Value;
			((MelonBase)this).LoggerInstance.Msg($"loaded. press {_key} to poop");
		}

		public override void OnSceneWasLoaded(int buildIndex, string sceneName)
		{
			_built = false;
			_diagDone = false;
			_butt = null;
			_body = (Rigidbody[])(object)new Rigidbody[0];
			_turds.Clear();
			_stains.Clear();
			PoopLook.Forget();
		}

		public override void OnUpdate()
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			if (!_sfxTried)
			{
				_sfxTried = true;
				try
				{
					LoadSfx();
				}
				catch (Exception ex)
				{
					((MelonBase)this).LoggerInstance.Error("wav search blew up: " + ex);
				}
			}
			Keyboard current = Keyboard.current;
			if (current != null && ((ButtonControl)current[_key]).wasPressedThisFrame)
			{
				try
				{
					Squeeze();
				}
				catch (Exception ex2)
				{
					((MelonBase)this).LoggerInstance.Error("poop failed: " + ex2);
				}
			}
			TickTurds();
			TickStains();
		}

		public override void OnFixedUpdate()
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: 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_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_0060: 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)
			float time = Time.time;
			for (int i = 0; i < _turds.Count; i++)
			{
				Turd turd = _turds[i];
				if (!((Object)(object)turd.go == (Object)null) && !((Object)(object)turd.rb == (Object)null))
				{
					Vector3 velocity = turd.rb.velocity;
					Vector3 val = turd.lastVel - velocity;
					float magnitude = ((Vector3)(ref val)).magnitude;
					turd.lastVel = velocity;
					if (!(magnitude < _thudJolt.Value) && !(time - turd.lastThud < 0.25f) && !(time - turd.born < 0.1f))
					{
						turd.lastThud = time;
						PoopAudio.Play(_sfx, _thudPitch.Value, Mathf.Clamp(magnitude / 8f, 0.4f, 1f));
					}
				}
			}
		}

		private void LoadSfx()
		{
			List<string> list = new List<string>();
			try
			{
				list.Add(Path.GetDirectoryName(((MelonBase)this).MelonAssembly.Location));
			}
			catch
			{
			}
			try
			{
				string directoryName = Path.GetDirectoryName(Application.dataPath);
				list.Add(Path.Combine(directoryName, "Mods"));
				list.Add(Path.Combine(directoryName, "Mods", "Poop"));
				list.Add(Path.Combine(directoryName, "UserData"));
				list.Add(Path.Combine(directoryName, "UserData", "Poop"));
				list.Add(directoryName);
			}
			catch
			{
			}
			List<string> list2 = new List<string>();
			HashSet<string> hashSet = new HashSet<string>();
			foreach (string item in list)
			{
				if (string.IsNullOrEmpty(item))
				{
					continue;
				}
				string fullPath;
				try
				{
					fullPath = Path.GetFullPath(item);
				}
				catch
				{
					continue;
				}
				if (!hashSet.Add(fullPath) || !Directory.Exists(fullPath))
				{
					continue;
				}
				string[] files = Directory.GetFiles(fullPath, "*.wav");
				foreach (string text in files)
				{
					list2.Add(text);
					if (string.Equals(Path.GetFileName(text), "poop.wav", StringComparison.OrdinalIgnoreCase))
					{
						try
						{
							_sfx = PoopAudio.LoadWav(text);
							((MelonBase)this).LoggerInstance.Msg($"loaded {text} ({_sfx.length:0.00}s, {_sfx.channels}ch, {_sfx.frequency}hz)");
							return;
						}
						catch (Exception ex)
						{
							((MelonBase)this).LoggerInstance.Error("found " + text + " but couldnt read it: " + ex.Message);
						}
					}
				}
			}
			((MelonBase)this).LoggerInstance.Warning("no poop.wav. folders checked:");
			foreach (string item2 in hashSet)
			{
				((MelonBase)this).LoggerInstance.Warning("  " + item2);
			}
			if (list2.Count <= 0)
			{
				return;
			}
			((MelonBase)this).LoggerInstance.Warning("wavs i did see (rename one to poop.wav):");
			foreach (string item3 in list2)
			{
				((MelonBase)this).LoggerInstance.Warning("  " + item3);
			}
		}

		private void Squeeze()
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: 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_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Expected O, but got Unknown
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: 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)
			//IL_0307: Unknown result type (might be due to invalid IL or missing references)
			//IL_0308: Unknown result type (might be due to invalid IL or missing references)
			//IL_0320: Unknown result type (might be due to invalid IL or missing references)
			//IL_0294: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a4: Unknown result type (might be due to invalid IL or missing references)
			FindButt();
			if (!_built)
			{
				BuildStuff();
			}
			Vector3 val;
			Vector3 val2;
			if ((Object)(object)_butt != (Object)null)
			{
				val = _butt.position + Vector3.down * 0.15f;
				val2 = Vector3.down * 3f + Random.insideUnitSphere * 0.4f;
			}
			else
			{
				Camera val3 = MainCam();
				if ((Object)(object)val3 == (Object)null)
				{
					((MelonBase)this).LoggerInstance.Msg("no hip and no camera, nowhere to poop from");
					return;
				}
				val = ((Component)val3).transform.position + ((Component)val3).transform.forward * 1.5f;
				val2 = ((Component)val3).transform.forward * 4f;
				((MelonBase)this).LoggerInstance.Msg("no rigidbody with '" + _bonePref.Value + "' in the name, pooping out of the camera instead");
			}
			GameObject val4 = new GameObject("Poop");
			val4.layer = _layer;
			val4.transform.position = val;
			val4.transform.rotation = Quaternion.Euler(0f, Random.Range(0f, 360f), 0f);
			val4.transform.localScale = Vector3.one * _scale.Value;
			val4.AddComponent<MeshFilter>().sharedMesh = _poopMesh;
			MeshRenderer val5 = val4.AddComponent<MeshRenderer>();
			((Renderer)val5).sharedMaterial = _poopMat;
			((Renderer)val5).shadowCastingMode = (ShadowCastingMode)1;
			((Renderer)val5).receiveShadows = true;
			CapsuleCollider val6 = val4.AddComponent<CapsuleCollider>();
			val6.direction = 1;
			val6.radius = 0.12f;
			val6.height = 0.3f;
			val6.center = new Vector3(0f, 0.15f, 0f);
			Rigidbody val7 = val4.AddComponent<Rigidbody>();
			val7.mass = 0.5f;
			val7.drag = 0.1f;
			val7.collisionDetectionMode = (CollisionDetectionMode)1;
			val7.velocity = val2;
			val7.angularVelocity = Random.insideUnitSphere * 6f;
			Rigidbody[] body = _body;
			for (int i = 0; i < body.Length; i++)
			{
				foreach (Collider componentsInChild in ((Component)body[i]).GetComponentsInChildren<Collider>())
				{
					Physics.IgnoreCollision((Collider)(object)val6, componentsInChild, true);
				}
			}
			if (_launch.Value > 0f)
			{
				body = _body;
				for (int i = 0; i < body.Length; i++)
				{
					body[i].AddForce(Vector3.up * _launch.Value, (ForceMode)2);
				}
			}
			PoopAudio.Play(_sfx, 1f, 1f);
			_turds.Add(new Turd
			{
				go = val4,
				rb = val7,
				col = (Collider)(object)val6,
				mr = (Renderer)(object)val5,
				born = Time.time,
				lastVel = val2
			});
			if (_debugCube.Value)
			{
				SpawnTestCubes(val);
			}
		}

		private void SpawnTestCubes(Vector3 at)
		{
			//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_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: 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_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: 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_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			GameObject obj = GameObject.CreatePrimitive((PrimitiveType)3);
			((Object)obj).name = "PoopTestCube_MyMaterial";
			obj.layer = _layer;
			obj.transform.position = at + Vector3.up * 1.2f + Vector3.left * 0.4f;
			obj.transform.localScale = Vector3.one * 0.35f;
			obj.GetComponent<Renderer>().sharedMaterial = _poopMat;
			Object.Destroy((Object)(object)obj, 6f);
			GameObject obj2 = GameObject.CreatePrimitive((PrimitiveType)3);
			((Object)obj2).name = "PoopTestCube_UnityMaterial";
			obj2.layer = _layer;
			obj2.transform.position = at + Vector3.up * 1.2f + Vector3.right * 0.4f;
			obj2.transform.localScale = Vector3.one * 0.35f;
			Object.Destroy((Object)(object)obj2, 6f);
			Material sharedMaterial = obj2.GetComponent<Renderer>().sharedMaterial;
			((MelonBase)this).LoggerInstance.Msg("test cubes up. unity's default material = " + (((Object)(object)sharedMaterial == (Object)null) ? "NULL" : (((Object)sharedMaterial).name + " / " + ((Object)sharedMaterial.shader).name)));
		}

		private void FindButt()
		{
			if ((Object)(object)_butt != (Object)null || Time.time < _nextButtSearch)
			{
				return;
			}
			_nextButtSearch = Time.time + 2f;
			string value = _bonePref.Value.ToLowerInvariant();
			List<Rigidbody> list = new List<Rigidbody>();
			foreach (Rigidbody item in Object.FindObjectsOfType<Rigidbody>())
			{
				if (((Object)item).name.ToLowerInvariant().Contains(value))
				{
					list.Add(item);
				}
			}
			if (list.Count != 0)
			{
				Rigidbody val = PickMine(list);
				_butt = ((Component)val).transform;
				_body = Ragdoll(val);
				((MelonBase)this).LoggerInstance.Msg($"{list.Count} characters, using '{((Object)((Component)val).transform.root).name}' as me ({_body.Length} bodies)");
			}
		}

		private Rigidbody PickMine(List<Rigidbody> hips)
		{
			int value = _actorIndex.Value;
			if (value >= 0 && value < hips.Count)
			{
				((MelonBase)this).LoggerInstance.Msg($"ActorIndex forced to {value}");
				return hips[value];
			}
			foreach (Rigidbody hip in hips)
			{
				if (LocalFlags.SaysLocal(((Component)hip).transform.root))
				{
					return hip;
				}
			}
			Rigidbody val = null;
			int num = int.MaxValue;
			foreach (Rigidbody hip2 in hips)
			{
				PlayerInput val2 = null;
				try
				{
					val2 = ((Component)hip2).GetComponentInParent<PlayerInput>();
				}
				catch
				{
				}
				if (!((Object)(object)val2 == (Object)null) && val2.playerIndex < num)
				{
					num = val2.playerIndex;
					val = hip2;
				}
			}
			if ((Object)(object)val != (Object)null)
			{
				return val;
			}
			((MelonBase)this).LoggerInstance.Warning("couldnt tell which character is you, using the first one. set ActorIndex in the cfg to force it");
			return hips[0];
		}

		private static Rigidbody[] Ragdoll(Rigidbody start)
		{
			Dictionary<int, Rigidbody> byId = new Dictionary<int, Rigidbody>();
			Dictionary<int, List<int>> links = new Dictionary<int, List<int>>();
			foreach (Joint item in Object.FindObjectsOfType<Joint>())
			{
				Rigidbody component = ((Component)item).GetComponent<Rigidbody>();
				Rigidbody connectedBody = item.connectedBody;
				if (!((Object)(object)component == (Object)null) && !((Object)(object)connectedBody == (Object)null))
				{
					Link(component, connectedBody);
					Link(connectedBody, component);
				}
			}
			HashSet<int> hashSet = new HashSet<int>();
			Queue<int> queue = new Queue<int>();
			List<Rigidbody> list = new List<Rigidbody>();
			int instanceID = ((Object)start).GetInstanceID();
			byId[instanceID] = start;
			queue.Enqueue(instanceID);
			hashSet.Add(instanceID);
			while (queue.Count > 0)
			{
				int key = queue.Dequeue();
				list.Add(byId[key]);
				if (!links.TryGetValue(key, out var value))
				{
					continue;
				}
				foreach (int item2 in value)
				{
					if (hashSet.Add(item2))
					{
						queue.Enqueue(item2);
					}
				}
			}
			return list.ToArray();
			void Link(Rigidbody a, Rigidbody b)
			{
				int instanceID2 = ((Object)a).GetInstanceID();
				int instanceID3 = ((Object)b).GetInstanceID();
				byId[instanceID2] = a;
				byId[instanceID3] = b;
				if (!links.TryGetValue(instanceID2, out var value2))
				{
					value2 = (links[instanceID2] = new List<int>());
				}
				value2.Add(instanceID3);
			}
		}

		private static Camera MainCam()
		{
			Camera main = Camera.main;
			if ((Object)(object)main != (Object)null && ((Behaviour)main).enabled)
			{
				return main;
			}
			Camera val = null;
			foreach (Camera item in (Il2CppArrayBase<Camera>)(object)Camera.allCameras)
			{
				if (!((Object)(object)item == (Object)null) && ((Behaviour)item).enabled && !((Object)(object)item.targetTexture != (Object)null) && ((Object)(object)val == (Object)null || item.depth > val.depth))
				{
					val = item;
				}
			}
			return val;
		}

		private int PickLayer()
		{
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00fa: 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_00c7: Unknown result type (might be due to invalid IL or missing references)
			if (_layerOverride.Value >= 0 && _layerOverride.Value < 32)
			{
				((MelonBase)this).LoggerInstance.Msg($"LayerOverride = {_layerOverride.Value} ({LayerMask.LayerToName(_layerOverride.Value)})");
				return _layerOverride.Value;
			}
			Camera val = MainCam();
			int num = (((Object)(object)val != (Object)null) ? val.cullingMask : (-1));
			int num2 = -1;
			RaycastHit val2 = default(RaycastHit);
			if (Physics.Raycast((((Object)(object)_butt != (Object)null) ? _butt.position : (((Object)(object)val != (Object)null) ? ((Component)val).transform.position : Vector3.zero)) + Vector3.up * 0.5f, Vector3.down, ref val2, 30f, -1, (QueryTriggerInteraction)1))
			{
				num2 = ((Component)((RaycastHit)(ref val2)).collider).gameObject.layer;
			}
			int num3 = ((_body.Length != 0) ? ((Component)_body[0]).gameObject.layer : (-1));
			int donorLayer = PoopLook.DonorLayer;
			List<int> list = new List<int> { donorLayer, 0 };
			for (int i = 1; i < 32; i++)
			{
				if (!list.Contains(i))
				{
					list.Add(i);
				}
			}
			int num4 = 0;
			int num5 = int.MinValue;
			foreach (int item in list)
			{
				if ((num & (1 << item)) != 0)
				{
					int num6 = 0;
					if (num2 >= 0 && !Physics.GetIgnoreLayerCollision(item, num2))
					{
						num6 += 2;
					}
					if (num3 >= 0 && !Physics.GetIgnoreLayerCollision(item, num3))
					{
						num6++;
					}
					if (num6 > num5)
					{
						num5 = num6;
						num4 = item;
					}
					if (num6 == 3)
					{
						break;
					}
				}
			}
			((MelonBase)this).LoggerInstance.Msg($"camera '{(Object.op_Implicit((Object)(object)val) ? ((Object)val).name : "none")}' mask 0x{num:X8}, ground layer {num2}, actor layer {num3}, donor layer {donorLayer}");
			((MelonBase)this).LoggerInstance.Msg($"poop goes on layer {num4} ({LayerMask.LayerToName(num4)}), camera draws it = {(num & (1 << num4)) != 0}");
			if (num5 < 0)
			{
				((MelonBase)this).LoggerInstance.Warning("no layer is in the camera mask at all?! set LayerOverride manually");
			}
			return num4;
		}

		private void Diagnose(Turd t)
		{
			//IL_000c: 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_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_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			Camera val = MainCam();
			Bounds bounds = t.mr.bounds;
			float value = (((Object)(object)val != (Object)null) ? Vector3.Distance(((Component)val).transform.position, ((Bounds)(ref bounds)).center) : (-1f));
			((MelonBase)this).LoggerInstance.Msg("---- visibility check ----");
			((MelonBase)this).LoggerInstance.Msg($"renderer.isVisible = {t.mr.isVisible}   enabled = {t.mr.enabled}   layer = {t.go.layer} ({LayerMask.LayerToName(t.go.layer)})");
			((MelonBase)this).LoggerInstance.Msg($"bounds centre {((Bounds)(ref bounds)).center} size {((Bounds)(ref bounds)).size}   {value:0.0}m from camera '{(Object.op_Implicit((Object)(object)val) ? ((Object)val).name : "none")}'");
			if ((Object)(object)val != (Object)null)
			{
				((MelonBase)this).LoggerInstance.Msg($"camera near/far {val.nearClipPlane}/{val.farClipPlane}, mask bit set = {(val.cullingMask & (1 << t.go.layer)) != 0}");
			}
			((MelonBase)this).LoggerInstance.Msg($"material '{((Object)t.mr.sharedMaterial).name}' shader '{((Object)t.mr.sharedMaterial.shader).name}' queue {t.mr.sharedMaterial.renderQueue} keywords [{PoopLook.Keywords(t.mr.sharedMaterial)}]");
			((MelonBase)this).LoggerInstance.Msg("pipeline " + PoopLook.PipelineName + ". on URP the shader must start with 'Universal Render Pipeline/' or it only casts a shadow");
		}

		private void TickTurds()
		{
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			float time = Time.time;
			for (int num = _turds.Count - 1; num >= 0; num--)
			{
				Turd turd = _turds[num];
				if ((Object)(object)turd.go == (Object)null)
				{
					_turds.RemoveAt(num);
				}
				else
				{
					if (!_diagDone && time - turd.born > 0.5f)
					{
						_diagDone = true;
						try
						{
							Diagnose(turd);
						}
						catch (Exception ex)
						{
							((MelonBase)this).LoggerInstance.Error("diag failed: " + ex.Message);
						}
					}
					if (time - turd.born > _poopSecs.Value)
					{
						Object.Destroy((Object)(object)turd.go);
						_turds.RemoveAt(num);
					}
					else if (!(time - turd.lastSplat < 0.2f))
					{
						Vector3 val = turd.go.transform.position + Vector3.up * 0.15f * _scale.Value;
						Vector3 val2 = val - turd.lastSplatPos;
						if (!(((Vector3)(ref val2)).sqrMagnitude < 0.0009f))
						{
							val2 = turd.rb.velocity;
							if (!Poke(turd, val, ((Vector3)(ref val2)).normalized))
							{
								for (int i = 0; i < Feelers.Length && !Poke(turd, val, Feelers[i]); i++)
								{
								}
							}
						}
					}
				}
			}
		}

		private bool Poke(Turd t, Vector3 from, Vector3 dir)
		{
			//IL_0022: 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_0068: 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_007b: Unknown result type (might be due to invalid IL or missing references)
			if (((Vector3)(ref dir)).sqrMagnitude < 0.01f)
			{
				return false;
			}
			float num = 0.2f * _scale.Value;
			RaycastHit hit = default(RaycastHit);
			if (!Physics.Raycast(from, dir, ref hit, num, -1, (QueryTriggerInteraction)1))
			{
				return false;
			}
			if ((Object)(object)((RaycastHit)(ref hit)).collider == (Object)(object)t.col)
			{
				return false;
			}
			if (((Object)((Component)((RaycastHit)(ref hit)).collider).gameObject).name == "Poop")
			{
				return false;
			}
			Splat(hit);
			t.lastSplat = Time.time;
			t.lastSplatPos = from;
			return true;
		}

		private void Splat(RaycastHit hit)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_0058: 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_005e: 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_007c: 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_0081: 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_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_00aa: 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_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: 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)
			GameObject val = new GameObject("PoopSplat");
			val.layer = _layer;
			val.AddComponent<MeshFilter>().sharedMesh = _blobs[Random.Range(0, _blobs.Length)];
			MeshRenderer obj = val.AddComponent<MeshRenderer>();
			((Renderer)obj).sharedMaterial = _splatMat;
			((Renderer)obj).shadowCastingMode = (ShadowCastingMode)0;
			((Renderer)obj).receiveShadows = true;
			Vector3 normal = ((RaycastHit)(ref hit)).normal;
			Vector3 val2 = ((Mathf.Abs(Vector3.Dot(normal, Vector3.up)) > 0.95f) ? Vector3.forward : Vector3.up);
			val.transform.position = ((RaycastHit)(ref hit)).point + normal * 0.008f;
			val.transform.rotation = Quaternion.LookRotation(normal, val2) * Quaternion.Euler(0f, 0f, Random.Range(0f, 360f));
			float num = Random.Range(0.35f, 0.6f) * _scale.Value;
			val.transform.localScale = new Vector3(num, num, num);
			val.transform.SetParent(((RaycastHit)(ref hit)).transform, true);
			_stains.Add(new Stain
			{
				go = val,
				dies = Time.time + _splatSecs.Value
			});
		}

		private void TickStains()
		{
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			float time = Time.time;
			for (int num = _stains.Count - 1; num >= 0; num--)
			{
				Stain stain = _stains[num];
				if ((Object)(object)stain.go == (Object)null)
				{
					_stains.RemoveAt(num);
				}
				else
				{
					float num2 = stain.dies - time;
					if (num2 <= 0f)
					{
						Object.Destroy((Object)(object)stain.go);
						_stains.RemoveAt(num);
					}
					else if (num2 < 2f)
					{
						stain.go.transform.localScale = stain.go.transform.localScale * (1f - Time.deltaTime * 0.6f);
					}
				}
			}
		}

		private void BuildStuff()
		{
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: 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)
			string value = "mesh";
			try
			{
				if ((Object)(object)_poopMesh == (Object)null)
				{
					_poopMesh = PoopMesh.BuildSwirl();
				}
				if (_blobs == null)
				{
					_blobs = (Mesh[])(object)new Mesh[6];
					for (int i = 0; i < _blobs.Length; i++)
					{
						_blobs[i] = PoopMesh.BuildBlob(i * 17 + 3);
					}
				}
				Instance loggerInstance = ((MelonBase)this).LoggerInstance;
				DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(28, 3);
				defaultInterpolatedStringHandler.AppendLiteral("mesh ");
				defaultInterpolatedStringHandler.AppendFormatted(_poopMesh.vertexCount);
				defaultInterpolatedStringHandler.AppendLiteral(" verts / ");
				defaultInterpolatedStringHandler.AppendFormatted(((Il2CppArrayBase<int>)(object)_poopMesh.triangles).Length / 3);
				defaultInterpolatedStringHandler.AppendLiteral(" tris, bounds ");
				Bounds bounds = _poopMesh.bounds;
				defaultInterpolatedStringHandler.AppendFormatted<Vector3>(((Bounds)(ref bounds)).size);
				loggerInstance.Msg(defaultInterpolatedStringHandler.ToStringAndClear());
				value = "prefs";
				PoopLook.ShaderOverride = ((_shaderOverride != null) ? (_shaderOverride.Value ?? "") : "");
				PoopLook.Mode = ((_matMode != null) ? (_matMode.Value ?? "Auto") : "Auto");
				((MelonBase)this).LoggerInstance.Msg($"render pipeline: {PoopLook.PipelineName} (urp = {PoopLook.IsUrp}), material mode {PoopLook.Mode}");
				value = "poop material";
				_poopMat = PoopLook.PoopMaterial();
				if ((Object)(object)_poopMat == (Object)null)
				{
					throw new Exception("PoopMaterial returned null");
				}
				value = "splat material";
				_splatMat = PoopLook.SplatMaterial();
				if ((Object)(object)_splatMat == (Object)null)
				{
					throw new Exception("SplatMaterial returned null");
				}
				value = "layer";
				_layer = PickLayer();
				_built = true;
				((MelonBase)this).LoggerInstance.Msg($"material shader '{((Object)_poopMat.shader).name}', {_poopMat.passCount} passes, keywords [{PoopLook.Keywords(_poopMat)}]");
			}
			catch (Exception ex)
			{
				((MelonBase)this).LoggerInstance.Error($"BuildStuff died at stage '{value}': {ex.GetType().Name}: {ex.Message}");
				throw;
			}
		}
	}
}