Decompiled source of INeedToPEEak v0.2.0

plugins\INeedToPEEak.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Peak.Afflictions;
using Photon.Pun;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using Zorro.Core;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("INeedToPEEak")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.2.0.0")]
[assembly: AssemblyInformationalVersion("0.2.0+8299ed7b503e268794e15674a51a62af9883aea3")]
[assembly: AssemblyProduct("INeedToPEEak")]
[assembly: AssemblyTitle("INeedToPEEak")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.2.0.0")]
[module: UnverifiableCode]
[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 INeedToPEEak
{
	internal static class BathroomAssets
	{
		private static Material _pooMaterial;

		private static Material _paperMaterial;

		private static Material _puddleMaterial;

		private static readonly Color PooBrown = new Color(0.38f, 0.23f, 0.06f);

		private static readonly Color PooBrownDark = new Color(0.27f, 0.16f, 0.04f);

		private static readonly Color PeeYellow = new Color(0.95f, 0.87f, 0.25f);

		private static readonly Color PaperWhite = new Color(0.95f, 0.95f, 0.92f);

		public static Sprite PooIcon { get; private set; }

		public static Sprite PeeIcon { get; private set; }

		public static Sprite DirtyIcon { get; private set; }

		public static Sprite StinkIcon { get; private set; }

		public static Texture2D PooItemIcon { get; private set; }

		public static Texture2D ToiletPaperItemIcon { get; private set; }

		public static Material PooMaterial
		{
			get
			{
				//IL_000d: Unknown result type (might be due to invalid IL or missing references)
				if (!((Object)(object)_pooMaterial != (Object)null))
				{
					return _pooMaterial = MakeMaterial(PooBrown, transparent: false);
				}
				return _pooMaterial;
			}
		}

		public static Material PaperMaterial
		{
			get
			{
				//IL_000d: Unknown result type (might be due to invalid IL or missing references)
				if (!((Object)(object)_paperMaterial != (Object)null))
				{
					return _paperMaterial = MakeMaterial(PaperWhite, transparent: false);
				}
				return _paperMaterial;
			}
		}

		public static Material PuddleMaterial
		{
			get
			{
				//IL_0030: Unknown result type (might be due to invalid IL or missing references)
				if (!((Object)(object)_puddleMaterial != (Object)null))
				{
					return _puddleMaterial = MakeMaterial(new Color(PeeYellow.r, PeeYellow.g, PeeYellow.b, 0.62f), transparent: true);
				}
				return _puddleMaterial;
			}
		}

		public static void CreateAll()
		{
			PooIcon = MakeSprite(DrawPooIcon(64));
			PeeIcon = MakeSprite(DrawDropIcon(64));
			DirtyIcon = MakeSprite(DrawDirtIcon(64));
			StinkIcon = MakeSprite(DrawStinkIcon(64));
			PooItemIcon = DrawPooIcon(128);
			ToiletPaperItemIcon = DrawToiletPaperIcon(128);
		}

		private static Material MakeMaterial(Color color, bool transparent)
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Expected O, but got Unknown
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			Shader val = Shader.Find("Universal Render Pipeline/Lit");
			if ((Object)(object)val == (Object)null)
			{
				val = Shader.Find("Universal Render Pipeline/Simple Lit");
			}
			if ((Object)(object)val == (Object)null)
			{
				val = Shader.Find("Standard");
			}
			if ((Object)(object)val == (Object)null)
			{
				val = Shader.Find("Sprites/Default");
			}
			Material val2 = new Material(val)
			{
				color = color
			};
			if (val2.HasProperty("_BaseColor"))
			{
				val2.SetColor("_BaseColor", color);
			}
			if (val2.HasProperty("_Smoothness"))
			{
				val2.SetFloat("_Smoothness", transparent ? 0.9f : 0.25f);
			}
			if (transparent)
			{
				if (val2.HasProperty("_Surface"))
				{
					val2.SetFloat("_Surface", 1f);
				}
				if (val2.HasProperty("_Blend"))
				{
					val2.SetFloat("_Blend", 0f);
				}
				val2.SetOverrideTag("RenderType", "Transparent");
				if (val2.HasProperty("_SrcBlend"))
				{
					val2.SetFloat("_SrcBlend", 5f);
				}
				if (val2.HasProperty("_DstBlend"))
				{
					val2.SetFloat("_DstBlend", 10f);
				}
				if (val2.HasProperty("_ZWrite"))
				{
					val2.SetFloat("_ZWrite", 0f);
				}
				val2.DisableKeyword("_ALPHATEST_ON");
				val2.EnableKeyword("_SURFACE_TYPE_TRANSPARENT");
				val2.renderQueue = 3000;
			}
			Object.DontDestroyOnLoad((Object)(object)val2);
			return val2;
		}

		private static Sprite MakeSprite(Texture2D tex)
		{
			//IL_0019: 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)
			Sprite obj = Sprite.Create(tex, new Rect(0f, 0f, (float)((Texture)tex).width, (float)((Texture)tex).height), new Vector2(0.5f, 0.5f), (float)((Texture)tex).width);
			Object.DontDestroyOnLoad((Object)(object)obj);
			return obj;
		}

		private static Texture2D NewTexture(int size)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(size, size, (TextureFormat)4, false)
			{
				wrapMode = (TextureWrapMode)1
			};
			Color val2 = default(Color);
			((Color)(ref val2))..ctor(0f, 0f, 0f, 0f);
			Color[] array = (Color[])(object)new Color[size * size];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = val2;
			}
			val.SetPixels(array);
			Object.DontDestroyOnLoad((Object)(object)val);
			return val;
		}

		private static void FillCircle(Texture2D tex, float cx, float cy, float r, Color color)
		{
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			int width = ((Texture)tex).width;
			int num = Mathf.Max(0, Mathf.FloorToInt(cx - r));
			int num2 = Mathf.Min(width - 1, Mathf.CeilToInt(cx + r));
			int num3 = Mathf.Max(0, Mathf.FloorToInt(cy - r));
			int num4 = Mathf.Min(width - 1, Mathf.CeilToInt(cy + r));
			for (int i = num3; i <= num4; i++)
			{
				for (int j = num; j <= num2; j++)
				{
					float num5 = (float)j - cx;
					float num6 = (float)i - cy;
					if (num5 * num5 + num6 * num6 <= r * r)
					{
						tex.SetPixel(j, i, color);
					}
				}
			}
		}

		private static Texture2D DrawPooIcon(int s)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: 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_0125: 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_0165: Unknown result type (might be due to invalid IL or missing references)
			Texture2D obj = NewTexture(s);
			float num = (float)s / 64f;
			FillCircle(obj, 32f * num, 14f * num, 17f * num, PooBrownDark);
			FillCircle(obj, 32f * num, 14f * num, 15f * num, PooBrown);
			FillCircle(obj, 32f * num, 30f * num, 13f * num, PooBrownDark);
			FillCircle(obj, 32f * num, 30f * num, 11f * num, PooBrown);
			FillCircle(obj, 32f * num, 44f * num, 9f * num, PooBrownDark);
			FillCircle(obj, 32f * num, 44f * num, 7f * num, PooBrown);
			FillCircle(obj, 34f * num, 52f * num, 4f * num, PooBrown);
			FillCircle(obj, 26f * num, 18f * num, 3.4f * num, Color.white);
			FillCircle(obj, 38f * num, 18f * num, 3.4f * num, Color.white);
			FillCircle(obj, 26f * num, 18f * num, 1.6f * num, Color.black);
			FillCircle(obj, 38f * num, 18f * num, 1.6f * num, Color.black);
			obj.Apply();
			return obj;
		}

		private static Texture2D DrawDropIcon(int s)
		{
			//IL_002e: 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_006a: Unknown result type (might be due to invalid IL or missing references)
			Texture2D obj = NewTexture(s);
			float num = (float)s / 64f;
			Color color = default(Color);
			((Color)(ref color))..ctor(0.55f, 0.45f, 0.05f);
			DrawDropShape(obj, num, 2f * num, color);
			DrawDropShape(obj, num, 0f, PeeYellow);
			FillCircle(obj, 26f * num, 22f * num, 3.4f * num, new Color(1f, 1f, 0.88f));
			obj.Apply();
			return obj;
		}

		private static void DrawDropShape(Texture2D tex, float u, float grow, Color color)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			FillCircle(tex, 32f * u, 21f * u, 14f * u + grow, color);
			for (int i = 0; i <= 56; i++)
			{
				float num = (float)i / 56f;
				float num2 = Mathf.Lerp(21f, 57f, num);
				float num3 = Mathf.Lerp(14f, 0.5f, Mathf.Pow(num, 1.15f));
				FillCircle(tex, 32f * u, num2 * u, num3 * u + grow, color);
			}
		}

		private static Texture2D DrawDirtIcon(int s)
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = NewTexture(s);
			float num = (float)s / 64f;
			Color color = default(Color);
			((Color)(ref color))..ctor(0.62f, 0.62f, 0.6f);
			Color color2 = default(Color);
			((Color)(ref color2))..ctor(0.42f, 0.42f, 0.4f);
			FillCircle(val, 32f * num, 30f * num, 15f * num, color2);
			FillCircle(val, 32f * num, 30f * num, 13f * num, color);
			float[,] array = new float[6, 3]
			{
				{ 14f, 44f, 5f },
				{ 50f, 42f, 6f },
				{ 20f, 14f, 5f },
				{ 46f, 16f, 4f },
				{ 55f, 28f, 3f },
				{ 9f, 28f, 3.5f }
			};
			for (int i = 0; i < array.GetLength(0); i++)
			{
				FillCircle(val, array[i, 0] * num, array[i, 1] * num, (array[i, 2] + 1.2f) * num, color2);
				FillCircle(val, array[i, 0] * num, array[i, 1] * num, array[i, 2] * num, color);
			}
			val.Apply();
			return val;
		}

		private static Texture2D DrawStinkIcon(int s)
		{
			//IL_009f: 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)
			Texture2D val = NewTexture(s);
			float num = (float)s / 64f;
			Color color = default(Color);
			((Color)(ref color))..ctor(0.72f, 0.78f, 0.28f);
			Color color2 = default(Color);
			((Color)(ref color2))..ctor(0.45f, 0.5f, 0.14f);
			for (int i = 0; i < 3; i++)
			{
				float num2 = (float)(18 + i * 14) * num;
				for (int j = 0; j <= 40; j++)
				{
					float num3 = (float)j / 40f;
					float cy = (10f + num3 * 44f) * num;
					float cx = num2 + Mathf.Sin(num3 * MathF.PI * 2.5f) * 4.5f * num;
					FillCircle(val, cx, cy, 3.4f * num, color2);
					FillCircle(val, cx, cy, 2.4f * num, color);
				}
			}
			val.Apply();
			return val;
		}

		private static Texture2D DrawToiletPaperIcon(int s)
		{
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: 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_0041: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = NewTexture(s);
			float num = (float)s / 128f;
			Color color = default(Color);
			((Color)(ref color))..ctor(0.65f, 0.65f, 0.62f);
			for (int i = (int)(8f * num); i < (int)(64f * num); i++)
			{
				for (int j = (int)(78f * num); j < (int)(104f * num); j++)
				{
					val.SetPixel(j, i, PaperWhite);
				}
			}
			FillCircle(val, 64f * num, 74f * num, 42f * num, color);
			FillCircle(val, 64f * num, 74f * num, 39f * num, PaperWhite);
			FillCircle(val, 64f * num, 74f * num, 15f * num, color);
			FillCircle(val, 64f * num, 74f * num, 12f * num, new Color(0.8f, 0.75f, 0.68f));
			val.Apply();
			return val;
		}
	}
	internal static class BathroomCleanup
	{
		private static readonly List<GameObject> Poos = new List<GameObject>();

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

		public static void RegisterPoo(GameObject go)
		{
			Enforce(Poos, go, BathroomConfig.MaxPoos.Value);
		}

		public static void RegisterPuddle(GameObject go)
		{
			Enforce(Puddles, go, BathroomConfig.MaxPuddles.Value);
		}

		private static void Enforce(List<GameObject> list, GameObject go, int max)
		{
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)go != (Object)null)
			{
				list.Add(go);
			}
			list.RemoveAll((GameObject g) => (Object)(object)g == (Object)null);
			if (max <= 0)
			{
				return;
			}
			int num = 0;
			while (num < list.Count && list.Count > max)
			{
				GameObject val = list[num];
				PhotonView component = val.GetComponent<PhotonView>();
				if ((Object)(object)component == (Object)null || !component.IsMine)
				{
					list.RemoveAt(num);
					continue;
				}
				Item component2 = val.GetComponent<Item>();
				if ((Object)(object)component2 != (Object)null && (int)component2.itemState != 0)
				{
					num++;
					continue;
				}
				list.RemoveAt(num);
				PhotonNetwork.Destroy(val);
			}
		}
	}
	public enum BathroomDifficulty
	{
		Gentle,
		Normal,
		Rough,
		Brutal
	}
	public enum ToiletPaperWipes
	{
		Three = 3,
		Five = 5,
		Seven = 7
	}
	internal static class BathroomConfig
	{
		public static ConfigEntry<KeyCode> PooKey;

		public static ConfigEntry<KeyCode> PeeKey;

		public static ConfigEntry<BathroomDifficulty> Difficulty;

		public static ConfigEntry<bool> ToiletPaperReplacesLuggageItem;

		public static ConfigEntry<bool> EnableDirty;

		public static ConfigEntry<bool> EnableStink;

		public static ConfigEntry<float> PooFromFoodRatio;

		public static ConfigEntry<float> PeeFromDrinkRatio;

		public static ConfigEntry<float> PeeFallbackPerDrink;

		public static ConfigEntry<float> PeeGainCap;

		public static ConfigEntry<float> ActionThreshold;

		public static ConfigEntry<float> SecondsPerFullBar;

		public static ConfigEntry<float> MovementEpsilon;

		public static ConfigEntry<float> PeeDrainPerSecond;

		public static ConfigEntry<float> PooMoveSpeedMultiplier;

		public static ConfigEntry<float> PooBaseDiameter;

		public static ConfigEntry<float> PooCarryStink;

		public static ConfigEntry<float> EatTimeRatio;

		public static ConfigEntry<float> EatPoisonRatio;

		public static ConfigEntry<float> DirtyPerPoo;

		public static ConfigEntry<float> DirtyPerWipe;

		public static ConfigEntry<ToiletPaperWipes> ToiletPaperUses;

		public static ConfigEntry<float> TPChanceBigLuggage;

		public static ConfigEntry<float> TPChanceExplorerLuggage;

		public static ConfigEntry<bool> GiveStartingToiletPaper;

		public static ConfigEntry<float> PuddleMaxDiameter;

		public static ConfigEntry<float> PuddleFullAmount;

		public static ConfigEntry<float> PuddleLifetime;

		public static ConfigEntry<int> MaxPoos;

		public static ConfigEntry<int> MaxPuddles;

		public static ConfigEntry<bool> SkeletonsDontGoToBathroom;

		public static ConfigEntry<bool> CureAllRemovesPooPee;

		public static ConfigEntry<bool> PandoraRollsPooPee;

		public static ConfigEntry<float> PandoraPooPeeChance;

		public static ConfigEntry<int> ToiletPaperItemID;

		public static ConfigEntry<int> PooItemID;

		public static int ToiletPaperUseCount => (int)ToiletPaperUses.Value;

		public static float EffectScale
		{
			get
			{
				if (Difficulty == null)
				{
					return 1f;
				}
				return Difficulty.Value switch
				{
					BathroomDifficulty.Gentle => 0.5f, 
					BathroomDifficulty.Rough => 1.5f, 
					BathroomDifficulty.Brutal => 2f, 
					_ => 1f, 
				};
			}
		}

		private static ConfigDescription Hidden(string description)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			return new ConfigDescription(description, (AcceptableValueBase)null, new object[1] { "Hidden" });
		}

		public static void Bind(ConfigFile cfg)
		{
			PooKey = cfg.Bind<KeyCode>("Input", "PooKey", (KeyCode)107, "Key held to poo.");
			PeeKey = cfg.Bind<KeyCode>("Input", "PeeKey", (KeyCode)108, "Key held to pee.");
			Difficulty = cfg.Bind<BathroomDifficulty>("General", "Difficulty", BathroomDifficulty.Normal, "How strongly bathroom needs affect you. Scales poo/pee build-up, dirtiness, stink and poo poisoning. Gentle = half, Rough = 1.5x, Brutal = double.");
			EnableDirty = cfg.Bind<bool>("General", "EnableDirty", true, Hidden("Get Dirty after pooping (cured with toilet paper). Turn off if you don't want to depend on finding toilet paper."));
			EnableStink = cfg.Bind<bool>("General", "EnableStink", true, Hidden("Carrying a poo makes you Stink. Turn off to carry poos with no penalty."));
			ToiletPaperReplacesLuggageItem = cfg.Bind<bool>("ToiletPaper", "ReplacesALuggageItem", false, "ON: toilet paper takes the place of one item the luggage rolled, keeping its item count the same (that item is destroyed, which can eat items added by other mods). OFF: toilet paper is added alongside the normal loot and nothing is removed.");
			TPChanceExplorerLuggage = cfg.Bind<float>("ToiletPaper", "ChanceExplorerLuggage", 0.25f, "Chance (0-1) an Explorer's Luggage contains toilet paper.");
			TPChanceBigLuggage = cfg.Bind<float>("ToiletPaper", "ChanceBigLuggage", 0.03f, "Chance (0-1) a Big Luggage contains toilet paper.");
			ToiletPaperUses = cfg.Bind<ToiletPaperWipes>("ToiletPaper", "UsesPerRoll", ToiletPaperWipes.Five, "Wipes per toilet paper roll. Raise this for bigger groups.");
			GiveStartingToiletPaper = cfg.Bind<bool>("ToiletPaper", "GiveStartingRoll", true, "One random player starts the run with a toilet paper roll.");
			PooFromFoodRatio = cfg.Bind<float>("Gain", "PooFromFoodRatio", 0.5f, Hidden("Fraction of the hunger a food cures that is added as Poo."));
			PeeFromDrinkRatio = cfg.Bind<float>("Gain", "PeeFromDrinkRatio", 0.5f, Hidden("Fraction of the statuses a drink cures that is added as Pee."));
			PeeFallbackPerDrink = cfg.Bind<float>("Gain", "PeeFallbackPerDrink", 0.15f, Hidden("Pee added by a drink that cures no statuses at all."));
			PeeGainCap = cfg.Bind<float>("Gain", "PeeGainCap", 0.5f, Hidden("Maximum Pee a single drink can add (some drinks cure huge amounts)."));
			ActionThreshold = cfg.Bind<float>("Actions", "ActionThreshold", 1f / 3f, Hidden("Minimum fill (fraction of the stamina bar) of Poo/Pee before you can relieve yourself."));
			SecondsPerFullBar = cfg.Bind<float>("Actions", "SecondsPerFullBar", 10f, Hidden("Seconds it takes to poo a FULL bar. 33% poo => ~3.3s, 85% => 8.5s. Pee drains at the same rate."));
			MovementEpsilon = cfg.Bind<float>("Actions", "MovementEpsilon", 0.35f, Hidden("Velocity above which you no longer count as standing still."));
			PeeDrainPerSecond = cfg.Bind<float>("Actions", "PeeDrainPerSecond", 0.1f, Hidden("Pee removed per second while peeing (0.1 = full bar in 10s)."));
			PooMoveSpeedMultiplier = cfg.Bind<float>("Actions", "PooMoveSpeedMultiplier", 0.25f, Hidden("Movement force multiplier while pooping (stacks with the 50% crouch penalty)."));
			PooBaseDiameter = cfg.Bind<float>("PooItem", "PooBaseDiameter", 0.35f, Hidden("World diameter of a default (33%) poo. Roughly half a Bing Bong."));
			PooCarryStink = cfg.Bind<float>("PooItem", "PooCarryStink", 0.1f, Hidden("Stink status per poo carried (hands or main three slots); removed when dropped. Stacks per poo."));
			EatTimeRatio = cfg.Bind<float>("PooItem", "EatTimeRatio", 0.5f, Hidden("Eating a poo takes its poo-time multiplied by this (default: half)."));
			EatPoisonRatio = cfg.Bind<float>("PooItem", "EatPoisonRatio", 0.5f, Hidden("Poison given when eating a poo = original poo amount times this."));
			DirtyPerPoo = cfg.Bind<float>("Dirty", "DirtyPerPoo", 0.05f, Hidden("Dirty status applied after pooping."));
			DirtyPerWipe = cfg.Bind<float>("Dirty", "DirtyPerWipe", 0.05f, Hidden("Dirty status removed per toilet paper wipe."));
			PuddleMaxDiameter = cfg.Bind<float>("Puddle", "PuddleMaxDiameter", 1.2f, Hidden("Maximum pee puddle diameter (about a beached jellyfish)."));
			PuddleFullAmount = cfg.Bind<float>("Puddle", "PuddleFullAmount", 1f, Hidden("Amount of pee (bar fraction) that grows a puddle to maximum size."));
			PuddleLifetime = cfg.Bind<float>("Puddle", "PuddleLifetime", 0f, Hidden("Seconds before a puddle dries up. 0 = never."));
			MaxPoos = cfg.Bind<int>("Performance", "MaxPoos", 40, Hidden("Most poos allowed to exist at once (oldest on the ground is removed past this). 0 = unlimited."));
			MaxPuddles = cfg.Bind<int>("Performance", "MaxPuddles", 20, Hidden("Most of your own pee puddles allowed at once (oldest is removed past this). 0 = unlimited."));
			SkeletonsDontGoToBathroom = cfg.Bind<bool>("Interactions", "SkeletonsDontGoToBathroom", true, Hidden("Skeletons (revived via the Book of Bones) don't gain Poo/Pee, just like they don't get hungry."));
			CureAllRemovesPooPee = cfg.Bind<bool>("Interactions", "CureAllRemovesPooPee", true, Hidden("Cure-All (and other 'clear all status' items) also remove Poo and Pee."));
			PandoraRollsPooPee = cfg.Bind<bool>("Interactions", "PandoraRollsPooPee", true, Hidden("Pandora's Lunchbox clears Poo/Pee and can randomly re-roll them like other statuses."));
			PandoraPooPeeChance = cfg.Bind<float>("Interactions", "PandoraPooPeeChance", 0.5f, Hidden("Chance (0-1) that Pandora's Lunchbox rolls each of Poo and Pee."));
			ToiletPaperItemID = cfg.Bind<int>("ItemIDs", "ToiletPaperItemID", 61001, Hidden("Item database ID for toilet paper. Must match on all players."));
			PooItemID = cfg.Bind<int>("ItemIDs", "PooItemID", 61002, Hidden("Item database ID for poo. Must match on all players."));
		}
	}
	internal static class BathroomItemInteractions
	{
		[HarmonyPatch(typeof(CharacterAfflictions), "ClearAllStatus")]
		private static class Patch_ClearAllStatusMethod
		{
			private static void Postfix(CharacterAfflictions __instance)
			{
				if (BathroomConfig.CureAllRemovesPooPee.Value)
				{
					RemovePooPee(__instance);
				}
			}
		}

		[HarmonyPatch(typeof(Action_ClearAllStatus), "RunAction")]
		private static class Patch_ClearAllStatusAction
		{
			private static void Prefix()
			{
				StatusGainPatches.SuppressHungerGain = true;
			}

			private static void Postfix(Action_ClearAllStatus __instance)
			{
				StatusGainPatches.SuppressHungerGain = false;
				if (BathroomConfig.CureAllRemovesPooPee.Value)
				{
					Item component = ((Component)__instance).GetComponent<Item>();
					Character val = (((Object)(object)component != (Object)null) ? component.holderCharacter : null);
					if ((Object)(object)val != (Object)null)
					{
						RemovePooPee(val.refs.afflictions);
					}
				}
			}
		}

		[HarmonyPatch(typeof(Affliction_Chaos), "OnApplied")]
		private static class Patch_Chaos
		{
			private static void Postfix(Affliction_Chaos __instance)
			{
				//IL_0049: 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)
				if (!BathroomConfig.PandoraRollsPooPee.Value)
				{
					return;
				}
				Character character = ((Affliction)__instance).character;
				if (!((Object)(object)character == (Object)null) && character.IsLocal)
				{
					float num = Mathf.Clamp01(BathroomConfig.PandoraPooPeeChance.Value);
					if (Random.value < num)
					{
						character.refs.afflictions.AddStatus(BathroomStatuses.Poo, Random.Range(0.1f, 0.6f), false, true, true);
					}
					if (Random.value < num)
					{
						character.refs.afflictions.AddStatus(BathroomStatuses.Pee, Random.Range(0.1f, 0.6f), false, true, true);
					}
				}
			}
		}

		private static void RemovePooPee(CharacterAfflictions afflictions)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)afflictions == (Object)null))
			{
				afflictions.SubtractStatus(BathroomStatuses.Poo, 5f, false, false);
				afflictions.SubtractStatus(BathroomStatuses.Pee, 5f, false, false);
			}
		}
	}
	internal static class BathroomItems
	{
		private class BathroomPrefabPool : IPunPrefabPool
		{
			private readonly IPunPrefabPool fallback;

			public BathroomPrefabPool(IPunPrefabPool fallback)
			{
				this.fallback = fallback;
			}

			public GameObject Instantiate(string prefabId, Vector3 position, Quaternion rotation)
			{
				//IL_001f: 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_0010: Unknown result type (might be due to invalid IL or missing references)
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				if (Prefabs.TryGetValue(prefabId, out var value))
				{
					return Object.Instantiate<GameObject>(value, position, rotation);
				}
				return fallback.Instantiate(prefabId, position, rotation);
			}

			public void Destroy(GameObject gameObject)
			{
				if ((Object)(object)gameObject != (Object)null && ((Object)(object)gameObject.GetComponent<PooItem>() != (Object)null || (Object)(object)gameObject.GetComponent<PeePuddle>() != (Object)null || (Object)(object)gameObject.GetComponent<ToiletPaperWipe>() != (Object)null))
				{
					Object.Destroy((Object)(object)gameObject);
				}
				else
				{
					fallback.Destroy(gameObject);
				}
			}
		}

		public const string PooPrefabName = "0_Items/INTP_Poo";

		public const string TPPrefabName = "0_Items/INTP_ToiletPaper";

		public const string PuddlePrefabName = "0_Items/INTP_PeePuddle";

		private static readonly Dictionary<string, GameObject> Prefabs = new Dictionary<string, GameObject>();

		private static GameObject pooPrefab;

		private static GameObject tpPrefab;

		private static GameObject puddlePrefab;

		private static Mesh sphereMesh;

		private static Mesh cylinderMesh;

		public static ushort PooItemID => (ushort)BathroomConfig.PooItemID.Value;

		public static ushort ToiletPaperItemID => (ushort)BathroomConfig.ToiletPaperItemID.Value;

		public static void Initialize()
		{
			CacheMeshes();
			pooPrefab = BuildPooPrefab();
			tpPrefab = BuildToiletPaperPrefab();
			puddlePrefab = BuildPuddlePrefab();
			Register("0_Items/INTP_Poo", pooPrefab);
			Register("0_Items/INTP_ToiletPaper", tpPrefab);
			Register("0_Items/INTP_PeePuddle", puddlePrefab);
			InstallPrefabPool();
		}

		private static void Register(string key, GameObject prefab)
		{
			Prefabs[key] = prefab;
			string key2 = key.Substring(key.LastIndexOf('/') + 1);
			Prefabs[key2] = prefab;
		}

		private static void CacheMeshes()
		{
			GameObject obj = GameObject.CreatePrimitive((PrimitiveType)0);
			sphereMesh = obj.GetComponent<MeshFilter>().sharedMesh;
			Object.Destroy((Object)(object)obj);
			GameObject obj2 = GameObject.CreatePrimitive((PrimitiveType)2);
			cylinderMesh = obj2.GetComponent<MeshFilter>().sharedMesh;
			Object.Destroy((Object)(object)obj2);
		}

		private static GameObject NewInactiveRoot(string name)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Expected O, but got Unknown
			//IL_0014: Expected O, but got Unknown
			GameObject val = new GameObject(name);
			val.SetActive(false);
			Object.DontDestroyOnLoad((Object)val);
			return val;
		}

		private static GameObject AddVisual(GameObject parent, Mesh mesh, Material material, Vector3 localPos, Vector3 localScale, Vector3 localEuler = default(Vector3))
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: 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_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			GameObject val = new GameObject("Visual");
			val.transform.SetParent(parent.transform, false);
			val.transform.localPosition = localPos;
			val.transform.localScale = localScale;
			val.transform.localEulerAngles = localEuler;
			val.AddComponent<MeshFilter>().sharedMesh = mesh;
			((Renderer)val.AddComponent<MeshRenderer>()).sharedMaterial = material;
			return val;
		}

		private static void AddHandGrips(GameObject parent, Vector3 rightLocalPos, Vector3 leftLocalPos)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Hand_R");
			val.transform.SetParent(parent.transform, false);
			val.transform.localPosition = rightLocalPos;
			GameObject val2 = new GameObject("Hand_L");
			val2.transform.SetParent(parent.transform, false);
			val2.transform.localPosition = leftLocalPos;
		}

		private static PhotonView AddPhotonView(GameObject go, params Component[] observed)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			PhotonView obj = go.AddComponent<PhotonView>();
			obj.OwnershipTransfer = (OwnershipOption)1;
			obj.Synchronization = (ViewSynchronization)3;
			obj.observableSearch = (ObservableSearch)0;
			obj.ObservedComponents = new List<Component>(observed);
			return obj;
		}

		private static GameObject BuildPooPrefab()
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: 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_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: 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_00b7: 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_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: 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_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Expected O, but got Unknown
			GameObject val = NewInactiveRoot("INTP_Poo");
			Material pooMaterial = BathroomAssets.PooMaterial;
			AddVisual(val, sphereMesh, pooMaterial, new Vector3(0f, 0.3f, 0f), new Vector3(1f, 0.7f, 1f));
			AddVisual(val, sphereMesh, pooMaterial, new Vector3(0f, 0.62f, 0f), new Vector3(0.74f, 0.55f, 0.74f));
			AddVisual(val, sphereMesh, pooMaterial, new Vector3(0f, 0.88f, 0f), new Vector3(0.48f, 0.42f, 0.48f));
			AddHandGrips(val, new Vector3(0.45f, 0.35f, 0f), new Vector3(-0.45f, 0.35f, 0f));
			BoxCollider obj = val.AddComponent<BoxCollider>();
			obj.center = new Vector3(0f, 0.5f, 0f);
			obj.size = new Vector3(0.95f, 1f, 0.95f);
			val.AddComponent<Rigidbody>().angularDamping = 3f;
			ItemPhysicsSyncer val2 = val.AddComponent<ItemPhysicsSyncer>();
			AddPhotonView(val, (Component)val2);
			Item obj2 = val.AddComponent<Item>();
			obj2.itemID = PooItemID;
			obj2.mass = 4f;
			obj2.usingTimePrimary = 1.65f;
			obj2.totalUses = -1;
			obj2.UIData = new ItemUIData
			{
				itemName = "Poo",
				icon = BathroomAssets.PooItemIcon,
				mainInteractPrompt = "Eat",
				canDrop = true,
				canPocket = true,
				canBackpack = true,
				canThrow = true
			};
			Action_PlayAnimation obj3 = val.AddComponent<Action_PlayAnimation>();
			((ItemAction)obj3).OnPressed = true;
			obj3.animationName = "PlayerEat";
			val.AddComponent<PooItem>();
			return val;
		}

		private static GameObject BuildToiletPaperPrefab()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: 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_0068: 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_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Expected O, but got Unknown
			GameObject val = NewInactiveRoot("INTP_ToiletPaper");
			AddVisual(val, cylinderMesh, BathroomAssets.PaperMaterial, Vector3.zero, new Vector3(0.28f, 0.126f, 0.28f), new Vector3(0f, 0f, 90f));
			AddVisual(val, cylinderMesh, BathroomAssets.PooMaterial, Vector3.zero, new Vector3(0.098f, 0.1288f, 0.098f), new Vector3(0f, 0f, 90f));
			AddHandGrips(val, new Vector3(0.14f, 0f, 0f), new Vector3(-0.14f, 0f, 0f));
			val.AddComponent<SphereCollider>().radius = 0.154f;
			val.AddComponent<Rigidbody>();
			ItemPhysicsSyncer val2 = val.AddComponent<ItemPhysicsSyncer>();
			AddPhotonView(val, (Component)val2);
			ToiletPaperItem toiletPaperItem = val.AddComponent<ToiletPaperItem>();
			((Item)toiletPaperItem).itemID = ToiletPaperItemID;
			((Item)toiletPaperItem).mass = 4f;
			((Item)toiletPaperItem).usingTimePrimary = 1.2f;
			((Item)toiletPaperItem).totalUses = BathroomConfig.ToiletPaperUseCount;
			((Item)toiletPaperItem).UIData = new ItemUIData
			{
				itemName = "Toilet Paper",
				icon = BathroomAssets.ToiletPaperItemIcon,
				mainInteractPrompt = "Wipe",
				canDrop = true,
				canPocket = true,
				canBackpack = true,
				canThrow = true
			};
			val.AddComponent<Action_ReduceUses>().consumeOnFullyUsed = true;
			val.AddComponent<ToiletPaperWipe>();
			return val;
		}

		private static GameObject BuildPuddlePrefab()
		{
			//IL_0025: 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_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = NewInactiveRoot("INTP_PeePuddle");
			AddVisual(val, cylinderMesh, BathroomAssets.PuddleMaterial, new Vector3(0f, 0.012f, 0f), new Vector3(1f, 0.012f, 1f));
			BoxCollider obj = val.AddComponent<BoxCollider>();
			((Collider)obj).isTrigger = true;
			obj.center = new Vector3(0f, 0.1f, 0f);
			obj.size = new Vector3(0.95f, 0.22f, 0.95f);
			PeePuddle peePuddle = val.AddComponent<PeePuddle>();
			AddPhotonView(val, (Component)peePuddle);
			return val;
		}

		public static IEnumerator RegisterItemsWhenReady()
		{
			ItemDatabase database = null;
			while ((Object)(object)database == (Object)null)
			{
				try
				{
					database = SingletonAsset<ItemDatabase>.Instance;
				}
				catch
				{
				}
				if ((Object)(object)database == (Object)null)
				{
					yield return (object)new WaitForSeconds(0.5f);
				}
			}
			RegisterItem(database, pooPrefab.GetComponent<Item>());
			RegisterItem(database, tpPrefab.GetComponent<Item>());
			AddLocalization();
			CopyGripsFromVanilla(database);
			Plugin.Log.LogInfo((object)$"Registered items: Poo (id {PooItemID}), Toilet Paper (id {ToiletPaperItemID})");
		}

		private static void AddLocalization()
		{
			try
			{
				AddTerm("NAME_POO", "Poo");
				AddTerm("NAME_TOILET PAPER", "Toilet Paper");
				AddTerm("DESC_POO", "You made this.");
				AddTerm("DESC_TOILET PAPER", "Five wipes of pure luxury.");
				AddTerm("EAT", "Eat");
				AddTerm("WIPE", "Wipe");
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"Failed to add localization terms: {arg}");
			}
			static void AddTerm(string key, string text)
			{
				Dictionary<string, List<string>> mainTable = LocalizedText.mainTable;
				if (!mainTable.ContainsKey(key))
				{
					int num = Enum.GetNames(typeof(Language)).Length;
					List<string> list = new List<string>(num);
					for (int i = 0; i < num; i++)
					{
						list.Add(text);
					}
					mainTable.Add(key, list);
				}
			}
		}

		private static void CopyGripsFromVanilla(ItemDatabase database)
		{
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			Item donor = null;
			Transform donorR = null;
			Transform donorL = null;
			foreach (KeyValuePair<ushort, Item> item in database.itemLookup)
			{
				Item value = item.Value;
				if ((Object)(object)value == (Object)null || (Object)(object)((Component)value).GetComponent<PooItem>() != (Object)null || (Object)(object)((Component)value).GetComponent<ToiletPaperWipe>() != (Object)null)
				{
					continue;
				}
				Transform val = ((Component)value).transform.Find("Hand_R");
				Transform val2 = ((Component)value).transform.Find("Hand_L");
				if (!((Object)(object)val == (Object)null) && !((Object)(object)val2 == (Object)null))
				{
					donor = value;
					donorR = val;
					donorL = val2;
					if (((Object)((Component)value).gameObject).name == "BingBong")
					{
						break;
					}
				}
			}
			if ((Object)(object)donor == (Object)null)
			{
				Plugin.Log.LogWarning((object)"No vanilla item with Hand_R/Hand_L found; keeping default hold setup.");
				return;
			}
			Plugin.Log.LogInfo((object)("Copying hold setup from vanilla item '" + ((Object)((Component)donor).gameObject).name + "' " + $"(defaultPos {donor.defaultPos}, defaultForward {donor.defaultForward}, " + $"R {donorR.localPosition}, L {donorL.localPosition})"));
			ApplyHoldSetup(tpPrefab);
			ApplyHoldSetup(pooPrefab);
			void ApplyHoldSetup(GameObject prefab)
			{
				//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_001d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0022: Unknown result type (might be due to invalid IL or missing references)
				//IL_004f: 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)
				Item component = prefab.GetComponent<Item>();
				component.defaultPos = donor.defaultPos;
				component.defaultForward = donor.defaultForward;
				Transform val3 = prefab.transform.Find("Hand_R");
				Transform obj = prefab.transform.Find("Hand_L");
				val3.localRotation = donorR.localRotation;
				obj.localRotation = donorL.localRotation;
			}
		}

		private static void RegisterItem(ItemDatabase database, Item item)
		{
			if (database.itemLookup.ContainsKey(item.itemID))
			{
				if ((Object)(object)database.itemLookup[item.itemID] != (Object)(object)item)
				{
					Plugin.Log.LogError((object)($"Item ID {item.itemID} already taken by {((Object)database.itemLookup[item.itemID]).name}! " + "Change it in the config on ALL players."));
				}
			}
			else
			{
				database.itemLookup.Add(item.itemID, item);
				((DatabaseAsset<ItemDatabase, Item>)(object)database).Objects.Add(item);
			}
		}

		private static void InstallPrefabPool()
		{
			if (!(PhotonNetwork.PrefabPool is BathroomPrefabPool))
			{
				PhotonNetwork.PrefabPool = (IPunPrefabPool)(object)new BathroomPrefabPool(PhotonNetwork.PrefabPool);
			}
		}
	}
	internal static class BathroomStatuses
	{
		[HarmonyPatch(typeof(CharacterAfflictions), "InitStatusArrays")]
		private static class Patch_InitStatusArrays
		{
			private static bool logged;

			private static void Postfix(CharacterAfflictions __instance)
			{
				//IL_0098: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a2: Expected I4, but got Unknown
				//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
				//IL_00af: Expected I4, but got Unknown
				//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
				//IL_00bc: Expected I4, but got Unknown
				//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c9: Expected I4, but got Unknown
				__instance.currentStatuses = Grow(__instance.currentStatuses);
				__instance.currentIncrementalStatuses = Grow(__instance.currentIncrementalStatuses);
				__instance.currentDecrementalStatuses = Grow(__instance.currentDecrementalStatuses);
				__instance.lastAddedStatus = Grow(__instance.lastAddedStatus);
				__instance.lastAddedIncrementalStatus = Grow(__instance.lastAddedIncrementalStatus);
				if (!logged)
				{
					logged = true;
					Plugin.Log.LogInfo((object)($"Status arrays grown to {__instance.currentStatuses.Length} " + $"(vanilla {VanillaCount}); Poo={(int)Poo} Pee={(int)Pee} Dirty={(int)Dirty} Stink={(int)Stink}"));
				}
			}
		}

		[HarmonyPatch(typeof(CharacterAfflictions), "GetStatusCap")]
		private static class Patch_GetStatusCap
		{
			private static void Postfix(STATUSTYPE type, ref float __result)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0006: Invalid comparison between Unknown and I4
				if ((int)type >= VanillaCount)
				{
					__result = 1f;
				}
			}
		}

		[HarmonyPatch(typeof(StaminaBar), "Start")]
		private static class Patch_StaminaBarStart
		{
			private const string ClonePrefix = "BarAffliction_INTP_";

			private static void Postfix(StaminaBar __instance)
			{
				//IL_0032: Unknown result type (might be due to invalid IL or missing references)
				//IL_003c: Invalid comparison between Unknown and I4
				//IL_0097: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a3: Expected I4, but got Unknown
				//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f7: 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_0115: 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_0133: Unknown result type (might be due to invalid IL or missing references)
				//IL_014c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0151: 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_01a1: Expected I4, but got Unknown
				//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
				//IL_01ae: Expected I4, but got Unknown
				//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
				//IL_01bb: Expected I4, but got Unknown
				//IL_01be: Unknown result type (might be due to invalid IL or missing references)
				//IL_01c8: Expected I4, but got Unknown
				try
				{
					if (__instance.afflictions == null || __instance.afflictions.Length == 0)
					{
						return;
					}
					List<BarAffliction> list = new List<BarAffliction>(__instance.afflictions);
					bool flag = false;
					BarAffliction[] afflictions = __instance.afflictions;
					for (int i = 0; i < afflictions.Length; i++)
					{
						if ((int)afflictions[i].afflictionType >= VanillaCount)
						{
							flag = true;
							break;
						}
					}
					if (flag)
					{
						return;
					}
					Transform parent = ((Component)__instance.afflictions[0]).transform.parent;
					Dictionary<int, BarAffliction> dictionary = new Dictionary<int, BarAffliction>();
					afflictions = ((Component)parent).GetComponentsInChildren<BarAffliction>(true);
					foreach (BarAffliction val in afflictions)
					{
						if (((Object)((Component)val).gameObject).name.StartsWith("BarAffliction_INTP_"))
						{
							dictionary[(int)val.afflictionType] = val;
						}
					}
					BarAffliction val2 = null;
					afflictions = __instance.afflictions;
					foreach (BarAffliction val3 in afflictions)
					{
						if (!val3.isPetrify)
						{
							val2 = val3;
							break;
						}
					}
					if ((Object)(object)val2 == (Object)null)
					{
						val2 = __instance.afflictions[0];
					}
					list.Add(GetOrClone(dictionary, val2, Poo, PooColor, BathroomAssets.PooIcon));
					list.Add(GetOrClone(dictionary, val2, Pee, PeeColor, BathroomAssets.PeeIcon));
					list.Add(GetOrClone(dictionary, val2, Dirty, DirtyColor, BathroomAssets.DirtyIcon));
					list.Add(GetOrClone(dictionary, val2, Stink, StinkColor, BathroomAssets.StinkIcon));
					__instance.afflictions = list.ToArray();
					Plugin.Log.LogInfo((object)($"Stamina bar extended: vanilla={VanillaCount} segments, " + $"Poo={(int)Poo} Pee={(int)Pee} Dirty={(int)Dirty} Stink={(int)Stink}, " + $"template='{((Object)((Component)val2).gameObject).name}', total={__instance.afflictions.Length}"));
				}
				catch (Exception arg)
				{
					Plugin.Log.LogError((object)$"Failed to extend stamina bar UI: {arg}");
				}
			}

			private static BarAffliction GetOrClone(Dictionary<int, BarAffliction> survivors, BarAffliction template, STATUSTYPE type, Color color, Sprite icon)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0009: Expected I4, but got Unknown
				//IL_0017: Unknown result type (might be due to invalid IL or missing references)
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				if (survivors.TryGetValue((int)type, out var value) && (Object)(object)value != (Object)null)
				{
					return value;
				}
				return CloneSegment(template, type, color, icon);
			}

			private static BarAffliction CloneSegment(BarAffliction template, STATUSTYPE type, Color color, Sprite icon)
			{
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				//IL_001f: Expected I4, but got Unknown
				//IL_0038: 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_008b: Unknown result type (might be due to invalid IL or missing references)
				//IL_007d: Unknown result type (might be due to invalid IL or missing references)
				GameObject val = Object.Instantiate<GameObject>(((Component)template).gameObject, ((Component)template).transform.parent);
				((Object)val).name = "BarAffliction_INTP_" + (int)type;
				BarAffliction component = val.GetComponent<BarAffliction>();
				component.afflictionType = type;
				component.isPetrify = false;
				Image[] componentsInChildren = val.GetComponentsInChildren<Image>(true);
				foreach (Image val2 in componentsInChildren)
				{
					if ((Object)(object)component.icon != (Object)null && (Object)(object)val2 == (Object)(object)component.icon)
					{
						val2.sprite = icon;
						((Graphic)val2).color = Color.white;
					}
					else
					{
						((Graphic)val2).color = color;
					}
				}
				val.SetActive(false);
				return component;
			}
		}

		public static readonly int VanillaCount = Enum.GetNames(typeof(STATUSTYPE)).Length;

		public static readonly STATUSTYPE Poo = (STATUSTYPE)VanillaCount;

		public static readonly STATUSTYPE Pee = (STATUSTYPE)(VanillaCount + 1);

		public static readonly STATUSTYPE Dirty = (STATUSTYPE)(VanillaCount + 2);

		public static readonly STATUSTYPE Stink = (STATUSTYPE)(VanillaCount + 3);

		public static readonly int TotalCount = VanillaCount + 4;

		public static readonly Color PooColor = new Color(0.45f, 0.27f, 0.07f);

		public static readonly Color PeeColor = new Color(0.93f, 0.85f, 0.21f);

		public static readonly Color DirtyColor = new Color(0.55f, 0.55f, 0.53f);

		public static readonly Color StinkColor = new Color(0.55f, 0.6f, 0.18f);

		public const float Chunk = 0.025f;

		public static float ChunkUp(float amount)
		{
			if (amount <= 0f)
			{
				return 0f;
			}
			return Mathf.Ceil(amount / 0.025f) * 0.025f;
		}

		public static bool AddModStatus(CharacterAfflictions afflictions, STATUSTYPE type, float amount)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)afflictions == (Object)null || amount <= 0f)
			{
				return false;
			}
			bool inAirport = afflictions.m_inAirport;
			if (inAirport)
			{
				afflictions.m_inAirport = false;
			}
			try
			{
				bool num = afflictions.AddStatus(type, amount, false, true, true);
				if (!num)
				{
					ManualLogSource log = Plugin.Log;
					string text = $"The game refused {type} +{amount:F3} ";
					object arg = inAirport;
					Character character = afflictions.character;
					string text2 = $"(airport={arg}, locked={((character != null) ? new bool?(character.statusesLocked) : ((bool?)null))}, ";
					Character character2 = afflictions.character;
					bool? obj;
					if (character2 == null)
					{
						obj = null;
					}
					else
					{
						CharacterData data = character2.data;
						obj = ((data != null) ? new bool?(data.isSkeleton) : ((bool?)null));
					}
					log.LogWarning((object)(text + text2 + $"skeleton={obj}, " + $"invincible={afflictions.character?.data?.isInvincible})"));
				}
				return num;
			}
			finally
			{
				if (inAirport)
				{
					afflictions.m_inAirport = true;
				}
			}
		}

		private static float[] Grow(float[] arr)
		{
			if (arr == null || arr.Length >= TotalCount)
			{
				return arr;
			}
			float[] array = new float[TotalCount];
			Array.Copy(arr, array, arr.Length);
			return array;
		}
	}
	public class CharacterBathroom : MonoBehaviourPun
	{
		private Character character;

		private float pooProgress;

		private float pooDuration;

		private float peeReleased;

		private float peeStartLevel;

		private PeePuddle activePuddle;

		private ParticleSystem peeStream;

		private int lastPooCarryCount = -1;

		private const float StreamStartSpeed = 3.2f;

		private const float StreamGravityModifier = 1.35f;

		private static readonly Vector3 StreamLocalOffset = new Vector3(0f, 0f, 0.22f);

		private static readonly Quaternion StreamLocalTilt = Quaternion.Euler(12f, 0f, 0f);

		public bool IsPooping { get; private set; }

		public bool IsPeeing { get; private set; }

		internal static CharacterBathroom LocalInstance { get; private set; }

		internal Character CharacterRef => character;

		private CharacterAfflictions Afflictions => character.refs.afflictions;

		private void Awake()
		{
			character = ((Component)this).GetComponent<Character>();
		}

		private void OnDestroy()
		{
			if ((Object)(object)LocalInstance == (Object)(object)this)
			{
				LocalInstance = null;
			}
		}

		private void Update()
		{
			//IL_003b: 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_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			UpdateCarriedPooStink();
			if ((Object)(object)character == (Object)null || !character.IsLocal || character.isBot)
			{
				return;
			}
			LocalInstance = this;
			float currentStatus = Afflictions.GetCurrentStatus(BathroomStatuses.Poo);
			float currentStatus2 = Afflictions.GetCurrentStatus(BathroomStatuses.Pee);
			bool num = character.CanDoInput();
			bool flag = num && Input.GetKey(BathroomConfig.PooKey.Value);
			bool flag2 = num && Input.GetKey(BathroomConfig.PeeKey.Value);
			if (IsPooping)
			{
				if (!flag || !CanPoo())
				{
					StopPoo();
					return;
				}
				pooProgress += Time.deltaTime;
				if (pooProgress >= pooDuration)
				{
					FinishPoo();
				}
			}
			else if (IsPeeing)
			{
				if (!flag2 || !CanPee() || Afflictions.GetCurrentStatus(BathroomStatuses.Pee) <= 0.001f)
				{
					StopPee();
				}
				else
				{
					ContinuePee();
				}
			}
			else if (flag && currentStatus >= BathroomConfig.ActionThreshold.Value && CanPoo())
			{
				StartPoo(currentStatus);
			}
			else if (flag2 && currentStatus2 >= BathroomConfig.ActionThreshold.Value && CanPee())
			{
				StartPee(currentStatus2);
			}
		}

		private bool CanPoo()
		{
			CharacterData data = character.data;
			if (data.isGrounded && data.fullyConscious && !data.shouldPetrify && !data.isClimbingAnything && !data.isCarried && !data.isJumping)
			{
				return !data.usingWheel;
			}
			return false;
		}

		private bool CanPee()
		{
			if (CanPoo() && ((Vector3)(ref character.data.avarageVelocity)).magnitude < BathroomConfig.MovementEpsilon.Value)
			{
				return ((Vector2)(ref character.input.movementInput)).magnitude < 0.01f;
			}
			return false;
		}

		private void StartPoo(float level)
		{
			IsPooping = true;
			pooProgress = 0f;
			pooDuration = Mathf.Max(0.5f, level * BathroomConfig.SecondsPerFullBar.Value);
		}

		private void StopPoo()
		{
			IsPooping = false;
			pooProgress = 0f;
		}

		private void FinishPoo()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: 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_0078: 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_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: 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_00ce: 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_00e0: Unknown result type (might be due to invalid IL or missing references)
			IsPooping = false;
			float currentStatus = Afflictions.GetCurrentStatus(BathroomStatuses.Poo);
			Afflictions.SetStatus(BathroomStatuses.Poo, 0f, true);
			if (BathroomConfig.EnableDirty.Value)
			{
				BathroomStatuses.AddModStatus(Afflictions, BathroomStatuses.Dirty, BathroomStatuses.ChunkUp(BathroomConfig.DirtyPerPoo.Value * BathroomConfig.EffectScale));
			}
			Vector3 val = (character.data.isGrounded ? character.data.groundPos : character.Center);
			Quaternion val2 = Quaternion.Euler(0f, Random.Range(0f, 360f), 0f);
			((MonoBehaviourPun)this).photonView.RPC("RPC_MasterSpawnPoo", (RpcTarget)2, new object[3]
			{
				val + Vector3.up * 0.1f,
				val2,
				currentStatus
			});
		}

		[PunRPC]
		public void RPC_MasterSpawnPoo(Vector3 pos, Quaternion rot, float amount)
		{
			//IL_000d: 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)
			if (PhotonNetwork.IsMasterClient && (Object)(object)PhotonNetwork.InstantiateRoomObject("0_Items/INTP_Poo", pos, rot, (byte)0, new object[1] { amount }) == (Object)null)
			{
				Plugin.Log.LogError((object)"Poo InstantiateRoomObject returned null!");
			}
		}

		private void StartPee(float level)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			IsPeeing = true;
			peeReleased = 0f;
			peeStartLevel = level;
			((MonoBehaviourPun)this).photonView.RPC("RPC_SetPeeVFX", (RpcTarget)0, new object[1] { true });
			Vector3 val = ComputeStreamLanding();
			GameObject val2 = PhotonNetwork.Instantiate("0_Items/INTP_PeePuddle", val, Quaternion.identity, (byte)0, (object[])null);
			activePuddle = (((Object)(object)val2 != (Object)null) ? val2.GetComponent<PeePuddle>() : null);
		}

		private Vector3 ComputeStreamLanding()
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: 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_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: 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_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)
			//IL_0085: 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_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_009c: 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_00a7: 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_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: 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_00c4: 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_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: 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)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: 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_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: 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_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: 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_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			Rigidbody bodypartRig = character.GetBodypartRig((BodypartType)0);
			Transform obj = (((Object)(object)bodypartRig != (Object)null) ? ((Component)bodypartRig).transform : ((Component)character).transform);
			Vector3 val = obj.TransformPoint(StreamLocalOffset);
			Vector3 val2 = obj.rotation * StreamLocalTilt * Vector3.forward;
			Vector3 val3 = ((Vector3)(ref val2)).normalized * 3.2f;
			Vector3 val4 = Physics.gravity * 1.35f;
			LayerMask mask = HelperFunctions.GetMask((LayerType)1);
			Vector3 val5 = val;
			RaycastHit val8 = default(RaycastHit);
			for (int i = 0; i < 250; i++)
			{
				Vector3 val6 = val5 + val3 * 0.02f + 0.5f * val4 * 0.02f * 0.02f;
				val3 += val4 * 0.02f;
				Vector3 val7 = val6 - val5;
				float magnitude = ((Vector3)(ref val7)).magnitude;
				if (magnitude > 0.0001f && Physics.Raycast(val5, val7 / magnitude, ref val8, magnitude, LayerMask.op_Implicit(mask), (QueryTriggerInteraction)1))
				{
					return ((RaycastHit)(ref val8)).point + Vector3.up * 0.02f;
				}
				val5 = val6;
				if (val5.y < val.y - 30f)
				{
					break;
				}
			}
			RaycastHit val9 = default(RaycastHit);
			if (Physics.Raycast(val5 + Vector3.up, Vector3.down, ref val9, 40f, LayerMask.op_Implicit(mask), (QueryTriggerInteraction)1))
			{
				return ((RaycastHit)(ref val9)).point + Vector3.up * 0.02f;
			}
			Vector3 normalized = ((Vector3)(ref character.data.lookDirection_Flat)).normalized;
			return (character.data.isGrounded ? character.data.groundPos : (character.Center + Vector3.down)) + normalized * 0.9f + Vector3.up * 0.02f;
		}

		private void ContinuePee()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: 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)
			float num = BathroomConfig.PeeDrainPerSecond.Value * Time.deltaTime;
			Afflictions.SubtractStatus(BathroomStatuses.Pee, num, false, false);
			peeReleased += num;
			if ((Object)(object)activePuddle != (Object)null)
			{
				activePuddle.SetPeeAmount(peeReleased);
			}
			if (peeReleased >= peeStartLevel - 0.001f && Afflictions.GetCurrentStatus(BathroomStatuses.Pee) <= 0.026f)
			{
				Afflictions.SetStatus(BathroomStatuses.Pee, 0f, true);
				StopPee();
			}
		}

		private void StopPee()
		{
			IsPeeing = false;
			activePuddle = null;
			((MonoBehaviourPun)this).photonView.RPC("RPC_SetPeeVFX", (RpcTarget)0, new object[1] { false });
		}

		[PunRPC]
		public void RPC_SetPeeVFX(bool active)
		{
			if (active && (Object)(object)peeStream == (Object)null)
			{
				CreatePeeStream();
			}
			if (!((Object)(object)peeStream == (Object)null))
			{
				if (active)
				{
					peeStream.Play();
				}
				else
				{
					peeStream.Stop(true, (ParticleSystemStopBehavior)1);
				}
			}
		}

		private void CreatePeeStream()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: 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_00a6: 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_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_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			Rigidbody bodypartRig = character.GetBodypartRig((BodypartType)0);
			if (!((Object)(object)bodypartRig == (Object)null))
			{
				GameObject val = new GameObject("INTP_PeeStream");
				val.transform.SetParent(((Component)bodypartRig).transform, false);
				val.transform.localPosition = StreamLocalOffset;
				val.transform.localRotation = StreamLocalTilt;
				peeStream = val.AddComponent<ParticleSystem>();
				MainModule main = peeStream.main;
				((MainModule)(ref main)).startSpeed = MinMaxCurve.op_Implicit(3.2f);
				((MainModule)(ref main)).startSize = MinMaxCurve.op_Implicit(0.055f);
				((MainModule)(ref main)).startLifetime = MinMaxCurve.op_Implicit(1.1f);
				((MainModule)(ref main)).gravityModifier = MinMaxCurve.op_Implicit(1.35f);
				((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(new Color(0.95f, 0.87f, 0.25f, 0.9f));
				((MainModule)(ref main)).simulationSpace = (ParticleSystemSimulationSpace)1;
				((MainModule)(ref main)).playOnAwake = false;
				EmissionModule emission = peeStream.emission;
				((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(65f);
				ShapeModule shape = peeStream.shape;
				((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)4;
				((ShapeModule)(ref shape)).angle = 3.5f;
				((ShapeModule)(ref shape)).radius = 0.015f;
				((Renderer)((Component)peeStream).GetComponent<ParticleSystemRenderer>()).material = BathroomAssets.PuddleMaterial;
				peeStream.Stop(true, (ParticleSystemStopBehavior)0);
			}
		}

		private void UpdateCarriedPooStink()
		{
			//IL_004e: 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_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)character == (Object)null || !((MonoBehaviourPun)this).photonView.IsMine || character.isBot || (Object)(object)character.player == (Object)null)
			{
				return;
			}
			if (!BathroomConfig.EnableDirty.Value && Afflictions.GetCurrentStatus(BathroomStatuses.Dirty) > 0f)
			{
				Afflictions.SetStatus(BathroomStatuses.Dirty, 0f, true);
			}
			if (!BathroomConfig.EnableStink.Value)
			{
				if (lastPooCarryCount != 0)
				{
					lastPooCarryCount = 0;
					Afflictions.SetStatus(BathroomStatuses.Stink, 0f, true);
				}
				return;
			}
			int num = 0;
			Player player = character.player;
			for (byte b = 0; b < 3; b++)
			{
				if (SlotHasPoo(player.GetItemSlot(b)))
				{
					num++;
				}
			}
			if (SlotHasPoo(player.tempFullSlot))
			{
				num++;
			}
			if (num == 0 && (Object)(object)character.data.currentItem != (Object)null && character.data.currentItem.itemID == BathroomItems.PooItemID)
			{
				num = 1;
			}
			if (num != lastPooCarryCount)
			{
				lastPooCarryCount = num;
				Afflictions.SetStatus(BathroomStatuses.Stink, (float)num * BathroomConfig.PooCarryStink.Value * BathroomConfig.EffectScale, true);
			}
		}

		private static bool SlotHasPoo(ItemSlot slot)
		{
			if (slot != null && !slot.IsEmpty() && (Object)(object)slot.prefab != (Object)null)
			{
				return slot.prefab.itemID == BathroomItems.PooItemID;
			}
			return false;
		}

		internal bool TryGetProgress(out string label, out float fill, out Color color)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			if (IsPooping)
			{
				label = "Pooping...";
				fill = Mathf.Clamp01(pooProgress / pooDuration);
				color = BathroomStatuses.PooColor;
				return true;
			}
			if (IsPeeing)
			{
				label = "Peeing...";
				fill = Mathf.Clamp01(Afflictions.GetCurrentStatus(BathroomStatuses.Pee) / Mathf.Max(peeStartLevel, 0.01f));
				color = BathroomStatuses.PeeColor;
				return true;
			}
			label = null;
			fill = 0f;
			color = default(Color);
			return false;
		}
	}
	[HarmonyPatch(typeof(Character), "Awake")]
	internal static class Patch_CharacterAwake
	{
		private static void Postfix(Character __instance)
		{
			if ((Object)(object)((Component)__instance).GetComponent<CharacterBathroom>() == (Object)null)
			{
				((Component)__instance).gameObject.AddComponent<CharacterBathroom>();
				PhotonView component = ((Component)__instance).GetComponent<PhotonView>();
				if ((Object)(object)component != (Object)null)
				{
					component.RefreshRpcMonoBehaviourCache();
				}
			}
		}
	}
	[HarmonyPatch(typeof(CharacterMovement), "SetMovementState")]
	internal static class Patch_ForceCrouchWhilePooping
	{
		private static void Prefix(CharacterMovement __instance)
		{
			CharacterBathroom localInstance = CharacterBathroom.LocalInstance;
			if (!((Object)(object)localInstance == (Object)null) && localInstance.IsPooping && !((Object)(object)__instance.character != (Object)(object)localInstance.CharacterRef))
			{
				CharacterInput input = localInstance.CharacterRef.input;
				input.crouchIsPressed = true;
				input.sprintIsPressed = false;
				input.sprintToggleWasPressed = false;
			}
		}
	}
	[HarmonyPatch(typeof(CharacterMovement), "GetMovementForce")]
	internal static class Patch_SlowWhilePooping
	{
		private static void Postfix(CharacterMovement __instance, ref float __result)
		{
			if (!(__result <= 0f))
			{
				CharacterBathroom localInstance = CharacterBathroom.LocalInstance;
				if (!((Object)(object)localInstance == (Object)null) && localInstance.IsPooping && !((Object)(object)__instance.character != (Object)(object)localInstance.CharacterRef))
				{
					__result *= BathroomConfig.PooMoveSpeedMultiplier.Value;
				}
			}
		}
	}
	[HarmonyPatch(typeof(Spawner), "SpawnItems")]
	internal static class LuggagePatch
	{
		private const SpawnPool BiomeLuggagePools = (SpawnPool)889207808;

		private static void Postfix(Spawner __instance, List<Transform> spawnSpots, List<PhotonView> __result)
		{
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//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_0192: 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_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			if (!PhotonNetwork.IsMasterClient)
			{
				return;
			}
			Luggage val = (Luggage)(object)((__instance is Luggage) ? __instance : null);
			if (val == null)
			{
				return;
			}
			float toiletPaperChance = GetToiletPaperChance(val, spawnSpots);
			float num = Random.Range(0f, 1f);
			int num2 = __result?.Count ?? 0;
			Plugin.Log.LogInfo((object)("Luggage opened: name=" + ((Object)((Component)val).gameObject).name + ", displayName=" + val.displayName + ", " + $"pool={((Spawner)val).GetSpawnPool()}, spots={spawnSpots?.Count ?? 0}, items={num2}, " + $"tpChance={toiletPaperChance:F2}, roll={num:F2}"));
			if (toiletPaperChance <= 0f || num > toiletPaperChance)
			{
				return;
			}
			Vector3 val3;
			Quaternion val4;
			if (BathroomConfig.ToiletPaperReplacesLuggageItem.Value && __result != null && __result.Count > 0)
			{
				int index = Random.Range(0, __result.Count);
				PhotonView val2 = __result[index];
				if ((Object)(object)val2 == (Object)null)
				{
					return;
				}
				val3 = ((Component)val2).transform.position;
				val4 = ((Component)val2).transform.rotation;
				__result.RemoveAt(index);
				PhotonNetwork.Destroy(((Component)val2).gameObject);
			}
			else
			{
				val4 = Quaternion.identity;
				val3 = ((Component)val).transform.position + Vector3.up * 0.5f;
				if (spawnSpots != null && spawnSpots.Count > 0)
				{
					Transform val5 = spawnSpots[Random.Range(0, spawnSpots.Count)];
					if ((Object)(object)val5 != (Object)null)
					{
						val3 = val5.position + Vector3.up * 0.25f;
					}
				}
			}
			GameObject val6 = PhotonNetwork.InstantiateRoomObject("0_Items/INTP_ToiletPaper", val3, val4, (byte)0, (object[])null);
			if ((Object)(object)val6 != (Object)null)
			{
				PhotonView component = val6.GetComponent<PhotonView>();
				component.RPC("SetKinematicRPC", (RpcTarget)3, new object[3] { true, val3, val4 });
				__result?.Add(component);
				Plugin.Log.LogInfo((object)("Toilet paper spawned in " + ((Object)((Component)val).gameObject).name + " (mode=" + (BathroomConfig.ToiletPaperReplacesLuggageItem.Value ? "replace" : "additive") + ")"));
			}
			else
			{
				Plugin.Log.LogError((object)"Toilet paper InstantiateRoomObject returned null!");
			}
		}

		private static float GetToiletPaperChance(Luggage luggage, List<Transform> spawnSpots)
		{
			//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_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			SpawnPool spawnPool = ((Spawner)luggage).GetSpawnPool();
			if (((Enum)spawnPool).HasFlag((Enum)(object)(SpawnPool)16384))
			{
				return BathroomConfig.TPChanceExplorerLuggage.Value;
			}
			if ((spawnPool & 0x35003C00) != 0 && spawnSpots != null && spawnSpots.Count >= 3)
			{
				return BathroomConfig.TPChanceBigLuggage.Value;
			}
			string text = (luggage.displayName + " " + ((Object)((Component)luggage).gameObject).name).ToLowerInvariant();
			if (text.Contains("big"))
			{
				return BathroomConfig.TPChanceBigLuggage.Value;
			}
			if (text.Contains("explorer") || text.Contains("climber"))
			{
				return BathroomConfig.TPChanceExplorerLuggage.Value;
			}
			return 0f;
		}
	}
	public class PeePuddle : MonoBehaviourPun, IPunObservable
	{
		private float peeAmount;

		private float lastSlipTime;

		private float bornTime;

		private void Awake()
		{
			bornTime = Time.time;
			lastSlipTime = Time.time;
			ApplyScale(instant: true);
			if ((Object)(object)((MonoBehaviourPun)this).photonView != (Object)null && ((MonoBehaviourPun)this).photonView.IsMine)
			{
				BathroomCleanup.RegisterPuddle(((Component)this).gameObject);
			}
		}

		private void Update()
		{
			ApplyScale(instant: false);
			if (((MonoBehaviourPun)this).photonView.IsMine && BathroomConfig.PuddleLifetime.Value > 0f && Time.time - bornTime > BathroomConfig.PuddleLifetime.Value)
			{
				PhotonNetwork.Destroy(((Component)this).gameObject);
			}
		}

		public void SetPeeAmount(float amount)
		{
			if (((MonoBehaviourPun)this).photonView.IsMine)
			{
				peeAmount = Mathf.Max(peeAmount, amount);
			}
		}

		private float TargetDiameter()
		{
			float num = Mathf.Clamp01(peeAmount / Mathf.Max(0.05f, BathroomConfig.PuddleFullAmount.Value));
			return Mathf.Lerp(BathroomConfig.PooBaseDiameter.Value, BathroomConfig.PuddleMaxDiameter.Value, num);
		}

		private void ApplyScale(bool instant)
		{
			//IL_000d: 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)
			float num = TargetDiameter();
			float x = ((Component)this).transform.localScale.x;
			if (instant || !(Mathf.Abs(num - x) < 0.002f))
			{
				float num2 = (instant ? num : Mathf.Lerp(x, num, Time.deltaTime * 4f));
				((Component)this).transform.localScale = new Vector3(num2, 1f, num2);
			}
		}

		private void OnTriggerStay(Collider other)
		{
			Character val = default(Character);
			if (!(Time.time - lastSlipTime < 3f) && !(Time.time - bornTime < 1f) && CharacterRagdoll.TryGetCharacterFromCollider(other, ref val) && !((Object)(object)val == (Object)null) && val.IsLocal && val.data.isGrounded && !(((Vector3)(ref val.data.avarageVelocity)).magnitude < 1.5f))
			{
				CharacterBathroom component = ((Component)val).GetComponent<CharacterBathroom>();
				if (!((Object)(object)component != (Object)null) || !component.IsPeeing)
				{
					lastSlipTime = Time.time;
					((MonoBehaviourPun)this).photonView.RPC("RPCA_PuddleSlip", (RpcTarget)0, new object[1] { val.refs.view.ViewID });
				}
			}
		}

		[PunRPC]
		public void RPCA_PuddleSlip(int viewID)
		{
			lastSlipTime = Time.time;
			BathroomSlip.SlipCharacter(viewID);
		}

		public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
		{
			if (stream.IsWriting)
			{
				stream.SendNext((object)peeAmount);
			}
			else
			{
				peeAmount = (float)stream.ReceiveNext();
			}
		}
	}
	[BepInPlugin("com.exoflex.ineedtopeeak", "INeedToPEEak", "0.2.0")]
	public class Plugin : BaseUnityPlugin
	{
		public const string PluginGuid = "com.exoflex.ineedtopeeak";

		public const string PluginName = "INeedToPEEak";

		public const string PluginVersion = "0.2.0";

		private Harmony harmony;

		internal static Plugin Instance { get; private set; }

		internal static ManualLogSource Log { get; private set; }

		private void Awake()
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected O, but got Unknown
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			((MonoBehaviour)this).useGUILayout = false;
			BathroomConfig.Bind(((BaseUnityPlugin)this).Config);
			BathroomAssets.CreateAll();
			BathroomItems.Initialize();
			harmony = new Harmony("com.exoflex.ineedtopeeak");
			harmony.PatchAll(typeof(Plugin).Assembly);
			SceneManager.sceneLoaded += StartingItemGiver.OnSceneLoaded;
			((MonoBehaviour)this).StartCoroutine(BathroomItems.RegisterItemsWhenReady());
			Log.LogInfo((object)"INeedToPEEak 0.2.0 loaded. Stay regular out there.");
		}

		private void OnGUI()
		{
			//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_0064: 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_009c: 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_00ba: 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_00de: Unknown result type (might be due to invalid IL or missing references)
			CharacterBathroom localInstance = CharacterBathroom.LocalInstance;
			if (!((Object)(object)localInstance == (Object)null) && localInstance.TryGetProgress(out var label, out var fill, out var color))
			{
				float num = 260f;
				float num2 = 18f;
				float num3 = ((float)Screen.width - num) / 2f;
				float num4 = (float)Screen.height * 0.72f;
				Color color2 = GUI.color;
				GUI.color = new Color(0f, 0f, 0f, 0.55f);
				GUI.DrawTexture(new Rect(num3 - 2f, num4 - 2f, num + 4f, num2 + 4f), (Texture)(object)Texture2D.whiteTexture);
				GUI.color = color;
				GUI.DrawTexture(new Rect(num3, num4, num * fill, num2), (Texture)(object)Texture2D.whiteTexture);
				GUI.color = Color.white;
				GUI.Label(new Rect(num3, num4 - 22f, num, 20f), label);
				GUI.color = color2;
			}
		}

		private void OnDestroy()
		{
			SceneManager.sceneLoaded -= StartingItemGiver.OnSceneLoaded;
			Harmony obj = harmony;
			if (obj != null)
			{
				obj.UnpatchSelf();
			}
		}
	}
	public class PooItem : ItemComponent, IPunInstantiateMagicCallback
	{
		private const float DefaultAmount = 1f / 3f;

		private const DataEntryKey PooAmountKey = (DataEntryKey)200;

		public float pooAmount = 1f / 3f;

		private float slipCounter;

		public override void Awake()
		{
			((ItemComponent)this).Awake();
			base.item.forceScale = false;
			ResolveFromData();
			ApplyAmount();
		}

		private void Start()
		{
			Item item = base.item;
			item.OnPrimaryFinishedCast = (Action)Delegate.Combine(item.OnPrimaryFinishedCast, new Action(OnEatenLocally));
		}

		private void OnDestroy()
		{
			if ((Object)(object)base.item != (Object)null)
			{
				Item item = base.item;
				item.OnPrimaryFinishedCast = (Action)Delegate.Remove(item.OnPrimaryFinishedCast, new Action(OnEatenLocally));
			}
		}

		public void OnPhotonInstantiate(PhotonMessageInfo info)
		{
			//IL_0000: 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)
			if (info.photonView.IsMine)
			{
				BathroomCleanup.RegisterPoo(((Component)this).gameObject);
			}
			object[] instantiationData = info.photonView.InstantiationData;
			if (instantiationData != null && instantiationData.Length != 0 && instantiationData[0] is float num)
			{
				pooAmount = Mathf.Clamp(num, 0.05f, 1f);
				if ((Object)(object)((MonoBehaviourPun)this).photonView != (Object)null && ((MonoBehaviourPun)this).photonView.IsMine)
				{
					base.item.GetData<FloatItemData>((DataEntryKey)200, (Func<FloatItemData>)(() => new FloatItemData
					{
						Value = pooAmount
					})).Value = pooAmount;
					if (base.item.data != null)
					{
						((MonoBehaviourPun)this).photonView.RPC("SetItemInstanceDataRPC", (RpcTarget)1, new object[1] { base.item.data });
					}
				}
			}
			ApplyAmount();
		}

		public override void OnInstanceDataSet()
		{
			ResolveFromData();
			ApplyAmount();
		}

		private void ResolveFromData()
		{
			FloatItemData val = default(FloatItemData);
			if ((Object)(object)base.item != (Object)null && base.item.HasData((DataEntryKey)200) && base.item.data.TryGetDataEntry<FloatItemData>((DataEntryKey)200, ref val))
			{
				pooAmount = Mathf.Clamp(val.Value, 0.05f, 1f);
			}
		}

		private void ApplyAmount()
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)base.item == (Object)null)
			{
				base.item = ((Component)this).GetComponent<Item>();
			}
			float num = BathroomConfig.PooBaseDiameter.Value * (pooAmount / (1f / 3f));
			num = Mathf.Clamp(num, 0.12f, 1.6f);
			((Component)this).transform.localScale = Vector3.one * num;
			base.item.usingTimePrimary = Mathf.Max(0.4f, pooAmount * BathroomConfig.SecondsPerFullBar.Value * BathroomConfig.EatTimeRatio.Value);
		}

		private void OnEatenLocally()
		{
			Character holderCharacter = base.item.holderCharacter;
			if (!((Object)(object)holderCharacter == (Object)null) && holderCharacter.IsLocal)
			{
				holderCharacter.refs.afflictions.AddStatus((STATUSTYPE)3, pooAmount * BathroomConfig.EatPoisonRatio.Value * BathroomConfig.EffectScale, false, true, true);
				((MonoBehaviour)base.item).StartCoroutine(base.item.ConsumeDelayed(false));
			}
		}

		private void Update()
		{
			//IL_0006: 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_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			if ((int)base.item.itemState != 0)
			{
				slipCounter = 0f;
				return;
			}
			slipCounter += Time.deltaTime;
			if (slipCounter < 3f)
			{
				return;
			}
			Character localCharacter = Character.localCharacter;
			if (!((Object)(object)localCharacter == (Object)null) && localCharacter.data.isGrounded)
			{
				float num = Mathf.Max(0.9f, ((Component)this).transform.localScale.x * 2f);
				if (!(Vector3.Distance(localCharacter.Center, ((Component)this).transform.position) > num) && !(((Vector3)(ref localCharacter.data.avarageVelocity)).magnitude < 1.5f))
				{
					slipCounter = 0f;
					((MonoBehaviourPun)this).photonView.RPC("RPCA_PooSlip", (RpcTarget)0, new object[1] { localCharacter.refs.view.ViewID });
				}
			}
		}

		[PunRPC]
		public void RPCA_PooSlip(int viewID)
		{
			//IL_003d: 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_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)
			BathroomSlip.SlipCharacter(viewID);
			Rigidbody component = ((Component)this).GetComponent<Rigidbody>();
			PhotonView val = PhotonView.Find(viewID);
			if ((Object)(object)component != (Object)null && (Object)(object)val != (Object)null)
			{
				Character component2 = ((Component)val).GetComponent<Character>();
				if ((Object)(object)component2 != (Object)null)
				{
					component.AddForce((component2.data.lookDirection_Flat * 0.5f + Vector3.up) * 40f, (ForceMode)1);
				}
			}
		}
	}
	internal static class BathroomSlip
	{
		public static void SlipCharacter(int viewID)
		{
			//IL_005a: 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_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: 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_00bd: 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)
			PhotonView val = PhotonView.Find(viewID);
			if (!((Object)(object)val == (Object)null))
			{
				Character component = ((Component)val).GetComponent<Character>();
				if (!((Object)(object)component == (Object)null))
				{
					Rigidbody bodypartRig = component.GetBodypartRig((BodypartType)16);
					Rigidbody bodypartRig2 = component.GetBodypartRig((BodypartType)13);
					Rigidbody bodypartRig3 = component.GetBodypartRig((BodypartType)0);
					Rigidbody bodypartRig4 = component.GetBodypartRig((BodypartType)4);
					component.RPCA_Fall(2f, 0f);
					bodypartRig.AddForce((component.data.lookDirection_Flat + Vector3.up) * 200f, (ForceMode)1);
					bodypartRig2.AddForce((component.data.lookDirection_Flat + Vector3.up) * 200f, (ForceMode)1);
					bodypartRig3.AddForce(Vector3.up * 1500f, (ForceMode)1);
					bodypartRig4.AddForce(component.data.lookDirection_Flat * -300f, (ForceMode)1);
				}
			}
		}
	}
	internal static class StartingItemGiver
	{
		public static void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			if (BathroomConfig.GiveStartingToiletPaper.Value && (int)mode == 0)
			{
				string text = ((Scene)(ref scene)).name ?? "";
				if (!(text == "Airport") && !text.Contains("Title") && !text.Contains("Boot") && !text.Contains("Menu"))
				{
					((MonoBehaviour)Plugin.Instance).StartCoroutine(GiveWhenReady());
				}
			}
		}

		private static IEnumerator GiveWhenReady()
		{
			float deadline = Time.realtimeSinceStartup + 60f;
			while (Time.realtimeSinceStartup < deadline && (!PhotonNetwork.InRoom || Character.AllCharacters.Count < PhotonNetwork.CurrentRoom.PlayerCount || !((Object)(object)Character.localCharacter != (Object)null)))
			{
				yield return (object)new WaitForSeconds(0.5f);
			}
			yield return (object)new WaitForSeconds(2f);
			if (!PhotonNetwork.IsMasterClient || Character.AllCharacters.Count == 0)
			{
				yield break;
			}
			List<Character> list = Character.AllCharacters.FindAll((Character c) => (Object)(object)c != (Object)null && !c.isBot && (Object)(object)c.player != (Object)null);
			if (list.Count != 0)
			{
				Character val = list[Random.Range(0, list.Count)];
				ItemSlot val2 = default(ItemSlot);
				if (val.player.AddItem(BathroomItems.ToiletPaperItemID, (ItemInstanceData)null, ref val2))
				{
					Plugin.Log.LogInfo((object)(val.characterName + " starts with the toilet paper."));
				}
				else
				{
					Plugin.Log.LogWarning((object)"Could not give the starting toilet paper roll.");
				}
			}
		}
	}
	internal static class StatusGainPatches
	{
		[HarmonyPatch(typeof(CharacterAfflictions), "SubtractStatus")]
		private static class Patch_HungerSubtracted
		{
			private static void Postfix(CharacterAfflictions __instance, STATUSTYPE statusType, float amount, bool fromRPC, bool decreasedNaturally)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0002: Invalid comparison between Unknown and I4
				//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
				//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
				//IL_0258: Unknown result type (might be due to invalid IL or missing references)
				//IL_027c: Unknown result type (might be due to invalid IL or missing references)
				if ((int)statusType != 1)
				{
					return;
				}
				Character character = __instance.character;
				if (!fromRPC && amount > 0f && !decreasedNaturally)
				{
					ManualLogSource log = Plugin.Log;
					string[] obj = new string[7]
					{
						string.Format("[hunger] -{0:F3} on '{1}' ", amount, ((character != null) ? character.characterName : null) ?? "?"),
						$"local={((character != null) ? new bool?(character.IsLocal) : ((bool?)null))} suppress={SuppressHungerGain} ",
						null,
						null,
						null,
						null,
						null
					};
					bool? obj2;
					if (character == null)
					{
						obj2 = null;
					}
					else
					{
						CharacterRefs refs = character.refs;
						if (refs == null)
						{
							obj2 = null;
						}
						else
						{
							CharacterAfflictions afflictions = refs.afflictions;
							obj2 = ((afflictions != null) ? new bool?(afflictions.canGetHungry) : ((bool?)null));
						}
					}
					obj[2] = $"canHunger={obj2} ";
					bool? obj3;
					if (character == null)
					{
						obj3 = null;
					}
					else
					{
						CharacterData data = character.data;
						obj3 = ((data != null) ? new bool?(data.isSkeleton) : ((bool?)null));
					}
					obj[3] = $"skeleton={obj3} ";
					obj[4] = "item='";
					object obj4;
					if (character == null)
					{
						obj4 = null;
					}
					else
					{
						CharacterData data2 = character.data;
						if (data2 == null)
						{
							obj4 = null;
						}
						else
						{
							Item currentItem = data2.currentItem;
							obj4 = ((currentItem != null) ? ((Object)currentItem).name : null);
						}
					}
					if (obj4 == null)
					{
						obj4 = "none";
					}
					obj[5] = (string)obj4;
					obj[6] = "'";
					log.LogDebug((object)string.Concat(obj));
				}
				if (fromRPC || decreasedNaturally || amount <= 0f || SuppressHungerGain || !CanProcessDigestion(character))
				{
					return;
				}
				Item currentItem2 = character.data.currentItem;
				if (!IsOurItem(currentItem2))
				{
					if (IsDrink(currentItem2))
					{
						float num = Mathf.Min(amount * BathroomConfig.PeeFromDrinkRatio.Value, BathroomConfig.PeeGainCap.Value);
						BathroomStatuses.AddModStatus(character.refs.afflictions, BathroomStatuses.Pee, BathroomStatuses.ChunkUp(num * BathroomConfig.EffectScale));
					}
					else
					{
						BathroomStatuses.AddModStatus(character.refs.afflictions, BathroomStatuses.Poo, BathroomStatuses.ChunkUp(amount * BathroomConfig.PooFromFoodRatio.Value * BathroomConfig.EffectScale));
					}
					Plugin.Log.LogInfo((object)(string.Format("Digested '{0}' (drink={1}, cured={2:F3}) ", ((Object)(object)currentItem2 != (Object)null) ? ((Object)currentItem2).name : "?", IsDrink(currentItem2), amount) + $"-> Poo={character.refs.afflictions.GetCurrentStatus(BathroomStatuses.Poo):F3} " + $"Pee={character.refs.afflictions.GetCurrentStatus(BathroomStatuses.Pee):F3}"));
				}
			}
		}

		[HarmonyPatch(typeof(Action_Consume), "RunAction")]
		private static class Patch_Consume
		{
			private static void Postfix(Action_Consume __instance)
			{
				//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e6: Invalid comparison between Unknown and I4
				//IL_016f: Unknown result type (might be due