using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using System.Threading; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.Networking; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("WatchOutBro")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("3.0.1.0")] [assembly: AssemblyInformationalVersion("3.0.1+1620dd75f15e79ec40dd24dea94795bc73e00731")] [assembly: AssemblyProduct("WatchOutBro")] [assembly: AssemblyTitle("WatchOutBro")] [assembly: AssemblyVersion("3.0.1.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.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 WatchOutBro { public class AmbientPlayer : MonoBehaviour { private const float PollSeconds = 1f; private const string AmbientKey = "mommy_asmr_loop"; private float _nextCheck; private bool _lastShouldPlay; private void Update() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) if (Time.unscaledTime < _nextCheck) { return; } _nextCheck = Time.unscaledTime + 1f; Scene activeScene = SceneManager.GetActiveScene(); bool flag = IsAmbientScene(((Scene)(ref activeScene)).name) && Voices.Has("mommy_asmr_loop"); if (flag) { Voices.PlayLoop("mommy_asmr_loop"); if (!_lastShouldPlay) { Plugin.Log.LogInfo((object)("[wob] ambient on for scene '" + ((Scene)(ref activeScene)).name + "'")); } } else { Voices.StopLoop(); if (_lastShouldPlay) { Plugin.Log.LogInfo((object)("[wob] ambient off (scene '" + ((Scene)(ref activeScene)).name + "')")); } } _lastShouldPlay = flag; } private static bool IsAmbientScene(string name) { if (string.IsNullOrEmpty(name)) { return false; } string text = name.ToLowerInvariant(); if (!text.Contains("menu") && !text.Contains("lobby") && !text.Contains("truck")) { return text.Contains("main"); } return true; } } internal static class Assets { public static Texture2D Cat = null; public static Texture2D Warning = null; public static Texture2D Bubble = null; private static readonly Dictionary _iconCache = new Dictionary(); public static void Load() { Cat = LoadEmbedded("WatchOutBro.assets.cat.png"); Warning = MakeWarningTriangle(128); Bubble = MakeWhitePixel(); _iconCache[IconKind.Cat] = Cat; _iconCache[IconKind.Exclam] = Warning; } public static Texture2D Icon(IconKind kind) { if (_iconCache.TryGetValue(kind, out var value)) { return value; } Texture2D val = (Texture2D)(kind switch { IconKind.ShushFace => MakeShushFace(256), IconKind.Skull => MakeSkull(192), IconKind.Duck => MakeDuck(192), IconKind.Boom => MakeBoom(192), IconKind.Knife => MakeKnife(192), IconKind.Eye => MakeEye(192), IconKind.Question => MakeQuestion(192), IconKind.Brain => MakeBrain(192), IconKind.WK => MakeWK(256), IconKind.NoseShaver => MakeNoseShaver(192), IconKind.Beam => MakeBeam(256), _ => Warning, }); _iconCache[kind] = val; return val; } private static Texture2D LoadEmbedded(string resourceName) { //IL_003d: 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: Expected O, but got Unknown //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Expected O, but got Unknown using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName); if (stream == null) { Plugin.Log.LogError((object)("Embedded resource not found: " + resourceName)); return MakeWhitePixel(); } using MemoryStream memoryStream = new MemoryStream(); stream.CopyTo(memoryStream); Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false); ImageConversion.LoadImage(val, memoryStream.ToArray()); ((Texture)val).filterMode = (FilterMode)1; return val; } private static Texture2D MakeWhitePixel() { //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_000c: 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) //IL_001d: Expected O, but got Unknown Texture2D val = new Texture2D(1, 1, (TextureFormat)4, false); val.SetPixel(0, 0, Color.white); val.Apply(); return val; } private static Texture2D Blank(int size, out Color[] px) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Expected O, but got Unknown Texture2D val = new Texture2D(size, size, (TextureFormat)4, false); px = (Color[])(object)new Color[size * size]; return val; } private static void Apply(Texture2D tex, Color[] px) { tex.SetPixels(px); ((Texture)tex).filterMode = (FilterMode)1; tex.Apply(); } private static bool InCircle(float fx, float fy, float cx, float cy, float r) { return (fx - cx) * (fx - cx) + (fy - cy) * (fy - cy) < r * r; } private static bool InEllipse(float fx, float fy, float cx, float cy, float rx, float ry) { float num = (fx - cx) / rx; float num2 = (fy - cy) / ry; return num * num + num2 * num2 < 1f; } private static bool InRect(float fx, float fy, float x0, float y0, float x1, float y1) { if (fx >= x0 && fx <= x1 && fy >= y0) { return fy <= y1; } return false; } private static Texture2D MakeWarningTriangle(int size) { //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_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) Color[] px; Texture2D val = Blank(size, out px); Color val2 = default(Color); ((Color)(ref val2))..ctor(1f, 0.82f, 0.04f, 1f); Color black = Color.black; Color val3 = default(Color); ((Color)(ref val3))..ctor(0f, 0f, 0f, 0f); for (int i = 0; i < size; i++) { for (int j = 0; j < size; j++) { float num = (float)j / (float)(size - 1); float num2 = (float)i / (float)(size - 1); float num3 = 0.5f * (1f - num2); float num4 = 1f - num3; if (!(num >= num3) || !(num <= num4) || !(num2 >= 0.06f) || !(num2 <= 0.96f)) { px[i * size + j] = val3; continue; } float num5 = (num - num3) * (float)size; float num6 = (num4 - num) * (float)size; float num7 = (num2 - 0.06f) * (float)size; if (Mathf.Min(num5, Mathf.Min(num6, num7)) < 4f) { px[i * size + j] = black; continue; } bool flag = Mathf.Abs(num - 0.5f) < 0.04f && num2 > 0.3f && num2 < 0.72f; bool flag2 = (num - 0.5f) * (num - 0.5f) + (num2 - 0.2f) * (num2 - 0.2f) < 0.0035f; px[i * size + j] = ((flag || flag2) ? black : val2); } } Apply(val, px); return val; } private static Texture2D MakeShushFace(int size) { //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_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_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: 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_02aa: Unknown result type (might be due to invalid IL or missing references) //IL_02ac: Unknown result type (might be due to invalid IL or missing references) //IL_0292: Unknown result type (might be due to invalid IL or missing references) //IL_0293: Unknown result type (might be due to invalid IL or missing references) //IL_028c: Unknown result type (might be due to invalid IL or missing references) //IL_028e: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0129: 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_0155: Unknown result type (might be due to invalid IL or missing references) //IL_029e: Unknown result type (might be due to invalid IL or missing references) //IL_02a0: 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_0181: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) Color[] px; Texture2D val = Blank(size, out px); Color val2 = default(Color); ((Color)(ref val2))..ctor(1f, 0.85f, 0.7f, 1f); Color val3 = default(Color); ((Color)(ref val3))..ctor(0.95f, 0.78f, 0.62f, 1f); Color val4 = default(Color); ((Color)(ref val4))..ctor(1f, 0.7f, 0.7f, 1f); Color black = Color.black; Color val5 = default(Color); ((Color)(ref val5))..ctor(0.85f, 0.3f, 0.4f, 1f); Color val6 = default(Color); ((Color)(ref val6))..ctor(0f, 0f, 0f, 0f); for (int i = 0; i < size; i++) { for (int j = 0; j < size; j++) { float num = (float)j / (float)(size - 1); float num2 = (float)i / (float)(size - 1); Color val7 = val6; if (InCircle(num, num2, 0.5f, 0.5f, 0.46f)) { val7 = (InCircle(num, num2, 0.5f, 0.5f, 0.448f) ? val2 : black); if (Mathf.Abs(num - 0.36f) < 0.07f && Mathf.Abs(num2 - 0.62f) < 0.012f) { val7 = black; } if (Mathf.Abs(num - 0.64f) < 0.07f && Mathf.Abs(num2 - 0.62f) < 0.012f) { val7 = black; } if (Mathf.Abs(num - 0.36f) < 0.08f && Mathf.Abs(num2 - 0.7f) < 0.01f) { val7 = black; } if (Mathf.Abs(num - 0.64f) < 0.08f && Mathf.Abs(num2 - 0.7f) < 0.01f) { val7 = black; } if (InEllipse(num, num2, 0.5f, 0.32f, 0.07f, 0.025f)) { val7 = val5; } } if (((InRect(num, num2, 0.46f, 0.05f, 0.54f, 0.42f) && InCircle(num, num2, 0.5f, 0.42f, 0.06f)) || InRect(num, num2, 0.46f, 0.05f, 0.54f, 0.4f)) && (InRect(num, num2, 0.46f, 0.05f, 0.54f, 0.4f) || InCircle(num, num2, 0.5f, 0.4f, 0.04f))) { val7 = ((!(Mathf.Min(Mathf.Abs(num - 0.46f), Mathf.Abs(num - 0.54f)) * (float)size < 2f)) ? val3 : black); if (num2 < 0.1f) { val7 = val4; } } px[i * size + j] = val7; } } Apply(val, px); return val; } private static Texture2D MakeSkull(int size) { //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_0069: 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_008c: 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_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00af: 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_015e: 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_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0217: Unknown result type (might be due to invalid IL or missing references) //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: 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_020c: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) Color[] px; Texture2D val = Blank(size, out px); Color val2 = default(Color); ((Color)(ref val2))..ctor(0.95f, 0.95f, 0.92f, 1f); Color black = Color.black; Color val3 = default(Color); ((Color)(ref val3))..ctor(0f, 0f, 0f, 0f); for (int i = 0; i < size; i++) { for (int j = 0; j < size; j++) { float num = (float)j / (float)(size - 1); float num2 = (float)i / (float)(size - 1); Color val4 = val3; if (InEllipse(num, num2, 0.5f, 0.55f, 0.42f, 0.4f)) { val4 = val2; } if (InRect(num, num2, 0.3f, 0.18f, 0.7f, 0.4f)) { val4 = val2; } if (val4 == val2 && !InEllipse(num, num2, 0.5f, 0.55f, 0.4f, 0.38f) && !InRect(num, num2, 0.32f, 0.2f, 0.68f, 0.38f) && (InEllipse(num, num2, 0.5f, 0.55f, 0.42f, 0.4f) || InRect(num, num2, 0.3f, 0.18f, 0.7f, 0.4f))) { val4 = black; } if (InCircle(num, num2, 0.36f, 0.55f, 0.08f)) { val4 = black; } if (InCircle(num, num2, 0.64f, 0.55f, 0.08f)) { val4 = black; } if (Mathf.Abs(num - 0.5f) < 0.04f * (1f - Mathf.InverseLerp(0.32f, 0.45f, num2)) && num2 > 0.32f && num2 < 0.45f) { val4 = black; } if (num2 > 0.2f && num2 < 0.34f && (Mathf.Abs(num - 0.42f) < 0.012f || Mathf.Abs(num - 0.5f) < 0.012f || Mathf.Abs(num - 0.58f) < 0.012f)) { val4 = black; } px[i * size + j] = val4; } } Apply(val, px); return val; } private static Texture2D MakeDuck(int size) { //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_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_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: 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_0139: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0110: 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) Color[] px; Texture2D val = Blank(size, out px); Color val2 = default(Color); ((Color)(ref val2))..ctor(1f, 0.85f, 0.1f, 1f); Color val3 = default(Color); ((Color)(ref val3))..ctor(1f, 0.55f, 0.05f, 1f); Color black = Color.black; Color val4 = default(Color); ((Color)(ref val4))..ctor(0f, 0f, 0f, 0f); for (int i = 0; i < size; i++) { for (int j = 0; j < size; j++) { float num = (float)j / (float)(size - 1); float num2 = (float)i / (float)(size - 1); Color val5 = val4; if (InEllipse(num, num2, 0.45f, 0.32f, 0.34f, 0.22f)) { val5 = val2; } if (InCircle(num, num2, 0.62f, 0.62f, 0.18f)) { val5 = val2; } if (InRect(num, num2, 0.74f, 0.56f, 0.95f, 0.66f) && num < 0.72f + 0.22999996f * (1f - Mathf.Abs(num2 - 0.61f) * 14f)) { val5 = val3; } if (InCircle(num, num2, 0.62f, 0.66f, 0.018f)) { val5 = black; } px[i * size + j] = val5; } } Apply(val, px); return val; } private static Texture2D MakeBoom(int size) { //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) Color[] px; Texture2D val = Blank(size, out px); Color val2 = default(Color); ((Color)(ref val2))..ctor(1f, 0.45f, 0.05f, 1f); Color val3 = default(Color); ((Color)(ref val3))..ctor(1f, 0.9f, 0.1f, 1f); Color val4 = default(Color); ((Color)(ref val4))..ctor(0f, 0f, 0f, 0f); for (int i = 0; i < size; i++) { for (int j = 0; j < size; j++) { float num = (float)j / (float)(size - 1) - 0.5f; float num2 = (float)i / (float)(size - 1) - 0.5f; float num3 = Mathf.Atan2(num2, num); float num4 = Mathf.Sqrt(num * num + num2 * num2); float num5 = 0.42f + 0.08f * Mathf.Sin(num3 * 8f); Color val5 = val4; if (num4 < num5) { val5 = val2; } if (num4 < num5 * 0.65f) { val5 = val3; } px[i * size + j] = val5; } } Apply(val, px); return val; } private static Texture2D MakeKnife(int size) { //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_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_00e3: 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_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0109: 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_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) Color[] px; Texture2D val = Blank(size, out px); Color val2 = default(Color); ((Color)(ref val2))..ctor(0.85f, 0.85f, 0.9f, 1f); Color val3 = default(Color); ((Color)(ref val3))..ctor(0.45f, 0.25f, 0.1f, 1f); Color black = Color.black; Color val4 = default(Color); ((Color)(ref val4))..ctor(0f, 0f, 0f, 0f); for (int i = 0; i < size; i++) { for (int j = 0; j < size; j++) { float num = (float)j / (float)(size - 1); float num2 = (float)i / (float)(size - 1); Color val5 = val4; float num3 = (num + num2) * 0.5f; float num4 = num2 - num; if (Mathf.Abs(num4) < 0.06f && num3 > 0.3f && num3 < 0.92f) { val5 = val2; } if (Mathf.Abs(num4) < 0.1f && num3 > 0.1f && num3 < 0.32f) { val5 = val3; } if (val5 == val2 && Mathf.Abs(num4) > 0.05f) { val5 = black; } px[i * size + j] = val5; } } Apply(val, px); return val; } private static Texture2D MakeEye(int size) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_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_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: 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) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0123: 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_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) Color[] px; Texture2D val = Blank(size, out px); Color white = Color.white; Color val2 = default(Color); ((Color)(ref val2))..ctor(0.15f, 0.55f, 0.85f, 1f); Color black = Color.black; Color val3 = default(Color); ((Color)(ref val3))..ctor(0f, 0f, 0f, 0f); for (int i = 0; i < size; i++) { for (int j = 0; j < size; j++) { float fx = (float)j / (float)(size - 1); float fy = (float)i / (float)(size - 1); Color val4 = val3; if (InEllipse(fx, fy, 0.5f, 0.5f, 0.45f, 0.22f)) { val4 = white; } if (val4 == white && !InEllipse(fx, fy, 0.5f, 0.5f, 0.43f, 0.2f)) { val4 = black; } if (InCircle(fx, fy, 0.5f, 0.5f, 0.16f)) { val4 = val2; } if (InCircle(fx, fy, 0.5f, 0.5f, 0.07f)) { val4 = black; } if (InCircle(fx, fy, 0.55f, 0.55f, 0.025f)) { val4 = white; } px[i * size + j] = val4; } } Apply(val, px); return val; } private static Texture2D MakeQuestion(int size) { //IL_0063: 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_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: 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_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) Color[] px; Texture2D val = Blank(size, out px); Color val2 = default(Color); ((Color)(ref val2))..ctor(0.15f, 0.35f, 0.85f, 1f); Color val3 = default(Color); ((Color)(ref val3))..ctor(0f, 0f, 0f, 0f); for (int i = 0; i < size; i++) { for (int j = 0; j < size; j++) { float num = (float)j / (float)(size - 1); float num2 = (float)i / (float)(size - 1); Color val4 = val3; float num3 = Mathf.Sqrt((num - 0.5f) * (num - 0.5f) + (num2 - 0.65f) * (num2 - 0.65f)); if (num3 > 0.15f && num3 < 0.22f && num2 > 0.55f) { val4 = val2; } if (Mathf.Abs(num - 0.5f) < 0.045f && num2 > 0.3f && num2 < 0.55f) { val4 = val2; } if (InCircle(num, num2, 0.5f, 0.18f, 0.05f)) { val4 = val2; } px[i * size + j] = val4; } } Apply(val, px); return val; } private static Texture2D MakeBrain(int size) { //IL_007e: 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_00b6: 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_00b9: 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_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: 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_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) Color[] px; Texture2D val = Blank(size, out px); Color val2 = default(Color); ((Color)(ref val2))..ctor(1f, 0.6f, 0.7f, 1f); Color val3 = default(Color); ((Color)(ref val3))..ctor(0.6f, 0.3f, 0.4f, 1f); Color val4 = default(Color); ((Color)(ref val4))..ctor(0f, 0f, 0f, 0f); for (int i = 0; i < size; i++) { for (int j = 0; j < size; j++) { float num = (float)j / (float)(size - 1); float num2 = (float)i / (float)(size - 1); Color val5 = val4; if (InCircle(num, num2, 0.38f, 0.55f, 0.28f) || InCircle(num, num2, 0.62f, 0.55f, 0.28f)) { val5 = val2; } if (val5 == val2) { float num3 = Mathf.Sin(num * 18f) * 0.02f; if (Mathf.Abs(num2 - 0.55f - num3) < 0.005f) { val5 = val3; } if (Mathf.Abs(num2 - 0.4f - num3) < 0.005f) { val5 = val3; } if (Mathf.Abs(num2 - 0.7f - num3) < 0.005f) { val5 = val3; } } px[i * size + j] = val5; } } Apply(val, px); return val; } private static Texture2D MakeNoseShaver(int size) { //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_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_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: 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_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: 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_0109: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) Color[] px; Texture2D val = Blank(size, out px); Color val2 = default(Color); ((Color)(ref val2))..ctor(0.15f, 0.35f, 0.65f, 1f); Color val3 = default(Color); ((Color)(ref val3))..ctor(0.85f, 0.85f, 0.9f, 1f); Color black = Color.black; Color val4 = default(Color); ((Color)(ref val4))..ctor(0f, 0f, 0f, 0f); for (int i = 0; i < size; i++) { for (int j = 0; j < size; j++) { float num = (float)j / (float)(size - 1); float fy = (float)i / (float)(size - 1); Color val5 = val4; if (InRect(num, fy, 0.4f, 0.1f, 0.6f, 0.65f)) { val5 = val2; } if (InCircle(num, fy, 0.5f, 0.1f, 0.1f)) { val5 = val2; } if (InRect(num, fy, 0.36f, 0.65f, 0.64f, 0.8f)) { val5 = val3; } if (InCircle(num, fy, 0.5f, 0.8f, 0.14f)) { val5 = val3; } if (val5 == val3 && Mathf.Abs(Mathf.Sin(num * 60f)) > 0.92f) { val5 = black; } if (InCircle(num, fy, 0.5f, 0.35f, 0.04f)) { ((Color)(ref val5))..ctor(1f, 0.85f, 0.1f, 1f); } px[i * size + j] = val5; } } Apply(val, px); return val; } private static Texture2D MakeBeam(int size) { //IL_0079: 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_0086: 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_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_0094: 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) Color[] px; Texture2D val = Blank(size, out px); Color val2 = default(Color); ((Color)(ref val2))..ctor(0.4f, 1f, 1f, 1f); Color val3 = default(Color); ((Color)(ref val3))..ctor(0.4f, 1f, 1f, 0.4f); Color val4 = default(Color); ((Color)(ref val4))..ctor(0f, 0f, 0f, 0f); for (int i = 0; i < size; i++) { for (int j = 0; j < size; j++) { float num = Mathf.Abs((float)i / (float)(size - 1) - 0.5f); Color val5 = val4; if (num < 0.03f) { val5 = val2; } else if (num < 0.1f) { val5 = val3; } px[i * size + j] = val5; } } Apply(val, px); return val; } private static Texture2D MakeWK(int size) { //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_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0295: Unknown result type (might be due to invalid IL or missing references) //IL_0297: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_0245: Unknown result type (might be due to invalid IL or missing references) //IL_0246: Unknown result type (might be due to invalid IL or missing references) //IL_028a: Unknown result type (might be due to invalid IL or missing references) //IL_028b: Unknown result type (might be due to invalid IL or missing references) Color[] px; Texture2D val = Blank(size, out px); Color val2 = default(Color); ((Color)(ref val2))..ctor(0.92f, 0.3f, 0.1f, 1f); Color white = Color.white; Color val3 = default(Color); ((Color)(ref val3))..ctor(0f, 0f, 0f, 0f); for (int i = 0; i < size; i++) { for (int num = 0; num < size; num++) { float num2 = (float)num / (float)(size - 1); float num3 = (float)i / (float)(size - 1); int num4; Color val4; if (!InRect(num2, num3, 0.1f, 0.05f, 0.9f, 0.95f) && !InRect(num2, num3, 0.05f, 0.1f, 0.95f, 0.9f) && !InCircle(num2, num3, 0.1f, 0.1f, 0.05f) && !InCircle(num2, num3, 0.9f, 0.1f, 0.05f) && !InCircle(num2, num3, 0.1f, 0.9f, 0.05f)) { num4 = (InCircle(num2, num3, 0.9f, 0.9f, 0.05f) ? 1 : 0); if (num4 == 0) { val4 = val3; goto IL_011b; } } else { num4 = 1; } val4 = val2; goto IL_011b; IL_011b: Color val5 = val4; if (num4 != 0) { if (num3 > 0.3f && num3 < 0.7f) { float num5 = Mathf.InverseLerp(0.3f, 0.7f, num3); float num6 = 0.03f; if (Mathf.Abs(num2 - Mathf.Lerp(0.1f, 0.2f, num5)) < num6 || Mathf.Abs(num2 - Mathf.Lerp(0.3f, 0.2f, num5)) < num6 || Mathf.Abs(num2 - Mathf.Lerp(0.3f, 0.4f, num5)) < num6 || Mathf.Abs(num2 - Mathf.Lerp(0.5f, 0.4f, num5)) < num6) { val5 = white; } } if (num3 > 0.3f && num3 < 0.7f) { float num7 = 0.03f; if (Mathf.Abs(num2 - 0.58f) < num7) { val5 = white; } float num8 = Mathf.InverseLerp(0.5f, 0.7f, num3); if (num8 > 0f && num8 < 1f && Mathf.Abs(num2 - Mathf.Lerp(0.58f, 0.92f, num8)) < num7) { val5 = white; } float num9 = Mathf.InverseLerp(0.5f, 0.3f, num3); if (num9 > 0f && num9 < 1f && Mathf.Abs(num2 - Mathf.Lerp(0.58f, 0.92f, num9)) < num7) { val5 = white; } } } px[i * size + num] = val5; } } Apply(val, px); return val; } } public static class ClarkTrigger { public const float Duration = 4f; private const float MinInterval = 8f; private const int MaxLifetimeFires = 50; private static readonly string[] HighValueKeywords = new string[8] { "diamond", "crown", "jewel", "gold", "trophy", "ruby", "sapphire", "emerald" }; private static int _fires; private static int _lastValuableInstanceId; private static float _lastFireTime; private static bool _limitWarned; public static void OnPickup(string name, Component valuable) { if ((Object)(object)valuable == (Object)null) { return; } if (_fires >= 50) { if (!_limitWarned) { Plugin.Log.LogWarning((object)$"[wob] Clark trigger hit hard cap ({50}). Disabled for this session."); _limitWarned = true; } return; } int instanceID = ((Object)valuable).GetInstanceID(); float unscaledTime = Time.unscaledTime; if ((instanceID == _lastValuableInstanceId && unscaledTime - _lastFireTime < 5f) || unscaledTime - _lastFireTime < 8f) { return; } string text = name.ToLowerInvariant(); bool flag = false; string[] highValueKeywords = HighValueKeywords; foreach (string value in highValueKeywords) { if (text.Contains(value)) { flag = true; break; } } if (flag) { _lastValuableInstanceId = instanceID; _lastFireTime = unscaledTime; _fires++; Plugin.Log.LogInfo((object)$"[wob] clark trigger #{_fires}: {name}"); OverlayManager.TriggerOneShot(Reactions.Clark, 4f); } } } public static class ModConfig { public static ConfigEntry LogEnemyNames; public static ConfigEntry LogPickupCandidates; public static ConfigEntry LogGunFireCandidates; public static ConfigEntry VoiceVolume; public static ConfigEntry AmbientVolume; public static ConfigEntry GooberDuplicate; public static ConfigEntry UlfricChance; public static void Bind(ConfigFile cf) { LogEnemyNames = cf.Bind("Diagnostics", "LogEnemyNames", true, "Dump every detected enemy's transform name chain + matched reaction key. Default on for v3 so we can tune from logs if matching misses. Turn off once happy."); LogPickupCandidates = cf.Bind("Diagnostics", "LogPickupCandidates", true, "Log every pickup-method candidate that fires. Leave on until pickup hook is confirmed, then turn off."); LogGunFireCandidates = cf.Bind("Diagnostics", "LogGunFireCandidates", true, "Log every gun-fire-method candidate that fires. Leave on until DIRCM hook is confirmed."); VoiceVolume = cf.Bind("Audio", "VoiceVolume", 0.7f, "Volume for voice clips + procedural sound effects. 0..1."); AmbientVolume = cf.Bind("Audio", "AmbientVolume", 0.3f, "Volume for ambient layers (Mommy ASMR). 0..1."); GooberDuplicate = cf.Bind("Gameplay", "GooberDuplicate", false, "On pickup, spawn a visual duplicate of the same valuable at the player's feet. Default off until the real pickup method is identified — speculative dispatch would spam dupes per frame. Client-only when on."); UlfricChance = cf.Bind("Gameplay", "UlfricChance", 0.05f, "Probability per level scene load that Ulfric Stormcloak cameos. 0..1."); } } public static class DiagnosticLogger { private static readonly HashSet _seenPickup = new HashSet(); private static readonly HashSet _seenFire = new HashSet(); public static List PickupMethods { get; } = new List(); public static List FireMethods { get; } = new List(); public static void RegisterCandidatePatches(Harmony harmony) { Assembly assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly a) => a.GetName().Name == "Assembly-CSharp"); if (assembly == null) { Plugin.Log.LogWarning((object)"Assembly-CSharp not found — pickup/fire patches skipped."); return; } string[] source = new string[1] { "pickup" }; string[] source2 = new string[1] { "shoot" }; foreach (Type item in SafeGetTypes(assembly)) { if (!typeof(MonoBehaviour).IsAssignableFrom(item)) { continue; } MethodInfo[] methods = item.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (MethodInfo methodInfo in methods) { string nm = methodInfo.Name.ToLowerInvariant(); if (!methodInfo.IsAbstract && !methodInfo.IsGenericMethod) { bool num = source.Any((string k) => nm.Contains(k)); bool flag = source2.Any((string k) => nm.Contains(k)); if (num && PickupMethods.Count < 50) { TryPatch(harmony, methodInfo, PickupMethods, "LogPickupCandidate"); } if (flag && FireMethods.Count < 50) { TryPatch(harmony, methodInfo, FireMethods, "LogFireCandidate"); } } } } Plugin.Log.LogInfo((object)$"diagnostic patches: pickup={PickupMethods.Count} fire={FireMethods.Count}"); } private static void TryPatch(Harmony h, MethodBase m, List bag, string postfixName) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown try { HarmonyMethod val = new HarmonyMethod(typeof(DiagnosticLogger).GetMethod(postfixName, BindingFlags.Static | BindingFlags.NonPublic)); h.Patch(m, (HarmonyMethod)null, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); bag.Add(m); } catch (Exception ex) { if (!(ex is InvalidOperationException)) { Plugin.Log.LogDebug((object)("skip patch " + m.DeclaringType?.Name + "." + m.Name + ": " + ex.GetType().Name)); } } } private static void LogPickupCandidate(MethodBase __originalMethod) { try { if (ModConfig.LogPickupCandidates.Value) { string text = __originalMethod.DeclaringType?.FullName + "." + __originalMethod.Name; if (_seenPickup.Add(text)) { Plugin.Log.LogInfo((object)("[wob] pickup candidate fired: " + text)); } } } catch (Exception arg) { Plugin.Log.LogError((object)$"pickup postfix: {arg}"); } } private static void LogFireCandidate(MethodBase __originalMethod) { try { if (ModConfig.LogGunFireCandidates.Value) { string text = __originalMethod.DeclaringType?.FullName + "." + __originalMethod.Name; if (_seenFire.Add(text)) { Plugin.Log.LogInfo((object)("[wob] fire candidate fired: " + text)); } } } catch (Exception arg) { Plugin.Log.LogError((object)$"fire postfix: {arg}"); } } private static IEnumerable SafeGetTypes(Assembly a) { try { return a.GetTypes(); } catch (ReflectionTypeLoadException ex) { return ex.Types.Where((Type t) => t != null); } } } public class EnemyProximityWatcher : MonoBehaviour { [CompilerGenerated] private sealed class d__6 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public EnemyProximityWatcher <>4__this; private WaitForSeconds 5__2; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__6(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { 5__2 = null; <>1__state = -2; } private bool MoveNext() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown int num = <>1__state; EnemyProximityWatcher enemyProximityWatcher = <>4__this; if (num != 0) { if (num != 1) { return false; } <>1__state = -1; } else { <>1__state = -1; 5__2 = new WaitForSeconds(0.25f); } try { enemyProximityWatcher.Tick(); } catch (Exception arg) { Plugin.Log.LogError((object)$"Tick failed: {arg}"); } <>2__current = 5__2; <>1__state = 1; return true; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public const float TickSeconds = 0.25f; public const float ReactionHold = 1.2f; private static readonly string[] EnemyTypeNames = new string[2] { "EnemyParent", "Enemy" }; private Type[] _enemyTypes = Array.Empty(); private readonly HashSet _loggedNames = new HashSet(); private void Start() { _enemyTypes = ResolveTypes(EnemyTypeNames); if (_enemyTypes.Length == 0) { Plugin.Log.LogWarning((object)"No enemy types found by reflection — overlay will never trigger from enemies."); } else { Plugin.Log.LogInfo((object)("Watching enemy types: " + string.Join(", ", _enemyTypes.Select((Type t) => t.Name)))); } ((MonoBehaviour)this).StartCoroutine(TickLoop()); } [IteratorStateMachine(typeof(d__6))] private IEnumerator TickLoop() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__6(0) { <>4__this = this }; } private void Tick() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: 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_00ee: Unknown result type (might be due to invalid IL or missing references) Camera main = Camera.main; if ((Object)(object)main == (Object)null || _enemyTypes.Length == 0) { return; } Vector3 position = ((Component)main).transform.position; Dictionary dictionary = new Dictionary(); Type[] enemyTypes = _enemyTypes; for (int i = 0; i < enemyTypes.Length; i++) { Object[] array = Object.FindObjectsOfType(enemyTypes[i]); foreach (Object obj in array) { Component val = (Component)(object)((obj is Component) ? obj : null); if (val == null || (Object)(object)val == (Object)null) { continue; } int instanceID = ((Object)val.transform.root).GetInstanceID(); if (!dictionary.ContainsKey(instanceID)) { string text = CandidateName(val); ReactionDef reactionDef = Reactions.Lookup(text); if (ModConfig.LogEnemyNames.Value && _loggedNames.Add(text)) { Plugin.Log.LogInfo((object)("[wob] enemy: " + text + " → matched: " + reactionDef.Key)); } Vector3 val2 = val.transform.position - position; float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude; float num = reactionDef.TriggerRange * reactionDef.TriggerRange; if (!(sqrMagnitude > num)) { dictionary[instanceID] = (reactionDef, sqrMagnitude); } } } } foreach (KeyValuePair item in dictionary) { OverlayManager.Trigger(item.Value.Item1, item.Key, 1.2f); } } private static string CandidateName(Component c) { StringBuilder stringBuilder = new StringBuilder(); Transform val = c.transform; while ((Object)(object)val != (Object)null) { Append(stringBuilder, ((Object)val).name); val = val.parent; } Transform root = c.transform.root; if ((Object)(object)root != (Object)null) { Transform[] componentsInChildren = ((Component)root).GetComponentsInChildren(true); foreach (Transform val2 in componentsInChildren) { if (!((Object)(object)val2 == (Object)(object)c.transform) && !((Object)(object)val2 == (Object)(object)root)) { Append(stringBuilder, ((Object)val2).name); } } } return stringBuilder.ToString(); } private static void Append(StringBuilder sb, string s) { sb.Append('/').Append(s.Replace("(Clone)", "").Trim()); } private static Type[] ResolveTypes(IEnumerable names) { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); List list = new List(); foreach (string name in names) { Assembly[] array = assemblies; foreach (Assembly assembly in array) { Type type; try { type = assembly.GetType(name, throwOnError: false); } catch { continue; } if (type != null && typeof(Component).IsAssignableFrom(type)) { list.Add(type); break; } } } return list.ToArray(); } } public static class GooberCounter { private const float MinPickupInterval = 1f; private const int MaxLifetimeCount = 500; private const int MaxDuplicatesPerSession = 100; private static int _count; private static int _duplicateSpawnCount; private static int _lastValuableInstanceId; private static float _lastPickupTime; private static bool _limitWarned; private static readonly HashSet _ourDuplicates = new HashSet(); public static void OnPickup(string name, Component valuable) { if ((Object)(object)valuable == (Object)null) { return; } if (_count >= 500) { if (!_limitWarned) { Plugin.Log.LogWarning((object)$"[wob] Goober pickup count hit hard cap ({500}). Disabling further pickups for this session — likely the wrong method is being patched."); _limitWarned = true; } return; } int instanceID = ((Object)valuable).GetInstanceID(); if (_ourDuplicates.Contains(instanceID)) { return; } float unscaledTime = Time.unscaledTime; if ((instanceID != _lastValuableInstanceId || !(unscaledTime - _lastPickupTime < 5f)) && !(unscaledTime - _lastPickupTime < 1f)) { _lastValuableInstanceId = instanceID; _lastPickupTime = unscaledTime; _count++; Plugin.Log.LogInfo((object)$"[wob] goober pickup #{_count} ({name})"); if (_count <= 10) { Voices.Play($"goober_{_count}"); } else { Voices.Play("goober_iquit"); } if (ModConfig.GooberDuplicate.Value && _duplicateSpawnCount < 100) { SpawnDuplicate(valuable); } } } private static void SpawnDuplicate(Component valuable) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0053: 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) try { Vector3 val = valuable.transform.position + Vector3.up * 0.5f + new Vector3(Random.Range(-0.3f, 0.3f), 0f, Random.Range(-0.3f, 0.3f)); GameObject val2 = Object.Instantiate(valuable.gameObject, val, valuable.transform.rotation); _ourDuplicates.Add(((Object)val2).GetInstanceID()); _duplicateSpawnCount++; if (_ourDuplicates.Count > 200) { _ourDuplicates.Clear(); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("goober duplicate failed: " + ex.Message)); } } } public static class GunFireRouter { private static float _lastFireTime; public static void OnFireCandidate(object instance) { if (!(Time.unscaledTime - _lastFireTime < 0.05f)) { _lastFireTime = Time.unscaledTime; BeamFlash.Trigger(); if (Voices.Has("dircm_fire")) { Voices.Play("dircm_fire"); } else { Sounds.Play(SoundKind.IrBeam); } } } } public class BeamFlash : MonoBehaviour { public const float FlashSeconds = 0.1f; private static float _expiresAt; public static void Trigger() { _expiresAt = Time.unscaledTime + 0.1f; } private void OnGUI() { //IL_0040: 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_004a: 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_0087: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) if (!(Time.unscaledTime >= _expiresAt)) { GUI.depth = -2000; int width = Screen.width; int height = Screen.height; int num = 18; Rect val = new Rect(0f, (float)height * 0.5f - (float)num * 0.5f, (float)width, (float)num); Color color = GUI.color; GUI.color = new Color(0.4f, 1f, 1f, 0.85f); GUI.DrawTexture(val, (Texture)(object)Assets.Bubble); GUI.color = new Color(0.4f, 1f, 1f, 0.25f); GUI.DrawTexture(new Rect(0f, (float)height * 0.5f - (float)num * 2f, (float)width, (float)num * 4f), (Texture)(object)Assets.Bubble); GUI.color = color; } } } public enum IconKind { Cat, ShushFace, Skull, Duck, Boom, Knife, Eye, Question, Brain, Exclam, WK, NoseShaver, Beam } public static class Images { private static readonly Dictionary _textures = new Dictionary(); public static string Dir => Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) ?? "", "images"); public static bool Has(string key) { if (key != null) { return _textures.ContainsKey(key.ToLowerInvariant()); } return false; } public static Texture2D? Get(string key) { _textures.TryGetValue(key.ToLowerInvariant(), out var value); return value; } public static void LoadAll() { //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Expected O, but got Unknown if (!Directory.Exists(Dir)) { Plugin.Log.LogWarning((object)("images/ not found at " + Dir + " — using procedural icons. Drop PNG files there.")); return; } int num = 0; foreach (string item in Directory.EnumerateFiles(Dir)) { string text = Path.GetExtension(item).ToLowerInvariant(); if (text != ".png" && text != ".jpg" && text != ".jpeg") { continue; } try { byte[] array = File.ReadAllBytes(item); Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false); if (ImageConversion.LoadImage(val, array)) { ((Texture)val).filterMode = (FilterMode)1; _textures[Path.GetFileNameWithoutExtension(item).ToLowerInvariant()] = val; num++; } } catch (Exception ex) { Plugin.Log.LogWarning((object)("image load failed: " + item + " — " + ex.Message)); } } Plugin.Log.LogInfo((object)string.Format("images loaded: {0} ({1})", num, string.Join(", ", _textures.Keys))); } } public class LevelEventTrigger : MonoBehaviour { [CompilerGenerated] private sealed class d__7 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__7(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: { <>1__state = -1; float num = Random.Range(8f, 20f); <>2__current = (object)new WaitForSeconds(num); <>1__state = 1; return true; } case 1: <>1__state = -1; OverlayManager.TriggerOneShot(Reactions.WoltersKluwer, 6f); return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class d__8 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__8(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(Random.Range(2f, 5f)); <>1__state = 1; return true; case 1: <>1__state = -1; OverlayManager.TriggerOneShot(Reactions.Ulfric, 4f); return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public const float DelayMin = 8f; public const float DelayMax = 20f; public const float WkDuration = 6f; public const float UlfricDuration = 4f; private void OnEnable() { SceneManager.activeSceneChanged += OnSceneChanged; } private void OnDisable() { SceneManager.activeSceneChanged -= OnSceneChanged; } private void OnSceneChanged(Scene from, Scene to) { if (IsSkippableScene(((Scene)(ref to)).name)) { Plugin.Log.LogInfo((object)("WK skip — scene '" + ((Scene)(ref to)).name + "' looks like menu/lobby.")); return; } Plugin.Log.LogInfo((object)("level events armed for scene '" + ((Scene)(ref to)).name + "'")); ((MonoBehaviour)this).StartCoroutine(FireAfterDelay()); if (Random.value < ModConfig.UlfricChance.Value) { Plugin.Log.LogInfo((object)"[wob] ulfric cameo this level"); ((MonoBehaviour)this).StartCoroutine(FireUlfric()); } } [IteratorStateMachine(typeof(d__7))] private IEnumerator FireAfterDelay() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__7(0); } [IteratorStateMachine(typeof(d__8))] private IEnumerator FireUlfric() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__8(0); } private static bool IsSkippableScene(string name) { if (string.IsNullOrEmpty(name)) { return true; } string text = name.ToLowerInvariant(); if (text.Contains("menu")) { return true; } if (text.Contains("lobby")) { return true; } if (text.Contains("init")) { return true; } if (text.Contains("title")) { return true; } if (text.Contains("splash")) { return true; } if (text.Contains("loading")) { return true; } if (text.Contains("tutorial")) { return true; } if (text.Contains("intro")) { return true; } return false; } } public class Overlay : MonoBehaviour { private GUIStyle? _bubbleStyle; private GUIStyle? _wkTitleStyle; private GUIStyle? _wkBodyStyle; private GUIStyle? _shushStyle; private void OnGUI() { List list = new List(); foreach (ReactionDef item in OverlayManager.Active()) { list.Add(item); } if (list.Count == 0) { return; } GUI.depth = -1000; InitStyles(); if (OverlayManager.HasExclusive(out ReactionDef exclusive) && exclusive != null) { if (exclusive.Icon == IconKind.WK) { DrawWkModal(exclusive); } else if (exclusive.Icon == IconKind.ShushFace) { DrawShushFull(exclusive); } DrawCornerTriangles(); return; } _ = Screen.width; int height = Screen.height; int num = 0; foreach (ReactionDef item2 in list) { if (item2.Icon != IconKind.WK && item2.Icon != IconKind.ShushFace) { int y = height - 20 - 180 - num * 194; DrawStackedRow(item2, 20, y, 180); num++; if (num >= 4) { break; } } } DrawCornerTriangles(); } private void DrawStackedRow(ReactionDef r, int x, int y, int iconSize) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_004b: 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_0056: 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_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) Texture2D val = ResolveIcon(r); Rect val2 = default(Rect); ((Rect)(ref val2))..ctor((float)x, (float)y, (float)iconSize, (float)iconSize); GUI.DrawTexture(val2, (Texture)(object)val, (ScaleMode)2); Rect val3 = default(Rect); ((Rect)(ref val3))..ctor(((Rect)(ref val2)).xMax + 16f, ((Rect)(ref val2)).y + 20f, 360f, 76f); DrawFilled(val3, Color.white); DrawBorder(val3, 4, Color.black); for (int i = 0; i < 24; i++) { DrawFilled(new Rect(((Rect)(ref val3)).x - 24f + (float)i, ((Rect)(ref val3)).y + 76f - 16f + (float)i * 0.6f, (float)(24 - i), 2f), Color.white); } GUI.Label(val3, r.Message, _bubbleStyle); } private void DrawCornerTriangles() { //IL_001f: 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_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) int width = Screen.width; int height = Screen.height; GUI.DrawTexture(new Rect(12f, 12f, 96f, 96f), (Texture)(object)Assets.Warning, (ScaleMode)2); GUI.DrawTexture(new Rect((float)(width - 96 - 12), 12f, 96f, 96f), (Texture)(object)Assets.Warning, (ScaleMode)2); GUI.DrawTexture(new Rect(12f, (float)(height - 96 - 12), 96f, 96f), (Texture)(object)Assets.Warning, (ScaleMode)2); GUI.DrawTexture(new Rect((float)(width - 96 - 12), (float)(height - 96 - 12), 96f, 96f), (Texture)(object)Assets.Warning, (ScaleMode)2); } private void DrawShushFull(ReactionDef r) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0075: 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_0081: Unknown result type (might be due to invalid IL or missing references) int width = Screen.width; int height = Screen.height; Texture2D val = ResolveIcon(r); int num = (int)((float)height * 0.65f); GUI.DrawTexture(new Rect((float)(width - num) * 0.5f, (float)(height - num) * 0.5f - 30f, (float)num, (float)num), (Texture)(object)val, (ScaleMode)2); int num2 = (int)((float)width * 0.6f); int num3 = 110; Rect val2 = new Rect((float)(width - num2) * 0.5f, (float)(height - num3 - 40), (float)num2, (float)num3); DrawFilled(val2, Color.white); DrawBorder(val2, 5, Color.black); GUI.Label(val2, r.Message, _shushStyle); } private void DrawWkModal(ReactionDef r) { //IL_0045: 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_0051: 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_007f: 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_00cd: 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) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Expected O, but got Unknown int width = Screen.width; int height = Screen.height; int num = Mathf.Min(720, (int)((float)width * 0.7f)); int num2 = 360; Rect r2 = default(Rect); ((Rect)(ref r2))..ctor((float)(width - num) * 0.5f, (float)(height - num2) * 0.5f, (float)num, (float)num2); DrawFilled(r2, Color.white); DrawBorder(r2, 3, Color.black); Rect r3 = default(Rect); ((Rect)(ref r3))..ctor(((Rect)(ref r2)).x, ((Rect)(ref r2)).y, ((Rect)(ref r2)).width, 36f); DrawFilled(r3, new Color(0.85f, 0.27f, 0.1f, 1f)); GUI.Label(new Rect(((Rect)(ref r3)).x + 12f, ((Rect)(ref r3)).y + 4f, ((Rect)(ref r3)).width - 24f, ((Rect)(ref r3)).height), "Compliance Notice — wolterskluwer.com", _wkTitleStyle); Rect val = default(Rect); ((Rect)(ref val))..ctor(((Rect)(ref r2)).x + 24f, ((Rect)(ref r2)).y + 60f, 120f, 120f); GUI.DrawTexture(val, (Texture)(object)Assets.Icon(IconKind.WK), (ScaleMode)2); GUI.Label(new Rect(((Rect)(ref val)).xMax + 20f, ((Rect)(ref r2)).y + 60f, ((Rect)(ref r2)).width - 120f - 60f, ((Rect)(ref r2)).height - 80f), r.Message, _wkBodyStyle); Rect val2 = new Rect(((Rect)(ref r2)).xMax - 160f, ((Rect)(ref r2)).yMax - 56f, 140f, 36f); DrawFilled(val2, new Color(0.85f, 0.27f, 0.1f, 1f)); DrawBorder(val2, 2, Color.black); GUIStyle val3 = new GUIStyle(_wkTitleStyle) { alignment = (TextAnchor)4 }; GUI.Label(val2, "Acknowledge", val3); } private static Texture2D ResolveIcon(ReactionDef r) { if (r.ImageKey != null && Images.Has(r.ImageKey)) { return Images.Get(r.ImageKey); } return Assets.Icon(r.Icon); } private void InitStyles() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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_0034: 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_004a: Expected O, but got Unknown //IL_005d: 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_006a: 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_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Expected O, but got Unknown //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: 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_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Expected O, but got Unknown //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: 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_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Expected O, but got Unknown if (_bubbleStyle == null) { GUIStyle val = new GUIStyle(GUI.skin.label) { fontSize = 24, fontStyle = (FontStyle)1, alignment = (TextAnchor)4 }; val.normal.textColor = Color.black; val.wordWrap = true; _bubbleStyle = val; } if (_shushStyle == null) { GUIStyle val2 = new GUIStyle(GUI.skin.label) { fontSize = 56, fontStyle = (FontStyle)1, alignment = (TextAnchor)4 }; val2.normal.textColor = Color.black; val2.wordWrap = false; _shushStyle = val2; } if (_wkTitleStyle == null) { GUIStyle val3 = new GUIStyle(GUI.skin.label) { fontSize = 18, fontStyle = (FontStyle)1, alignment = (TextAnchor)3 }; val3.normal.textColor = Color.white; val3.wordWrap = false; _wkTitleStyle = val3; } if (_wkBodyStyle == null) { GUIStyle val4 = new GUIStyle(GUI.skin.label) { fontSize = 22, fontStyle = (FontStyle)1, alignment = (TextAnchor)0 }; val4.normal.textColor = Color.black; val4.wordWrap = true; _wkBodyStyle = val4; } } private static void DrawFilled(Rect r, Color c) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) Color color = GUI.color; GUI.color = c; GUI.DrawTexture(r, (Texture)(object)Assets.Bubble); GUI.color = color; } private static void DrawBorder(Rect r, int thickness, Color c) { //IL_0017: 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_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: 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) //IL_0088: Unknown result type (might be due to invalid IL or missing references) DrawFilled(new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).y, ((Rect)(ref r)).width, (float)thickness), c); DrawFilled(new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).yMax - (float)thickness, ((Rect)(ref r)).width, (float)thickness), c); DrawFilled(new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).y, (float)thickness, ((Rect)(ref r)).height), c); DrawFilled(new Rect(((Rect)(ref r)).xMax - (float)thickness, ((Rect)(ref r)).y, (float)thickness, ((Rect)(ref r)).height), c); } } public class OverlayManager : MonoBehaviour { private readonly struct ActiveReaction { public readonly ReactionDef Def; public readonly float ExpiresAt; public ActiveReaction(ReactionDef d, float t) { Def = d; ExpiresAt = t; } } public const int MaxStacked = 4; private static readonly Dictionary _byId = new Dictionary(); private static int _wkSourceCounter = -1; public static void Trigger(ReactionDef r, int sourceId, float duration) { ActiveReaction value; bool num = !_byId.TryGetValue(sourceId, out value) || !(Time.unscaledTime < value.ExpiresAt); _byId[sourceId] = new ActiveReaction(r, Time.unscaledTime + duration); if (num) { PlaySoundFor(r); } } public static void TriggerOneShot(ReactionDef r, float duration) { int sourceId = Interlocked.Decrement(ref _wkSourceCounter); Trigger(r, sourceId, duration); } public static IEnumerable Active() { float now = Time.unscaledTime; foreach (int item in (from kv in _byId where kv.Value.ExpiresAt <= now select kv.Key).ToList()) { _byId.Remove(item); } return (from a in _byId.Values orderby a.Def.Priority descending select a.Def).Take(4); } public static bool HasExclusive(out ReactionDef? exclusive) { foreach (ReactionDef item in Active()) { if (item.Icon == IconKind.WK || item.Icon == IconKind.ShushFace) { exclusive = item; return true; } } exclusive = null; return false; } private static void PlaySoundFor(ReactionDef r) { if (r.VoiceKey != null && Voices.Has(r.VoiceKey)) { Voices.Play(r.VoiceKey); } else { Sounds.Play(r.Sound); } } } public static class PickupPatch { private static readonly (string Type, string Method)[] Candidates = new(string, string)[13] { ("PhysGrabber", "PickUpValuable"), ("PhysGrabber", "PickupValuable"), ("PhysGrabber", "PickUp"), ("PhysGrabber", "Pickup"), ("PhysGrabber", "Grab"), ("PhysGrabber", "OnGrabStart"), ("PhysGrabber", "OnGrabStarted"), ("PhysGrabObject", "OnGrabStart"), ("PhysGrabObject", "OnGrab"), ("ValuableObject", "PickUp"), ("ValuableObject", "OnPickUp"), ("ValuableObject", "OnPickup"), ("ItemAttributes", "PickUp") }; public static void Apply(Harmony harmony) { //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Expected O, but got Unknown Assembly assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly a) => a.GetName().Name == "Assembly-CSharp"); if (assembly == null) { Plugin.Log.LogWarning((object)"PickupPatch: Assembly-CSharp not found — Goober inactive."); return; } MethodInfo method = typeof(PickupPatch).GetMethod("Postfix", BindingFlags.Static | BindingFlags.NonPublic); if (method == null) { Plugin.Log.LogError((object)"PickupPatch: postfix method not found via reflection — shouldn't happen."); return; } HarmonyMethod val = new HarmonyMethod(method); int num = 0; (string, string)[] candidates = Candidates; for (int i = 0; i < candidates.Length; i++) { var (text, mn) = candidates[i]; Type type; try { type = assembly.GetType(text, throwOnError: false); } catch { continue; } if (type == null) { continue; } foreach (MethodInfo item in from m in type.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) where m.Name == mn && !m.IsAbstract && !m.IsGenericMethod select m) { try { harmony.Patch((MethodBase)item, (HarmonyMethod)null, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); Plugin.Log.LogInfo((object)$"[wob] pickup patch wired: {text}.{mn} ({item.GetParameters().Length} args)"); num++; } catch (Exception ex) { Plugin.Log.LogWarning((object)("PickupPatch could not patch " + text + "." + mn + ": " + ex.GetType().Name + " " + ex.Message)); } } } if (num == 0) { Plugin.Log.LogWarning((object)"PickupPatch: no candidate methods resolved. Goober counter inactive until a real method is identified from BepInEx log (see [wob] pickup candidate lines)."); } } private static void Postfix(object __instance) { try { PickupRouter.OnRealPickup(__instance); } catch (Exception arg) { Plugin.Log.LogError((object)$"pickup postfix: {arg}"); } } } public static class PickupRouter { private static int _lastInstanceId; private static float _lastFireTime; private const float DebounceSeconds = 0.6f; public static void OnRealPickup(object instance) { Component val = ExtractValuable(instance); if (!((Object)(object)val == (Object)null)) { int instanceID = ((Object)val).GetInstanceID(); float unscaledTime = Time.unscaledTime; if (instanceID != _lastInstanceId || !(unscaledTime - _lastFireTime < 0.6f)) { _lastInstanceId = instanceID; _lastFireTime = unscaledTime; string name = (((Object)val.gameObject).name ?? "").Replace("(Clone)", "").Trim(); GooberCounter.OnPickup(name, val); ClarkTrigger.OnPickup(name, val); } } } public static void OnPickupCandidate(object instance) { Component val = ExtractValuable(instance); if (!((Object)(object)val == (Object)null)) { string name = (((Object)val.gameObject).name ?? "").Replace("(Clone)", "").Trim(); GooberCounter.OnPickup(name, val); ClarkTrigger.OnPickup(name, val); } } private static Component? ExtractValuable(object instance) { Component val = (Component)((instance is Component) ? instance : null); if (val != null) { return TryUseSelf(val); } Type type = instance.GetType(); FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { if (typeof(Component).IsAssignableFrom(fieldInfo.FieldType)) { object? value = fieldInfo.GetValue(instance); Component val2 = (Component)((value is Component) ? value : null); if ((Object)(object)val2 != (Object)null && IsLikelyValuable(fieldInfo.Name, val2)) { return val2; } } } PropertyInfo[] properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (PropertyInfo propertyInfo in properties) { if (!typeof(Component).IsAssignableFrom(propertyInfo.PropertyType)) { continue; } try { object? value2 = propertyInfo.GetValue(instance); Component val3 = (Component)((value2 is Component) ? value2 : null); if ((Object)(object)val3 != (Object)null && IsLikelyValuable(propertyInfo.Name, val3)) { return val3; } } catch { } } return null; } private static Component? TryUseSelf(Component c) { string text = ((object)c).GetType().Name.ToLowerInvariant(); if (text.Contains("valuable") || text.Contains("loot") || text.Contains("treasure")) { return c; } return null; } private static bool IsLikelyValuable(string memberName, Component v) { string text = memberName.ToLowerInvariant(); if (text.Contains("valuable") || text.Contains("loot") || text.Contains("treasure") || text.Contains("held") || text.Contains("grabbed") || text.Contains("carry") || text.Contains("pickup")) { return true; } string text2 = ((object)v).GetType().Name.ToLowerInvariant(); if (!text2.Contains("valuable") && !text2.Contains("loot")) { return text2.Contains("treasure"); } return true; } } [BepInPlugin("watchoutbro.WatchOutBro", "WatchOutBro", "3.0.1")] public class Plugin : BaseUnityPlugin { public const string GUID = "watchoutbro.WatchOutBro"; public const string NAME = "WatchOutBro"; public const string VERSION = "3.0.1"; internal static ManualLogSource Log; internal static Harmony Harm; private void Awake() { //IL_0025: 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_0030: Expected O, but got Unknown //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0053: 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_0074: Expected O, but got Unknown //IL_0088: 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_0096: 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_00a4: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; ModConfig.Bind(((BaseUnityPlugin)this).Config); Assets.Load(); Images.LoadAll(); GameObject val = new GameObject("WatchOutBroHost"); Object.DontDestroyOnLoad((Object)val); ((Object)val).hideFlags = (HideFlags)61; AudioSource val2 = val.AddComponent(); AudioSource loop = val.AddComponent(); Sounds.Init(val2); Voices.Init(val2, loop); Bootstrap bootstrap = val.AddComponent(); ((MonoBehaviour)bootstrap).StartCoroutine(Voices.LoadAll((MonoBehaviour)(object)bootstrap)); Harm = new Harmony("watchoutbro.WatchOutBro"); PickupPatch.Apply(Harm); DiagnosticLogger.RegisterCandidatePatches(Harm); val.AddComponent(); val.AddComponent(); val.AddComponent(); val.AddComponent(); val.AddComponent(); val.AddComponent(); Log.LogInfo((object)"WatchOutBro 3.0.1 loaded"); } } public class Bootstrap : MonoBehaviour { } public sealed class ReactionDef { public string[] NameMatches { get; } public float TriggerRange { get; } public string Message { get; } public IconKind Icon { get; } public SoundKind Sound { get; } public int Priority { get; } public string? ImageKey { get; } public string? VoiceKey { get; } public string Key { get; } public ReactionDef(string[] nameMatches, float triggerRange, string message, IconKind icon, SoundKind sound, int priority, string? imageKey = null, string? voiceKey = null) { NameMatches = nameMatches; TriggerRange = triggerRange; Message = message; Icon = icon; Sound = sound; Priority = priority; ImageKey = imageKey; VoiceKey = voiceKey; Key = ((nameMatches.Length != 0) ? nameMatches[0] : "?"); } } public static class Reactions { public static readonly List All = new List { new ReactionDef(new string[1] { "huntsman" }, 20f, "be quiet bro...", IconKind.ShushFace, SoundKind.Shush, 50), new ReactionDef(new string[2] { "bang", "banger" }, 15f, "RUN BRO", IconKind.Boom, SoundKind.Alarm, 60), new ReactionDef(new string[1] { "reaper" }, 25f, "duck bro", IconKind.Skull, SoundKind.Scream, 70), new ReactionDef(new string[1] { "headman" }, 12f, "mind your head bro", IconKind.Exclam, SoundKind.None, 30), new ReactionDef(new string[1] { "mentalist" }, 18f, "stay grounded bro", IconKind.Brain, SoundKind.None, 40), new ReactionDef(new string[1] { "apex" }, 15f, "QUACK BRO", IconKind.Duck, SoundKind.Alarm, 50), new ReactionDef(new string[1] { "hidden" }, 10f, "where bro??", IconKind.Question, SoundKind.None, 30), new ReactionDef(new string[2] { "clown", "birthday" }, 18f, "not funny bro", IconKind.Skull, SoundKind.Scream, 50), new ReactionDef(new string[2] { "peeper", "ceiling" }, 15f, "look away bro", IconKind.Eye, SoundKind.None, 40), new ReactionDef(new string[1] { "shadow" }, 15f, "lights on bro", IconKind.Exclam, SoundKind.None, 30), new ReactionDef(new string[1] { "bowtie" }, 15f, "fancy bro", IconKind.Exclam, SoundKind.None, 30), new ReactionDef(new string[1] { "tick" }, 12f, "bug spray bro", IconKind.Exclam, SoundKind.None, 30), new ReactionDef(new string[1] { "balloon" }, 18f, "pop bro", IconKind.Exclam, SoundKind.None, 30), new ReactionDef(new string[2] { "floater", "robe" }, 18f, "ghost bro", IconKind.Skull, SoundKind.None, 40), new ReactionDef(new string[2] { "cleanup", "crew" }, 15f, "tidy up bro", IconKind.Exclam, SoundKind.None, 30), new ReactionDef(new string[4] { "loom", "elsa", "heart", "oogly" }, 15f, "weird bro", IconKind.Exclam, SoundKind.None, 30), new ReactionDef(new string[1] { "spewer" }, 15f, "ew bro", IconKind.Exclam, SoundKind.None, 30), new ReactionDef(new string[1] { "animal" }, 15f, "wonky bro", IconKind.Exclam, SoundKind.None, 25), new ReactionDef(new string[1] { "chef" }, 15f, "I'm Dexter Morgan", IconKind.Exclam, SoundKind.None, 80, "dexter", "dexter"), new ReactionDef(new string[1] { "trudge" }, 18f, "DIRCM — incoming countermeasure", IconKind.NoseShaver, SoundKind.None, 80, "dircm", "dircm"), new ReactionDef(new string[1] { "gnome" }, 8f, "klonnku", IconKind.Exclam, SoundKind.None, 40, "klonnku", "klonnku"), new ReactionDef(new string[1] { "spewer" }, 15f, "plonko", IconKind.Exclam, SoundKind.None, 45, "plonko", "plonko") }; public static readonly ReactionDef Fallback = new ReactionDef(new string[1] { "*" }, 15f, "watch out bro...", IconKind.Cat, SoundKind.None, 0); public static readonly ReactionDef WoltersKluwer = new ReactionDef(new string[1] { "__wk__" }, 0f, "MANDATORY COMPLIANCE TRAINING\nWolters Kluwer Inc.\nClick anywhere to acknowledge", IconKind.WK, SoundKind.Bell, 100); public static readonly ReactionDef Ulfric = new ReactionDef(new string[1] { "__ulfric__" }, 0f, "Ulfric Stormcloak, the true high king", IconKind.Exclam, SoundKind.Bell, 90, "ulfric", "ulfric"); public static readonly ReactionDef Clark = new ReactionDef(new string[1] { "__clark__" }, 0f, "I think I like this Clark", IconKind.Cat, SoundKind.Bell, 75, "clark", "clark_pickup"); public static ReactionDef Lookup(string candidateName) { if (string.IsNullOrEmpty(candidateName)) { return Fallback; } string text = candidateName.ToLowerInvariant(); ReactionDef reactionDef = null; foreach (ReactionDef item in All) { string[] nameMatches = item.NameMatches; foreach (string value in nameMatches) { if (text.Contains(value)) { if (reactionDef == null || item.Priority > reactionDef.Priority) { reactionDef = item; } break; } } } return reactionDef ?? Fallback; } } public enum SoundKind { None, Shush, Scream, Alarm, Bell, IrBeam } public static class Sounds { private const int Sr = 44100; private const float Volume = 0.5f; private static AudioSource? _src; private static AudioClip? _shush; private static AudioClip? _scream; private static AudioClip? _alarm; private static AudioClip? _bell; private static AudioClip? _irBeam; public static void Init(AudioSource src) { _src = src; _src.playOnAwake = false; _src.spatialBlend = 0f; _src.volume = 0.5f; _src.loop = false; _shush = BuildShush(0.6f); _scream = BuildScream(0.8f); _alarm = BuildAlarm(1f); _bell = BuildBell(0.7f); _irBeam = BuildIrBeam(0.5f); } public static void Play(SoundKind kind) { if (!((Object)(object)_src == (Object)null)) { AudioClip val = (AudioClip)(kind switch { SoundKind.Shush => _shush, SoundKind.Scream => _scream, SoundKind.Alarm => _alarm, SoundKind.Bell => _bell, SoundKind.IrBeam => _irBeam, _ => null, }); if ((Object)(object)val != (Object)null) { _src.PlayOneShot(val, Mathf.Clamp01(ModConfig.VoiceVolume.Value)); } } } private static AudioClip BuildShush(float seconds) { int num = (int)(44100f * seconds); float[] array = new float[num]; Random random = new Random(1); float num2 = 0f; int num3 = 2205; int num4 = 8820; for (int i = 0; i < num; i++) { float num5 = (float)(random.NextDouble() * 2.0 - 1.0); num2 += 0.18f * (num5 - num2); float num6 = ((i < num3) ? ((float)i / (float)num3) : ((i > num - num4) ? ((float)(num - i) / (float)num4) : 1f)); array[i] = num2 * num6 * 0.8f; } AudioClip obj = AudioClip.Create("wob_shush", num, 1, 44100, false); obj.SetData(array, 0); return obj; } private static AudioClip BuildScream(float seconds) { int num = (int)(44100f * seconds); float[] array = new float[num]; double num2 = 0.0; for (int i = 0; i < num; i++) { float num3 = (float)i / (float)num; float num4 = Mathf.Lerp(800f, 200f, num3); float num5 = Mathf.Sin((float)i / 44100f * 2f * MathF.PI * 7f) * 30f; num2 += Math.PI * 2.0 * (double)(num4 + num5) / 44100.0; float num6 = Mathf.Sin(num3 * MathF.PI); array[i] = (float)Math.Sin(num2) * num6 * 0.7f; } AudioClip obj = AudioClip.Create("wob_scream", num, 1, 44100, false); obj.SetData(array, 0); return obj; } private static AudioClip BuildAlarm(float seconds) { int num = (int)(44100f * seconds); float[] array = new float[num]; int num2 = 4410; double num3 = 0.0; for (int i = 0; i < num; i++) { float num4 = ((i / num2 % 2 == 0) ? 440f : 660f); num3 += Math.PI * 2.0 * (double)num4 / 44100.0; array[i] = (float)((Math.Sin(num3) >= 0.0) ? 0.4 : (-0.4)); } AudioClip obj = AudioClip.Create("wob_alarm", num, 1, 44100, false); obj.SetData(array, 0); return obj; } private static AudioClip BuildIrBeam(float seconds) { int num = (int)(44100f * seconds); float[] array = new float[num]; double num2 = 0.0; for (int i = 0; i < num; i++) { float num3 = (float)i / (float)num; float num4 = Mathf.Lerp(3000f, 600f, Mathf.Pow(num3, 0.4f)); num2 += Math.PI * 2.0 * (double)num4 / 44100.0; float num5 = Mathf.Exp(-4f * num3); array[i] = (float)Math.Sin(num2) * num5 * 0.6f; } AudioClip obj = AudioClip.Create("wob_irbeam", num, 1, 44100, false); obj.SetData(array, 0); return obj; } private static AudioClip BuildBell(float seconds) { int num = (int)(44100f * seconds); float[] array = new float[num]; double num2 = 0.0; for (int i = 0; i < num; i++) { num2 += 0.12537875442898042; float num3 = Mathf.Exp(-3.5f * ((float)i / (float)num)); float num4 = Mathf.Sin((float)num2 * 2f) * 0.3f; array[i] = ((float)Math.Sin(num2) + num4) * num3 * 0.6f; } AudioClip obj = AudioClip.Create("wob_bell", num, 1, 44100, false); obj.SetData(array, 0); return obj; } } public static class Voices { [CompilerGenerated] private sealed class <>c__DisplayClass7_0 { public int loaded; public Action <>9__0; internal void b__0(bool ok) { if (ok) { loaded++; } } } [CompilerGenerated] private sealed class d__7 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public MonoBehaviour host; private <>c__DisplayClass7_0 <>8__1; private IEnumerator <>7__wrap1; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__7(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || num == 1) { try { } finally { <>m__Finally1(); } } <>8__1 = null; <>7__wrap1 = null; <>1__state = -2; } private bool MoveNext() { //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: 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) //IL_00d2: 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_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) try { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>8__1 = new <>c__DisplayClass7_0(); if (!Directory.Exists(Dir)) { Plugin.Log.LogWarning((object)("voices/ not found at " + Dir + " — using procedural sounds. Drop OGG/WAV files there.")); return false; } <>8__1.loaded = 0; <>7__wrap1 = Directory.EnumerateFiles(Dir).GetEnumerator(); <>1__state = -3; break; case 1: <>1__state = -3; break; } while (<>7__wrap1.MoveNext()) { string current = <>7__wrap1.Current; AudioType val = (AudioType)(Path.GetExtension(current).ToLowerInvariant() switch { ".ogg" => 14, ".wav" => 20, ".mp3" => 13, _ => 0, }); if ((int)val == 0) { continue; } <>2__current = host.StartCoroutine(LoadOne(current, val, delegate(bool ok) { if (ok) { <>8__1.loaded++; } })); <>1__state = 1; return true; } <>m__Finally1(); <>7__wrap1 = null; Plugin.Log.LogInfo((object)string.Format("voices loaded: {0} ({1})", <>8__1.loaded, string.Join(", ", _clips.Keys))); return false; } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; if (<>7__wrap1 != null) { <>7__wrap1.Dispose(); } } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class d__8 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public string path; public AudioType type; public Action done; private UnityWebRequest 5__2; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__8(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || num == 1) { try { } finally { <>m__Finally1(); } } 5__2 = null; <>1__state = -2; } private bool MoveNext() { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Invalid comparison between Unknown and I4 bool result; try { switch (<>1__state) { default: result = false; break; case 0: { <>1__state = -1; string absoluteUri = new Uri(path).AbsoluteUri; 5__2 = UnityWebRequestMultimedia.GetAudioClip(absoluteUri, type); <>1__state = -3; <>2__current = 5__2.SendWebRequest(); <>1__state = 1; result = true; break; } case 1: <>1__state = -3; if ((int)5__2.result != 1) { Plugin.Log.LogWarning((object)("voice load failed: " + path + " — " + 5__2.error)); done(obj: false); result = false; } else { AudioClip content = DownloadHandlerAudioClip.GetContent(5__2); string key = Path.GetFileNameWithoutExtension(path).ToLowerInvariant(); _clips[key] = content; done(obj: true); result = false; } <>m__Finally1(); break; } } catch { //try-fault ((IDisposable)this).Dispose(); throw; } return result; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; if (5__2 != null) { ((IDisposable)5__2).Dispose(); } } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static readonly Dictionary _clips = new Dictionary(); private static AudioSource? _src; private static AudioSource? _loopSrc; public static string Dir => Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) ?? "", "voices"); public static void Init(AudioSource oneShot, AudioSource loop) { _src = oneShot; _loopSrc = loop; _loopSrc.playOnAwake = false; _loopSrc.loop = true; _loopSrc.spatialBlend = 0f; } public static bool Has(string key) { if (key != null) { return _clips.ContainsKey(key); } return false; } [IteratorStateMachine(typeof(d__7))] public static IEnumerator LoadAll(MonoBehaviour host) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__7(0) { host = host }; } [IteratorStateMachine(typeof(d__8))] private static IEnumerator LoadOne(string path, AudioType type, Action done) { //IL_000e: 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) //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__8(0) { path = path, type = type, done = done }; } public static void Play(string key, float volumeScale = 1f) { if (!((Object)(object)_src == (Object)null) && _clips.TryGetValue(key.ToLowerInvariant(), out var value)) { _src.PlayOneShot(value, Mathf.Clamp01(ModConfig.VoiceVolume.Value * volumeScale)); } } public static void PlayLoop(string key, float volumeScale = 1f) { if (!((Object)(object)_loopSrc == (Object)null) && _clips.TryGetValue(key.ToLowerInvariant(), out var value) && (!_loopSrc.isPlaying || !((Object)(object)_loopSrc.clip == (Object)(object)value))) { _loopSrc.clip = value; _loopSrc.volume = Mathf.Clamp01(ModConfig.AmbientVolume.Value * volumeScale); _loopSrc.Play(); } } public static void StopLoop() { if ((Object)(object)_loopSrc != (Object)null && _loopSrc.isPlaying) { _loopSrc.Stop(); } } } public static class MyPluginInfo { public const string PLUGIN_GUID = "WatchOutBro"; public const string PLUGIN_NAME = "WatchOutBro"; public const string PLUGIN_VERSION = "3.0.1"; } }