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<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);
}
}
}
internal static class BathroomConfig
{
public static ConfigEntry<string> PooKey;
public static ConfigEntry<string> PeeKey;
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<int> 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 void Bind(ConfigFile cfg)
{
PooKey = cfg.Bind<string>("Input", "PooKey", "<Keyboard>/k", "Input System binding path held to poo.");
PeeKey = cfg.Bind<string>("Input", "PeeKey", "<Keyboard>/l", "Input System binding path held to pee.");
PooFromFoodRatio = cfg.Bind<float>("Gain", "PooFromFoodRatio", 0.5f, "Fraction of the hunger a food cures that is added as Poo.");
PeeFromDrinkRatio = cfg.Bind<float>("Gain", "PeeFromDrinkRatio", 0.5f, "Fraction of the statuses a drink cures that is added as Pee.");
PeeFallbackPerDrink = cfg.Bind<float>("Gain", "PeeFallbackPerDrink", 0.15f, "Pee added by a drink that cures no statuses at all.");
PeeGainCap = cfg.Bind<float>("Gain", "PeeGainCap", 0.5f, "Maximum Pee a single drink can add (some drinks cure huge amounts).");
ActionThreshold = cfg.Bind<float>("Actions", "ActionThreshold", 1f / 3f, "Minimum fill (fraction of the stamina bar) of Poo/Pee before you can relieve yourself.");
SecondsPerFullBar = cfg.Bind<float>("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<float>("Actions", "MovementEpsilon", 0.35f, "Velocity above which you no longer count as standing still.");
PeeDrainPerSecond = cfg.Bind<float>("Actions", "PeeDrainPerSecond", 0.1f, "Pee removed per second while peeing (0.1 = full bar in 10s).");
PooMoveSpeedMultiplier = cfg.Bind<float>("Actions", "PooMoveSpeedMultiplier", 0.25f, "Movement force multiplier while pooping (stacks with the 50% crouch penalty).");
PooBaseDiameter = cfg.Bind<float>("PooItem", "PooBaseDiameter", 0.35f, "World diameter of a default (33%) poo. Roughly half a Bing Bong.");
PooCarryStink = cfg.Bind<float>("PooItem", "PooCarryStink", 0.1f, "Stink status per poo carried (hands or main three slots); removed when dropped. Stacks per poo.");
EatTimeRatio = cfg.Bind<float>("PooItem", "EatTimeRatio", 0.5f, "Eating a poo takes its poo-time multiplied by this (default: half).");
EatPoisonRatio = cfg.Bind<float>("PooItem", "EatPoisonRatio", 0.5f, "Poison given when eating a poo = original poo amount times this.");
DirtyPerPoo = cfg.Bind<float>("Dirty", "DirtyPerPoo", 0.05f, "Dirty status applied after pooping.");
DirtyPerWipe = cfg.Bind<float>("Dirty", "DirtyPerWipe", 0.05f, "Dirty status removed per toilet paper wipe.");
ToiletPaperUses = cfg.Bind<int>("Dirty", "ToiletPaperUses", 5, "Wipes per toilet paper roll.");
TPChanceBigLuggage = cfg.Bind<float>("Dirty", "TPChanceBigLuggage", 0.03f, "Chance a Big Luggage has one of its items replaced with toilet paper.");
TPChanceExplorerLuggage = cfg.Bind<float>("Dirty", "TPChanceExplorerLuggage", 0.25f, "Chance an Explorer's Luggage has one of its items replaced with toilet paper.");
GiveStartingToiletPaper = cfg.Bind<bool>("Dirty", "GiveStartingToiletPaper", true, "One random player starts the run with a toilet paper roll.");
PuddleMaxDiameter = cfg.Bind<float>("Puddle", "PuddleMaxDiameter", 1.2f, "Maximum pee puddle diameter (about a beached jellyfish).");
PuddleFullAmount = cfg.Bind<float>("Puddle", "PuddleFullAmount", 1f, "Amount of pee (bar fraction) that grows a puddle to maximum size.");
PuddleLifetime = cfg.Bind<float>("Puddle", "PuddleLifetime", 0f, "Seconds before a puddle dries up. 0 = never.");
MaxPoos = cfg.Bind<int>("Performance", "MaxPoos", 40, "Most poos allowed to exist at once (oldest on the ground is removed past this). 0 = unlimited.");
MaxPuddles = cfg.Bind<int>("Performance", "MaxPuddles", 20, "Most of your own pee puddles allowed at once (oldest is removed past this). 0 = unlimited.");
SkeletonsDontGoToBathroom = cfg.Bind<bool>("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<bool>("Interactions", "CureAllRemovesPooPee", true, "Cure-All (and other 'clear all status' items) also remove Poo and Pee.");
PandoraRollsPooPee = cfg.Bind<bool>("Interactions", "PandoraRollsPooPee", true, "Pandora's Lunchbox clears Poo/Pee and can randomly re-roll them like other statuses.");
PandoraPooPeeChance = cfg.Bind<float>("Interactions", "PandoraPooPeeChance", 0.5f, "Chance (0-1) that Pandora's Lunchbox rolls each of Poo and Pee.");
ToiletPaperItemID = cfg.Bind<int>("ItemIDs", "ToiletPaperItemID", 61001, "Item database ID for toilet paper. Must match on all players.");
PooItemID = cfg.Bind<int>("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<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_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<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.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<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 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<BarAffliction> list = new List<BarAffliction>(__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<GameObject>(((Component)template).gameObject, ((Component)template).transform.parent);
((Object)val).name = $"BarAffliction_INTP_{(int)type}";
BarAffliction component = val.GetComponent<BarAffliction>();
component.afflictionType = type;
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 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<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_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<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_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<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)83901440;
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_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<PhotonView>();
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<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 & 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<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.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<FloatItemData>((DataEntryKey)200, (Func<FloatItemData>)(() => 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<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, 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<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_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<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);
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(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<Item>();
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<Item>();
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<Item>();
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<Action_ModifyStatus>();
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<Action_RestoreHunger>();
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<ItemUseFeedback>();
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<PooItem>() != (Object)null))
{
return (Object)(object)((Component)item).GetComponent<ToiletPaperWipe>() != (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<Item>();
}
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<object>());
}
}
}
}
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
internal sealed class IgnoresAccessChecksToAttribute : Attribute
{
public IgnoresAccessChecksToAttribute(string assemblyName)
{
}
}
}