using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using Assets.Scripts.UI.InGame.Levelup;
using Assets.Scripts.Utility;
using BepInEx;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using HarmonyLib;
using Inventory__Items__Pickups;
using Inventory__Items__Pickups.Xp_and_Levels;
using MelonLoader;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("BetterBanishes")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("BetterBanishes")]
[assembly: AssemblyCopyright("Copyright © 2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("a052f8b9-b678-40b0-a576-d1c5418579fb")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace SaveLoadWeapons
{
[BepInPlugin("mike9k1.megabonk.betterbanishes", "Better Banishes and Skips", "0.0.4")]
public class BetterBanishes : MelonMod
{
public new const string PLUGIN_GUID = "mike9k1.megabonk.betterbanishes";
public new const string PLUGIN_NAME = "Better Banishes and Skips";
public new const string PLUGIN_VERSION = "0.0.4";
private string LevelTypeName = "LevelupScreen";
private string LevelMethodName = "Banish";
private string SkipMethodName = "Skip";
private string RefreshTypeName = "PlayerInventory";
private string RefreshMethodName = "Update";
private string ExpTypeName = "Inventory__Items__Pickups.Xp_and_Levels.PlayerXp";
private string ExpMethodName = "AddXp";
private static int newRefreshCount = 2;
private static int xpToRefund = 0;
private static int initialRefreshValue = -1;
private static int lastPlayerLevel = 0;
private static int newPlayerLevel = 0;
private static bool banishUsed = false;
private static bool skipUsed = false;
private static LevelupScreen lvlScreen;
private static XpBarUI xpb;
private static EncounterWindows encWindow;
private float lastTime;
private static void RefreshPostfix(PlayerInventory __instance)
{
if (banishUsed)
{
newPlayerLevel = __instance.GetCharacterLevel();
xpToRefund = XpUtility.LevelToXp(newPlayerLevel + 1) - XpUtility.LevelToXp(newPlayerLevel);
__instance.AddLevel();
PlayerXp playerXp = __instance.playerXp;
playerXp.level -= 1;
PlayerXp playerXp2 = __instance.playerXp;
playerXp2.xp -= xpToRefund;
MelonLogger.Msg("Banish used. Reroll granted");
banishUsed = false;
if ((Object)(object)lvlScreen == (Object)null)
{
lvlScreen = Object.FindFirstObjectByType<LevelupScreen>();
}
if ((Object)(object)lvlScreen != (Object)null)
{
lvlScreen.level = __instance.playerXp.level;
lvlScreen.currentLevel = __instance.playerXp.level;
}
else
{
MelonLogger.Error("Level Screen instance not found. Player level will be updated on next level-up");
}
encWindow = Object.FindFirstObjectByType<EncounterWindows>();
if ((Object)(object)encWindow != (Object)null)
{
encWindow.currentLevel = __instance.playerXp.level;
}
else
{
MelonLogger.Error("Level Screen encounter window object not found. Player level will be updated on next level-up");
}
xpb = Object.FindFirstObjectByType<XpBarUI>();
if ((Object)(object)xpb != (Object)null)
{
xpb.Refresh(__instance.playerXp);
}
else
{
MelonLogger.Error("XP UI not found. Player XP will show when some is collected");
}
}
if (skipUsed)
{
newPlayerLevel = __instance.GetCharacterLevel();
xpToRefund = XpUtility.LevelToXp(newPlayerLevel) - XpUtility.LevelToXp(newPlayerLevel - 1);
xpToRefund = Convert.ToInt32((double)xpToRefund * 0.75);
__instance.AddXp(xpToRefund);
MelonLogger.Msg("Skip used. " + xpToRefund + " XP has been refunded from the previous levelup");
skipUsed = false;
}
}
private static void BanishPostfix(LevelupScreen __instance)
{
lvlScreen = __instance;
PlayerInventory playerInventory = GameManager.Instance.GetPlayerInventory();
newPlayerLevel = playerInventory.GetCharacterLevel();
xpToRefund = XpUtility.LevelToXp(newPlayerLevel + 1) - XpUtility.LevelToXp(newPlayerLevel);
playerInventory.AddLevel();
PlayerXp playerXp = playerInventory.playerXp;
playerXp.level -= 1;
PlayerXp playerXp2 = playerInventory.playerXp;
playerXp2.xp -= xpToRefund;
MelonLogger.Msg("Banish used. Reroll granted");
if ((Object)(object)lvlScreen != (Object)null)
{
lvlScreen.level = playerInventory.playerXp.level;
lvlScreen.currentLevel = playerInventory.playerXp.level;
}
else
{
MelonLogger.Error("Level Screen instance not found. Player level will be updated on next level-up");
}
encWindow = Object.FindFirstObjectByType<EncounterWindows>();
if ((Object)(object)encWindow != (Object)null)
{
encWindow.currentLevel = playerInventory.playerXp.level;
}
else
{
MelonLogger.Error("Level Screen encounter window object not found. Player level will be updated on next level-up");
}
xpb = Object.FindFirstObjectByType<XpBarUI>();
if ((Object)(object)xpb != (Object)null)
{
xpb.Refresh(playerInventory.playerXp);
}
else
{
MelonLogger.Error("XP UI not found. Player XP will show when some is collected");
}
}
private static void SkipPostfix(LevelupScreen __instance)
{
lvlScreen = __instance;
PlayerInventory playerInventory = GameManager.Instance.GetPlayerInventory();
newPlayerLevel = playerInventory.GetCharacterLevel();
xpToRefund = XpUtility.LevelToXp(newPlayerLevel) - XpUtility.LevelToXp(newPlayerLevel - 1);
xpToRefund = Convert.ToInt32((double)xpToRefund * 0.75);
playerInventory.AddXp(xpToRefund);
MelonLogger.Msg("Skip used. " + xpToRefund + " XP has been refunded from the previous levelup");
}
private static Type FindType(string fullName)
{
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
foreach (Assembly assembly in assemblies)
{
try
{
Type type = assembly.GetType(fullName, throwOnError: false);
if (type != null)
{
return type;
}
}
catch
{
}
}
return null;
}
private void TryPatch()
{
//IL_0094: Unknown result type (might be due to invalid IL or missing references)
//IL_009a: Expected O, but got Unknown
//IL_014f: Unknown result type (might be due to invalid IL or missing references)
//IL_0156: Expected O, but got Unknown
Type type = FindType(LevelTypeName);
if (type == null)
{
MelonLogger.Error("Type not found: " + LevelTypeName);
return;
}
MethodInfo method = type.GetMethod(LevelMethodName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (method == null)
{
MelonLogger.Error("Method not found: " + type.FullName + "." + LevelMethodName + "()");
return;
}
HarmonyMethod val = new HarmonyMethod(typeof(BetterBanishes).GetMethod("BanishPostfix", BindingFlags.Static | BindingFlags.NonPublic));
HarmonyInstance.Patch((MethodBase)method, (HarmonyMethod)null, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
MelonLogger.Msg("Patched " + type.FullName + "." + LevelMethodName + "()");
MethodInfo method2 = type.GetMethod(SkipMethodName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (method2 == null)
{
MelonLogger.Error("Method not found: " + type.FullName + "." + SkipMethodName + "()");
}
else
{
HarmonyMethod val2 = new HarmonyMethod(typeof(BetterBanishes).GetMethod("SkipPostfix", BindingFlags.Static | BindingFlags.NonPublic));
HarmonyInstance.Patch((MethodBase)method2, (HarmonyMethod)null, val2, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
MelonLogger.Msg("Patched " + type.FullName + "." + SkipMethodName + "()");
}
}
public override void OnInitializeMelon()
{
TryPatch();
}
}
}
namespace MelonLoader
{
public class MelonMod : BasePlugin
{
public Harmony HarmonyInstance;
public static MelonMod melonModRef;
public virtual string PLUGIN_GUID => "author.game.modname";
public virtual string PLUGIN_NAME => "Mod Name Here";
public virtual string PLUGIN_VERSION => "0.0.1";
public MelonMod()
{
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Expected O, but got Unknown
HarmonyInstance = new Harmony(PLUGIN_GUID);
melonModRef = this;
}
public virtual void OnInitializeMelon()
{
}
public virtual void OnLateInitializeMelon()
{
}
public virtual void OnFixedUpdate()
{
}
public virtual void OnUpdate()
{
}
public override void Load()
{
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Expected O, but got Unknown
//IL_0059: Unknown result type (might be due to invalid IL or missing references)
//IL_005f: Expected O, but got Unknown
OnInitializeMelon();
HarmonyMethod val = new HarmonyMethod(typeof(MelonMod).GetMethod("FixedUpdate"));
HarmonyInstance.Patch((MethodBase)typeof(MyTime).GetMethod("FixedUpdate"), (HarmonyMethod)null, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
HarmonyMethod val2 = new HarmonyMethod(typeof(MelonMod).GetMethod("Update"));
HarmonyInstance.Patch((MethodBase)typeof(MyTime).GetMethod("Update"), (HarmonyMethod)null, val2, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
}
public void Awake()
{
OnLateInitializeMelon();
}
public static void FixedUpdate()
{
melonModRef.OnFixedUpdate();
}
public static void Update()
{
melonModRef.OnUpdate();
}
}
public class MelonLogger
{
private static ManualLogSource log;
private static bool logAdded;
public static void Msg(string message)
{
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Expected O, but got Unknown
if (!logAdded)
{
log = new ManualLogSource(((AssemblyTitleAttribute)Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyTitleAttribute), inherit: false)[0]).Title);
Logger.Sources.Add((ILogSource)(object)log);
logAdded = true;
}
log.LogInfo((object)message);
}
public static void Error(string message)
{
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Expected O, but got Unknown
if (!logAdded)
{
log = new ManualLogSource(((AssemblyTitleAttribute)Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyTitleAttribute), inherit: false)[0]).Title);
Logger.Sources.Add((ILogSource)(object)log);
logAdded = true;
}
log.LogError((object)message);
}
}
}