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.InputSystem; 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.1.5.0")] [assembly: AssemblyInformationalVersion("0.1.5+f5ffbccd492ba21b1b70a0852145dce5e7ab7202")] [assembly: AssemblyProduct("INeedToPEEak")] [assembly: AssemblyTitle("INeedToPEEak")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.1.5.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_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: 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_00f5: 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.63f, 0.1f); FillCircle(val, 32f * num, 22f * num, 17f * num, color); FillCircle(val, 32f * num, 22f * num, 15f * num, PeeYellow); for (int i = 0; i < 22; i++) { float num2 = (float)i / 22f; float cy = (38f + num2 * 18f) * num; float num3 = Mathf.Lerp(11f, 1.2f, num2) * num; FillCircle(val, 32f * num, cy, num3 + 1.5f * num, color); FillCircle(val, 32f * num, cy, num3, PeeYellow); } FillCircle(val, 27f * num, 25f * num, 3.2f * num, new Color(1f, 1f, 0.85f)); val.Apply(); return val; } 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 Poos = new List(); private static readonly List Puddles = new List(); 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 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(); if ((Object)(object)component == (Object)null || !component.IsMine) { list.RemoveAt(num); continue; } Item component2 = val.GetComponent(); if ((Object)(object)component2 != (Object)null && (int)component2.itemState != 0) { num++; continue; } list.RemoveAt(num); PhotonNetwork.Destroy(val); } } } internal static class BathroomConfig { public static ConfigEntry PooKey; public static ConfigEntry PeeKey; public static ConfigEntry PooFromFoodRatio; public static ConfigEntry PeeFromDrinkRatio; public static ConfigEntry PeeFallbackPerDrink; public static ConfigEntry PeeGainCap; public static ConfigEntry ActionThreshold; public static ConfigEntry SecondsPerFullBar; public static ConfigEntry MovementEpsilon; public static ConfigEntry PeeDrainPerSecond; public static ConfigEntry PooMoveSpeedMultiplier; public static ConfigEntry PooBaseDiameter; public static ConfigEntry PooCarryStink; public static ConfigEntry EatTimeRatio; public static ConfigEntry EatPoisonRatio; public static ConfigEntry DirtyPerPoo; public static ConfigEntry DirtyPerWipe; public static ConfigEntry ToiletPaperUses; public static ConfigEntry TPChanceBigLuggage; public static ConfigEntry TPChanceExplorerLuggage; public static ConfigEntry GiveStartingToiletPaper; public static ConfigEntry PuddleMaxDiameter; public static ConfigEntry PuddleFullAmount; public static ConfigEntry PuddleLifetime; public static ConfigEntry MaxPoos; public static ConfigEntry MaxPuddles; public static ConfigEntry SkeletonsDontGoToBathroom; public static ConfigEntry CureAllRemovesPooPee; public static ConfigEntry PandoraRollsPooPee; public static ConfigEntry PandoraPooPeeChance; public static ConfigEntry ToiletPaperItemID; public static ConfigEntry PooItemID; public static void Bind(ConfigFile cfg) { PooKey = cfg.Bind("Input", "PooKey", "/k", "Input System binding path held to poo."); PeeKey = cfg.Bind("Input", "PeeKey", "/l", "Input System binding path held to pee."); PooFromFoodRatio = cfg.Bind("Gain", "PooFromFoodRatio", 0.5f, "Fraction of the hunger a food cures that is added as Poo."); PeeFromDrinkRatio = cfg.Bind("Gain", "PeeFromDrinkRatio", 0.5f, "Fraction of the statuses a drink cures that is added as Pee."); PeeFallbackPerDrink = cfg.Bind("Gain", "PeeFallbackPerDrink", 0.15f, "Pee added by a drink that cures no statuses at all."); PeeGainCap = cfg.Bind("Gain", "PeeGainCap", 0.5f, "Maximum Pee a single drink can add (some drinks cure huge amounts)."); ActionThreshold = cfg.Bind("Actions", "ActionThreshold", 1f / 3f, "Minimum fill (fraction of the stamina bar) of Poo/Pee before you can relieve yourself."); SecondsPerFullBar = cfg.Bind("Actions", "SecondsPerFullBar", 10f, "Seconds it takes to poo a FULL bar. 33% poo => ~3.3s, 85% => 8.5s. Pee drains at the same rate."); MovementEpsilon = cfg.Bind("Actions", "MovementEpsilon", 0.35f, "Velocity above which you no longer count as standing still."); PeeDrainPerSecond = cfg.Bind("Actions", "PeeDrainPerSecond", 0.1f, "Pee removed per second while peeing (0.1 = full bar in 10s)."); PooMoveSpeedMultiplier = cfg.Bind("Actions", "PooMoveSpeedMultiplier", 0.25f, "Movement force multiplier while pooping (stacks with the 50% crouch penalty)."); PooBaseDiameter = cfg.Bind("PooItem", "PooBaseDiameter", 0.35f, "World diameter of a default (33%) poo. Roughly half a Bing Bong."); PooCarryStink = cfg.Bind("PooItem", "PooCarryStink", 0.1f, "Stink status per poo carried (hands or main three slots); removed when dropped. Stacks per poo."); EatTimeRatio = cfg.Bind("PooItem", "EatTimeRatio", 0.5f, "Eating a poo takes its poo-time multiplied by this (default: half)."); EatPoisonRatio = cfg.Bind("PooItem", "EatPoisonRatio", 0.5f, "Poison given when eating a poo = original poo amount times this."); DirtyPerPoo = cfg.Bind("Dirty", "DirtyPerPoo", 0.05f, "Dirty status applied after pooping."); DirtyPerWipe = cfg.Bind("Dirty", "DirtyPerWipe", 0.05f, "Dirty status removed per toilet paper wipe."); ToiletPaperUses = cfg.Bind("Dirty", "ToiletPaperUses", 5, "Wipes per toilet paper roll."); TPChanceBigLuggage = cfg.Bind("Dirty", "TPChanceBigLuggage", 0.03f, "Chance a Big Luggage has one of its items replaced with toilet paper."); TPChanceExplorerLuggage = cfg.Bind("Dirty", "TPChanceExplorerLuggage", 0.25f, "Chance an Explorer's Luggage has one of its items replaced with toilet paper."); GiveStartingToiletPaper = cfg.Bind("Dirty", "GiveStartingToiletPaper", true, "One random player starts the run with a toilet paper roll."); PuddleMaxDiameter = cfg.Bind("Puddle", "PuddleMaxDiameter", 1.2f, "Maximum pee puddle diameter (about a beached jellyfish)."); PuddleFullAmount = cfg.Bind("Puddle", "PuddleFullAmount", 1f, "Amount of pee (bar fraction) that grows a puddle to maximum size."); PuddleLifetime = cfg.Bind("Puddle", "PuddleLifetime", 0f, "Seconds before a puddle dries up. 0 = never."); MaxPoos = cfg.Bind("Performance", "MaxPoos", 40, "Most poos allowed to exist at once (oldest on the ground is removed past this). 0 = unlimited."); MaxPuddles = cfg.Bind("Performance", "MaxPuddles", 20, "Most of your own pee puddles allowed at once (oldest is removed past this). 0 = unlimited."); SkeletonsDontGoToBathroom = cfg.Bind("Interactions", "SkeletonsDontGoToBathroom", true, "Skeletons (revived via the Book of Bones) don't gain Poo/Pee, just like they don't get hungry."); CureAllRemovesPooPee = cfg.Bind("Interactions", "CureAllRemovesPooPee", true, "Cure-All (and other 'clear all status' items) also remove Poo and Pee."); PandoraRollsPooPee = cfg.Bind("Interactions", "PandoraRollsPooPee", true, "Pandora's Lunchbox clears Poo/Pee and can randomly re-roll them like other statuses."); PandoraPooPeeChance = cfg.Bind("Interactions", "PandoraPooPeeChance", 0.5f, "Chance (0-1) that Pandora's Lunchbox rolls each of Poo and Pee."); ToiletPaperItemID = cfg.Bind("ItemIDs", "ToiletPaperItemID", 61001, "Item database ID for toilet paper. Must match on all players."); PooItemID = cfg.Bind("ItemIDs", "PooItemID", 61002, "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 Postfix(Action_ClearAllStatus __instance) { if (BathroomConfig.CureAllRemovesPooPee.Value) { Item component = ((Component)__instance).GetComponent(); 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(value, position, rotation); } return fallback.Instantiate(prefabId, position, rotation); } public void Destroy(GameObject gameObject) { if ((Object)(object)gameObject != (Object)null && ((Object)(object)gameObject.GetComponent() != (Object)null || (Object)(object)gameObject.GetComponent() != (Object)null || (Object)(object)gameObject.GetComponent() != (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 Prefabs = new Dictionary(); 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().sharedMesh; Object.Destroy((Object)(object)obj); GameObject obj2 = GameObject.CreatePrimitive((PrimitiveType)2); cylinderMesh = obj2.GetComponent().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().sharedMesh = mesh; ((Renderer)val.AddComponent()).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(); obj.OwnershipTransfer = (OwnershipOption)1; obj.Synchronization = (ViewSynchronization)3; obj.observableSearch = (ObservableSearch)0; obj.ObservedComponents = new List(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(); obj.center = new Vector3(0f, 0.5f, 0f); obj.size = new Vector3(0.95f, 1f, 0.95f); val.AddComponent().angularDamping = 3f; ItemPhysicsSyncer val2 = val.AddComponent(); AddPhotonView(val, (Component)val2); Item obj2 = val.AddComponent(); 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(); ((ItemAction)obj3).OnPressed = true; obj3.animationName = "PlayerEat"; val.AddComponent(); 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_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_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_0162: 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().radius = 0.154f; val.AddComponent(); ItemPhysicsSyncer val2 = val.AddComponent(); AddPhotonView(val, (Component)val2); ToiletPaperItem toiletPaperItem = val.AddComponent(); ((Item)toiletPaperItem).itemID = ToiletPaperItemID; ((Item)toiletPaperItem).mass = 4f; ((Item)toiletPaperItem).usingTimePrimary = 1.2f; ((Item)toiletPaperItem).totalUses = BathroomConfig.ToiletPaperUses.Value; ((Item)toiletPaperItem).UIData = new ItemUIData { itemName = "Toilet Paper", icon = BathroomAssets.ToiletPaperItemIcon, mainInteractPrompt = "Wipe", canDrop = true, canPocket = true, canBackpack = true, canThrow = true }; val.AddComponent().consumeOnFullyUsed = true; val.AddComponent(); 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(); ((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(); AddPhotonView(val, (Component)peePuddle); return val; } public static IEnumerator RegisterItemsWhenReady() { ItemDatabase database = null; while ((Object)(object)database == (Object)null) { try { database = SingletonAsset.Instance; } catch { } if ((Object)(object)database == (Object)null) { yield return (object)new WaitForSeconds(0.5f); } } RegisterItem(database, pooPrefab.GetComponent()); RegisterItem(database, tpPrefab.GetComponent()); 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> mainTable = LocalizedText.mainTable; if (!mainTable.ContainsKey(key)) { int num = Enum.GetNames(typeof(Language)).Length; List list = new List(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 item in database.itemLookup) { Item value = item.Value; if ((Object)(object)value == (Object)null || (Object)(object)((Component)value).GetComponent() != (Object)null || (Object)(object)((Component)value).GetComponent() != (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(); 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)(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 void Postfix(CharacterAfflictions __instance) { __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); } } [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_0003: Invalid comparison between Unknown and I4 if ((int)type >= 12) { __result = 1f; } } } [HarmonyPatch(typeof(StaminaBar), "Start")] private static class Patch_StaminaBarStart { private static void Postfix(StaminaBar __instance) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Invalid comparison between Unknown and I4 //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) try { if (__instance.afflictions == null || __instance.afflictions.Length == 0) { return; } BarAffliction[] afflictions = __instance.afflictions; for (int i = 0; i < afflictions.Length; i++) { if ((int)afflictions[i].afflictionType >= 12) { return; } } BarAffliction template = __instance.afflictions[0]; List list = new List(__instance.afflictions); list.Add(CloneSegment(template, Poo, PooColor, BathroomAssets.PooIcon)); list.Add(CloneSegment(template, Pee, PeeColor, BathroomAssets.PeeIcon)); list.Add(CloneSegment(template, Dirty, DirtyColor, BathroomAssets.DirtyIcon)); list.Add(CloneSegment(template, Stink, StinkColor, BathroomAssets.StinkIcon)); __instance.afflictions = list.ToArray(); } catch (Exception arg) { Plugin.Log.LogError((object)$"Failed to extend stamina bar UI: {arg}"); } } 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_0023: Expected I4, but got Unknown //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0081: 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) GameObject val = Object.Instantiate(((Component)template).gameObject, ((Component)template).transform.parent); ((Object)val).name = $"BarAffliction_INTP_{(int)type}"; BarAffliction component = val.GetComponent(); component.afflictionType = type; Image[] componentsInChildren = val.GetComponentsInChildren(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 const int VanillaCount = 12; public static readonly STATUSTYPE Poo = (STATUSTYPE)12; public static readonly STATUSTYPE Pee = (STATUSTYPE)13; public static readonly STATUSTYPE Dirty = (STATUSTYPE)14; public static readonly STATUSTYPE Stink = (STATUSTYPE)15; public const int TotalCount = 16; 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); private static float[] Grow(float[] arr) { if (arr == null || arr.Length >= 16) { return arr; } float[] array = new float[16]; 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(); } 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_00db: 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 flag = Plugin.PooAction != null && Plugin.PooAction.IsPressed(); bool flag2 = Plugin.PeeAction != null && Plugin.PeeAction.IsPressed(); 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.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_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0064: 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_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: 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); Afflictions.AddStatus(BathroomStatuses.Dirty, BathroomConfig.DirtyPerPoo.Value, false, true, true); 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() : 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(); 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()).material = BathroomAssets.PuddleMaterial; peeStream.Stop(true, (ParticleSystemStopBehavior)0); } } private void UpdateCarriedPooStink() { //IL_00c9: 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; } 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, 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() == (Object)null) { ((Component)__instance).gameObject.AddComponent(); PhotonView component = ((Component)__instance).GetComponent(); 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)83901440; private static void Postfix(Spawner __instance, List spawnSpots, List __result) { //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_0137: 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_0178: 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 || __result == null || __result.Count == 0) { return; } int index = Random.Range(0, __result.Count); PhotonView val2 = __result[index]; if (!((Object)(object)val2 == (Object)null)) { Vector3 position = ((Component)val2).transform.position; Quaternion rotation = ((Component)val2).transform.rotation; __result.RemoveAt(index); PhotonNetwork.Destroy(((Component)val2).gameObject); GameObject val3 = PhotonNetwork.InstantiateRoomObject("0_Items/INTP_ToiletPaper", position, rotation, (byte)0, (object[])null); if ((Object)(object)val3 != (Object)null) { PhotonView component = val3.GetComponent(); component.RPC("SetKinematicRPC", (RpcTarget)3, new object[3] { true, position, rotation }); __result.Add(component); Plugin.Log.LogInfo((object)("Toilet paper replaced an item in " + ((Object)((Component)val).gameObject).name)); } else { Plugin.Log.LogError((object)"Toilet paper InstantiateRoomObject returned null!"); } } } private static float GetToiletPaperChance(Luggage luggage, List 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 & 0x5003C00) != 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(); 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.1.5")] public class Plugin : BaseUnityPlugin { public const string PluginGuid = "com.exoflex.ineedtopeeak"; public const string PluginName = "INeedToPEEak"; public const string PluginVersion = "0.1.5"; private Harmony harmony; internal static Plugin Instance { get; private set; } internal static ManualLogSource Log { get; private set; } internal static InputAction PooAction { get; private set; } internal static InputAction PeeAction { get; private set; } private void Awake() { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Expected O, but got Unknown //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; ((MonoBehaviour)this).useGUILayout = false; BathroomConfig.Bind(((BaseUnityPlugin)this).Config); BathroomAssets.CreateAll(); BathroomItems.Initialize(); PooAction = new InputAction("INTP_Poo", (InputActionType)1, BathroomConfig.PooKey.Value, (string)null, (string)null, (string)null); PeeAction = new InputAction("INTP_Pee", (InputActionType)1, BathroomConfig.PeeKey.Value, (string)null, (string)null, (string)null); PooAction.Enable(); PeeAction.Enable(); 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.1.5 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(); } InputAction pooAction = PooAction; if (pooAction != null) { pooAction.Disable(); } InputAction peeAction = PeeAction; if (peeAction != null) { peeAction.Disable(); } } } 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)base.photonView != (Object)null && base.photonView.IsMine) { base.item.GetData((DataEntryKey)200, (Func)(() => new FloatItemData { Value = pooAmount })).Value = pooAmount; if (base.item.data != null) { base.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((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(); } 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, 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; base.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(); PhotonView val = PhotonView.Find(viewID); if ((Object)(object)component != (Object)null && (Object)(object)val != (Object)null) { Character component2 = ((Component)val).GetComponent(); 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_0055: Unknown result type (might be due to invalid IL or missing references) //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_0069: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: 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_009b: 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_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) PhotonView val = PhotonView.Find(viewID); if (!((Object)(object)val == (Object)null)) { Character component = ((Component)val).GetComponent(); 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); 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 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(Action_ModifyStatus), "RunAction")] private static class Patch_ModifyStatus { private static void Postfix(Action_ModifyStatus __instance) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 if ((int)__instance.statusType == 1 && !(__instance.changeAmount >= 0f)) { Item component = ((Component)__instance).GetComponent(); AddDigestion(((Object)(object)component != (Object)null) ? component.holderCharacter : null, component, Mathf.Abs(__instance.changeAmount)); } } } [HarmonyPatch(typeof(Action_RestoreHunger), "RunAction")] private static class Patch_RestoreHunger { private static void Postfix(Action_RestoreHunger __instance) { if (!(__instance.restorationAmount <= 0f)) { Item component = ((Component)__instance).GetComponent(); AddDigestion(((Object)(object)component != (Object)null) ? component.holderCharacter : null, component, __instance.restorationAmount); } } } [HarmonyPatch(typeof(Action_Consume), "RunAction")] private static class Patch_Consume { private static void Postfix(Action_Consume __instance) { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Invalid comparison between Unknown and I4 //IL_00e9: Unknown result type (might be due to invalid IL or missing references) Item component = ((Component)__instance).GetComponent(); if ((Object)(object)component == (Object)null || !IsDrink(component) || IsOurItem(component)) { return; } Character holderCharacter = component.holderCharacter; if (!CanProcessDigestion(holderCharacter)) { return; } float num = 0f; Action_ModifyStatus[] components = ((Component)component).GetComponents(); foreach (Action_ModifyStatus val in components) { if (!(val.changeAmount >= 0f)) { if ((int)val.statusType == 1) { return; } num += Mathf.Abs(val.changeAmount); } } Action_RestoreHunger[] components2 = ((Component)component).GetComponents(); for (int i = 0; i < components2.Length; i++) { if (components2[i].restorationAmount > 0f) { return; } } float num2 = ((num > 0f) ? Mathf.Min(num * BathroomConfig.PeeFromDrinkRatio.Value, BathroomConfig.PeeGainCap.Value) : BathroomConfig.PeeFallbackPerDrink.Value); holderCharacter.refs.afflictions.AddStatus(BathroomStatuses.Pee, num2, false, true, true); } } internal static bool IsDrink(Item item) { if ((Object)(object)item == (Object)null) { return false; } ItemUseFeedback component = ((Component)item).GetComponent(); if ((Object)(object)component != (Object)null && !string.IsNullOrEmpty(component.useAnimation)) { return component.useAnimation.ToLowerInvariant().Contains("drink"); } return false; } private static bool IsOurItem(Item item) { if ((Object)(object)item != (Object)null) { if (!((Object)(object)((Component)item).GetComponent() != (Object)null)) { return (Object)(object)((Component)item).GetComponent() != (Object)null; } return true; } return false; } internal static bool CanProcessDigestion(Character character) { if ((Object)(object)character == (Object)null || !character.IsLocal) { return false; } if (BathroomConfig.SkeletonsDontGoToBathroom.Value && character.data.isSkeleton) { return false; } return character.refs.afflictions.canGetHungry; } private static void AddDigestion(Character character, Item item, float hungerCured) { //IL_0063: 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) if (CanProcessDigestion(character) && !(hungerCured <= 0f) && !IsOurItem(item)) { if (IsDrink(item)) { float num = Mathf.Min(hungerCured * BathroomConfig.PeeFromDrinkRatio.Value, BathroomConfig.PeeGainCap.Value); character.refs.afflictions.AddStatus(BathroomStatuses.Pee, num, false, true, true); } else { character.refs.afflictions.AddStatus(BathroomStatuses.Poo, hungerCured * BathroomConfig.PooFromFoodRatio.Value, false, true, true); } } } } public class ToiletPaperItem : Item { public override bool CanUsePrimary() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) if (!((Item)this).CanUsePrimary()) { return false; } Character holderCharacter = ((Item)this).holderCharacter; if (!((Object)(object)holderCharacter == (Object)null)) { return holderCharacter.refs.afflictions.GetCurrentStatus(BathroomStatuses.Dirty) > 0.001f; } return true; } } public class ToiletPaperWipe : MonoBehaviourPun { private Item item; private void Awake() { item = ((Component)this).GetComponent(); } private void Start() { Item obj = item; obj.OnPrimaryFinishedCast = (Action)Delegate.Combine(obj.OnPrimaryFinishedCast, new Action(OnWipe)); } private void OnDestroy() { if ((Object)(object)item != (Object)null) { Item obj = item; obj.OnPrimaryFinishedCast = (Action)Delegate.Remove(obj.OnPrimaryFinishedCast, new Action(OnWipe)); } } private void OnWipe() { //IL_0029: Unknown result type (might be due to invalid IL or missing references) Character holderCharacter = item.holderCharacter; if (!((Object)(object)holderCharacter == (Object)null) && holderCharacter.IsLocal) { holderCharacter.refs.afflictions.SubtractStatus(BathroomStatuses.Dirty, BathroomConfig.DirtyPerWipe.Value, false, false); ((MonoBehaviourPun)this).photonView.RPC("ReduceUsesRPC", (RpcTarget)0, Array.Empty()); } } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }