Decompiled source of PerkRespec v1.0.1

BepInEx\plugins\PerkRespec.dll

Decompiled 12 hours ago
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 BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("PerkRespec")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("PerkRespec")]
[assembly: AssemblyCopyright("Copyright ©  2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("5d88a250-062a-4cbf-bbcf-9f398539636d")]
[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 PerkRespec
{
	public class GameConfig
	{
		public const bool RespecNotAllowedOutsideByDefault = false;

		public bool IsModEnabled => EnabledEntry?.Value ?? true;

		public bool AllowRespecFromAnywhere => AllowRespecFromAnywhereEntry?.Value ?? false;

		private ConfigEntry<bool> AllowRespecFromAnywhereEntry { get; set; } = null;


		private ConfigEntry<bool> EnabledEntry { get; set; } = null;


		public GameConfig(ConfigFile config)
		{
			EnabledEntry = config.Bind<bool>("General", "EnableMod", true, "Enable or disable the mod");
			AllowRespecFromAnywhereEntry = config.Bind<bool>("General", "AllowRespecFromAnywhere", false, "true: allow the respec from anywhere; false: allow respec only in towns");
		}
	}
	public static class GameProvider
	{
		public static ManualLogSource Log { get; set; }

		public static GameConfig Config { get; set; }

		public static BaseUnityPlugin Plugin { get; set; }
	}
	[BepInPlugin("scotilen.perkrespec", "PerkRespec", "1.0.1")]
	public class GamePlugin : BaseUnityPlugin
	{
		private void Awake()
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			GameProvider.Plugin = (BaseUnityPlugin)(object)this;
			GameProvider.Config = new GameConfig(((BaseUnityPlugin)this).Config);
			GameProvider.Log = ((BaseUnityPlugin)this).Logger;
			((BaseUnityPlugin)this).Logger.LogInfo((object)"PerkRespec loaded");
			new Harmony("scotilen.perkrespec").PatchAll();
		}
	}
	public class Versioning
	{
		public const string ModIdentifier = "scotilen.perkrespec";

		public const string ModName = "PerkRespec";

		public const string WebsiteUrl = "https://github.com/miguelcjalmeida/PerkRespec";

		public const string Description = "Allow respec of perks in any city, or in any moment if you prefer.";

		public const string Author = "Scotilen";

		public const string SemanticVersion = "1.0.1";

		public const int LastUpdateDate = 20251221;

		public static IList<string> Dependencies = DetermineDependencies();

		private static IList<string> DetermineDependencies()
		{
			List<string> list = new List<string>();
			list.Add("BepInEx-BepInExPack_AcrossTheObelisk-5.4.23");
			return list;
		}
	}
}
namespace PerkRespec.AllowPerkRespecing
{
	public class AllowPerkRespecUseCase
	{
		public int originalCityTier = 0;

		public bool originalCharIsInTown = false;

		public void PretendToBeInFirstCity(int originalCityTier, bool originalCharIsInTown)
		{
			if (GameProvider.Config.IsModEnabled && ShouldAllowPerkEditing())
			{
				this.originalCityTier = originalCityTier;
				this.originalCharIsInTown = originalCharIsInTown;
				GameProvider.Log.LogInfo((object)"Pretending to be in first city");
				SetTownTier(0);
				SetCharInTown(isInTown: true);
			}
		}

		public void StopPretending()
		{
			if (GameProvider.Config.IsModEnabled)
			{
				GameProvider.Log.LogInfo((object)"Stopped pretending to be in first city");
				SetTownTier(originalCityTier);
				SetCharInTown(originalCharIsInTown);
			}
		}

		private bool ShouldAllowPerkEditing()
		{
			if ((Object)(object)PerkTree.Instance == (Object)null)
			{
				return false;
			}
			if ((Object)(object)AtOManager.Instance == (Object)null)
			{
				return false;
			}
			if (GameProvider.Config.AllowRespecFromAnywhere)
			{
				return true;
			}
			return AtOManager.Instance.CharInTown();
		}

		private void SetTownTier(int tier)
		{
			GameProvider.Log.LogInfo((object)$"Setting town tier to {tier}");
			SetAttributeValue(AtOManager.Instance, "townTier", tier);
			AtOManager.Instance.gameHandicap = tier;
		}

		private void SetCharInTown(bool isInTown)
		{
			if (GameProvider.Config.AllowRespecFromAnywhere)
			{
				string text = (isInTown ? "yes" : "no");
				GameProvider.Log.LogInfo((object)("Setting char to be in town? " + text));
				SetAttributeValue(AtOManager.Instance, "charInTown", isInTown);
			}
		}

		private void SetAttributeValue(object instance, string key, object value)
		{
			if (instance == null)
			{
				return;
			}
			Type type = instance.GetType();
			if (!(type == null))
			{
				FieldInfo field = type.GetField(key, BindingFlags.Instance | BindingFlags.NonPublic);
				if (!(field == null))
				{
					field.SetValue(instance, value);
				}
			}
		}
	}
	public class PerkRespecPatches
	{
		[HarmonyPatch(typeof(PerkTree), "Show")]
		public class PerkTreeShowPatch
		{
			public static AllowPerkRespecUseCase useCase = new AllowPerkRespecUseCase();

			public static void Prefix()
			{
				int townTier = AtOManager.Instance.GetTownTier();
				bool originalCharIsInTown = AtOManager.Instance.CharInTown();
				useCase.PretendToBeInFirstCity(townTier, originalCharIsInTown);
			}
		}

		[HarmonyPatch(typeof(PerkTree), "HideAction")]
		public class PerkTreeHideActionPatch
		{
			public static void Postfix()
			{
				PerkTreeShowPatch.useCase.StopPretending();
			}
		}
	}
}