using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using Assets.Scripts.Inventory__Items__Pickups.Interactables;
using Assets.Scripts.Managers;
using BepInEx;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.SceneManagement;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("Potomatic")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Potomatic")]
[assembly: AssemblyCopyright("Copyright © 2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("bdc5034c-ac29-4bcf-b469-070abcf1ba89")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[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.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace Potomatic
{
internal static class LogBridge
{
private const string Prefix = "[Potomatic] ";
internal static Action<string> Info { get; set; } = delegate(string s)
{
Debug.Log(Object.op_Implicit("[Potomatic] " + s));
};
internal static Action<string> Warn { get; set; } = delegate(string s)
{
Debug.LogWarning(Object.op_Implicit("[Potomatic] " + s));
};
internal static Action<string> Error { get; set; } = delegate(string s)
{
Debug.LogError(Object.op_Implicit("[Potomatic] " + s));
};
internal static void UseUnityLogger()
{
Info = delegate(string s)
{
Debug.Log(Object.op_Implicit("[Potomatic] " + s));
};
Warn = delegate(string s)
{
Debug.LogWarning(Object.op_Implicit("[Potomatic] " + s));
};
Error = delegate(string s)
{
Debug.LogError(Object.op_Implicit("[Potomatic] " + s));
};
}
}
internal static class ModCore
{
private const string HarmonyId = "Maskoliver.Potomatic";
private static Harmony _harmony;
private static bool _initialized;
internal static void Init()
{
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Expected O, but got Unknown
if (_initialized)
{
LogBridge.Warn("[Potomatic] Init called more than once; ignoring.");
return;
}
_harmony = new Harmony("Maskoliver.Potomatic");
_harmony.PatchAll(typeof(ModCore).Assembly);
_initialized = true;
LogBridge.Info("[Potomatic] Harmony patches applied.");
}
internal static void Deinit()
{
if (!_initialized)
{
return;
}
try
{
Harmony harmony = _harmony;
if (harmony != null)
{
harmony.UnpatchSelf();
}
}
catch (Exception value)
{
LogBridge.Error($"[Potomatic] Unpatch failed: {value}");
}
finally
{
_harmony = null;
_initialized = false;
}
}
}
internal static class PotCache
{
private static readonly List<InteractablePot> Pots = new List<InteractablePot>(256);
private static readonly HashSet<int> PotIds = new HashSet<int>();
private static readonly HashSet<int> Interacted = new HashSet<int>();
private static bool _scanned;
private static string _sceneName = "";
private static int _scanDelayFrames;
private static bool _retryOnceScheduled;
private static int _lastScanFrame = -1;
private const float FallbackRange = 6f;
private const string TargetScene = "GeneratedMap";
private const int RetryThreshold = 10;
public static void Invalidate()
{
_scanned = false;
Pots.Clear();
PotIds.Clear();
Interacted.Clear();
_sceneName = "";
_retryOnceScheduled = false;
_scanDelayFrames = 0;
_lastScanFrame = -1;
LogBridge.Info("[Potomatic] Pot cache invalidated.");
}
public static void RequestScan(int delayFrames = 1)
{
if (delayFrames < 0)
{
delayFrames = 0;
}
_scanDelayFrames = delayFrames;
_scanned = false;
}
public static void EnsureScannedForGeneratedMap()
{
//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)
Scene activeScene = SceneManager.GetActiveScene();
if (!((Scene)(ref activeScene)).IsValid())
{
return;
}
if (!string.Equals(((Scene)(ref activeScene)).name, _sceneName, StringComparison.Ordinal))
{
_sceneName = ((Scene)(ref activeScene)).name;
_scanned = false;
Pots.Clear();
PotIds.Clear();
Interacted.Clear();
_retryOnceScheduled = false;
_scanDelayFrames = 15;
_lastScanFrame = -1;
}
else
{
if (_sceneName != "GeneratedMap")
{
return;
}
if (!_scanned)
{
if (_scanDelayFrames > 0)
{
_scanDelayFrames--;
}
else
{
DoScan();
}
}
else if (_retryOnceScheduled && Time.frameCount - _lastScanFrame > 30)
{
_retryOnceScheduled = false;
DoScan();
}
}
}
private static void DoScan()
{
Pots.Clear();
PotIds.Clear();
Interacted.Clear();
int num = 0;
try
{
Il2CppArrayBase<Transform> val = Object.FindObjectsOfType<Transform>(true);
for (int i = 0; i < val.Length; i++)
{
Transform val2 = val[i];
if ((Object)(object)val2 == (Object)null)
{
continue;
}
GameObject gameObject = ((Component)val2).gameObject;
if ((Object)(object)gameObject == (Object)null)
{
continue;
}
string name = ((Object)gameObject).name;
if (string.IsNullOrEmpty(name) || name.IndexOf("pot", StringComparison.OrdinalIgnoreCase) < 0)
{
continue;
}
InteractablePot val3 = gameObject.GetComponent<InteractablePot>() ?? gameObject.GetComponentInChildren<InteractablePot>(true) ?? gameObject.GetComponentInParent<InteractablePot>(true);
if (!((Object)(object)val3 == (Object)null))
{
int instanceID = ((Object)val3).GetInstanceID();
if (PotIds.Add(instanceID))
{
Pots.Add(val3);
num++;
}
}
}
_scanned = true;
_lastScanFrame = Time.frameCount;
LogBridge.Info($"[Potomatic] GeneratedMap scan complete. Cached {num} pot(s).");
if (num < 10)
{
_retryOnceScheduled = true;
}
}
catch (Exception value)
{
LogBridge.Error($"[Potomatic] Scene scan failed: {value}");
}
}
private static bool HoverThenInteract(InteractablePot pot, DetectInteractables detector)
{
try
{
((BaseInteractable)pot).StartHover(detector);
detector.TryInteract();
if (((BaseInteractable)pot).Interact())
{
return true;
}
}
catch (Exception ex)
{
LogBridge.Warn("[Potomatic] Hover/Interact error: " + ex.Message);
}
return false;
}
public static void TryAutoInteractNear(DetectInteractables detector)
{
//IL_0044: 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_0041: 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_007f: 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_008b: Unknown result type (might be due to invalid IL or missing references)
//IL_0090: 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_0099: 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_00a8: 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_00b8: Unknown result type (might be due to invalid IL or missing references)
if (!_scanned || _sceneName != "GeneratedMap" || Pots.Count == 0 || (Object)(object)detector == (Object)null)
{
return;
}
Transform transform = ((Component)detector).transform;
Vector3 val = (Vector3)((transform != null) ? transform.position : default(Vector3));
for (int i = 0; i < Pots.Count; i++)
{
InteractablePot val2 = Pots[i];
if ((Object)(object)val2 == (Object)null)
{
continue;
}
int instanceID = ((Object)val2).GetInstanceID();
if (Interacted.Contains(instanceID))
{
continue;
}
Vector3 val3 = val - ((Component)val2).transform.position;
if (!(val3.x * val3.x + val3.y * val3.y + val3.z * val3.z > 36f))
{
bool flag = false;
try
{
flag = ((BaseInteractable)val2).CanInteract();
}
catch
{
}
if (flag && HoverThenInteract(val2, detector))
{
Interacted.Add(instanceID);
}
}
}
}
}
[HarmonyPatch(typeof(DetectInteractables), "Update")]
internal static class Patch_DetectInteractables_Update
{
[HarmonyPostfix]
private static void Postfix(DetectInteractables __instance)
{
PotCache.EnsureScannedForGeneratedMap();
PotCache.TryAutoInteractNear(__instance);
}
}
[HarmonyPatch(typeof(MapController), "RestartRun")]
internal static class Patch_MapController_RestartRun
{
[HarmonyPostfix]
private static void Postfix()
{
PotCache.Invalidate();
PotCache.RequestScan(20);
}
}
[HarmonyPatch(typeof(MapController), "StartNewMap")]
internal static class Patch_MapController_StartNewMap
{
[HarmonyPostfix]
private static void Postfix()
{
PotCache.Invalidate();
PotCache.RequestScan(20);
}
}
[HarmonyPatch(typeof(MapController), "LoadNextStage")]
internal static class Patch_MapController_LoadNextStage
{
[HarmonyPostfix]
private static void Postfix()
{
PotCache.Invalidate();
PotCache.RequestScan(20);
}
}
[HarmonyPatch(typeof(MapController), "LoadFinalStage")]
internal static class Patch_MapController_LoadFinalStage
{
[HarmonyPostfix]
private static void Postfix()
{
PotCache.Invalidate();
PotCache.RequestScan(20);
}
}
[HarmonyPatch(typeof(MapGenerator), "GenerateMap", new Type[]
{
typeof(MapData),
typeof(StageData),
typeof(int)
})]
internal static class Patch_MapGenerator_GenerateMap_MDS
{
[HarmonyPostfix]
private static void Postfix()
{
PotCache.Invalidate();
PotCache.RequestScan(30);
}
}
[HarmonyPatch(typeof(MapGenerator), "GenerateMap", new Type[] { typeof(int) })]
internal static class Patch_MapGenerator_GenerateMap_I
{
[HarmonyPostfix]
private static void Postfix()
{
PotCache.Invalidate();
PotCache.RequestScan(30);
}
}
[HarmonyPatch(typeof(SpawnInteractables), "SpawnShit")]
internal static class Patch_SpawnInteractables_SpawnShit
{
[HarmonyPostfix]
private static void Postfix()
{
PotCache.RequestScan(10);
}
}
[HarmonyPatch(typeof(SpawnInteractables), "SpawnChests")]
internal static class Patch_SpawnInteractables_SpawnChests
{
[HarmonyPostfix]
private static void Postfix()
{
PotCache.RequestScan(10);
}
}
[HarmonyPatch(typeof(SpawnInteractables), "SpawnShrines")]
internal static class Patch_SpawnInteractables_SpawnShrines
{
[HarmonyPostfix]
private static void Postfix()
{
PotCache.RequestScan(10);
}
}
[BepInPlugin("com.maskoliver.potomatic", "Potomatic", "1.0.0")]
public sealed class BepInEntry : BasePlugin
{
private ManualLogSource _log;
public override void Load()
{
_log = Logger.CreateLogSource("Potomatic");
LogBridge.Info = delegate(string s)
{
_log.LogInfo((object)s);
};
LogBridge.Warn = delegate(string s)
{
_log.LogWarning((object)s);
};
LogBridge.Error = delegate(string s)
{
_log.LogError((object)s);
};
ModCore.Init();
}
public override bool Unload()
{
ModCore.Deinit();
LogBridge.UseUnityLogger();
if (_log != null)
{
Logger.Sources.Remove((ILogSource)(object)_log);
_log = null;
}
return true;
}
}
}