Decompiled source of SkillFloors v1.1.2

plugins/SkillFloors.dll

Decompiled a week 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 System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Jotunn;
using Jotunn.Utils;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using TMPro;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("SkillFloors")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("SkillFloors")]
[assembly: AssemblyCopyright("Copyright ©  2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("e3243d22-4307-4008-ba36-9f326008cde5")]
[assembly: AssemblyFileVersion("1.1.2")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.2.0")]
[module: UnverifiableCode]
namespace SkillFloors;

[BepInPlugin("Armikur.mod.Valheim.SkillFloors", "SkillFloors", "1.1.2")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
internal class SkillFloors : BaseUnityPlugin
{
	public const string PluginName = "SkillFloors";

	internal const string PluginAuthor = "Armikur";

	public const string PluginGUID = "Armikur.mod.Valheim.SkillFloors";

	public const string PluginVersion = "1.1.2";

	private readonly Harmony HarmonyInstance = new Harmony("Armikur.mod.Valheim.SkillFloors");

	internal static ConfigEntry<float> Config_SkillFloors_FloorXPGainRate;

	internal static ConfigEntry<bool> Config_SkillFloors_EnableDebugLogging;

	public static Dictionary<SkillType, SkillFloors_SkillFloorData> SkillFloors_SkillFloorDictionary = new Dictionary<SkillType, SkillFloors_SkillFloorData>();

	private void Awake()
	{
		CreateConfigValues();
		Logger.LogInfo((object)"Armikur's SkillFloors mod 1.1.2 has loaded!");
		Assembly executingAssembly = Assembly.GetExecutingAssembly();
		HarmonyInstance.PatchAll(executingAssembly);
	}

	private void CreateConfigValues()
	{
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Expected O, but got Unknown
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: Expected O, but got Unknown
		//IL_0069: Unknown result type (might be due to invalid IL or missing references)
		//IL_0073: Expected O, but got Unknown
		Config_SkillFloors_FloorXPGainRate = ((BaseUnityPlugin)this).Config.Bind<float>("Server Config", "Floor XP Gain Rate", 0.15f, new ConfigDescription("Multiplier for how much XP floor skills gain relative to regular skills (e.g., 0.15 = 15%). Values over 1 will give more XP than normal; helpful for catching up.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1.5f), new object[1] { (object)new ConfigurationManagerAttributes
		{
			IsAdminOnly = true
		} }));
		Config_SkillFloors_EnableDebugLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("Client Config", "Enable Debug Logging", false, new ConfigDescription("Shows each skill floor increase in the BepInEx window.", (AcceptableValueBase)null, Array.Empty<object>()));
	}

	public static void SkillFloors_GainFloorXP(Skill skill, float xpGained)
	{
		//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_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: 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_00cf: Unknown result type (might be due to invalid IL or missing references)
		SkillType skill2 = skill.m_info.m_skill;
		if (!SkillFloors_SkillFloorDictionary.TryGetValue(skill2, out var value))
		{
			value = new SkillFloors_SkillFloorData();
			SkillFloors_SkillFloorDictionary[skill2] = value;
		}
		float value2 = Config_SkillFloors_FloorXPGainRate.Value;
		float num = xpGained * value2;
		value.SkillFloors_Floor_XPProgress += num;
		float num2 = SkillFloors_CalculateRequiredFloorXP(value.SkillFloors_Floor_Level);
		if (value.SkillFloors_Floor_XPProgress >= num2)
		{
			value.SkillFloors_Floor_Level += 1f;
			value.SkillFloors_Floor_XPProgress = 0f;
			Logger.LogInfo((object)$"[SkillFloor] ---- {skill2} floor level increased to {value.SkillFloors_Floor_Level} ----");
		}
		float level = skill.m_level;
		float accumulator = skill.m_accumulator;
		float nextLevelRequirement = skill.GetNextLevelRequirement();
		if (Config_SkillFloors_EnableDebugLogging.Value)
		{
			Logger.LogInfo((object)$"[SkillFloor] {skill2} Floor: {value.SkillFloors_Floor_Level} ({value.SkillFloors_Floor_XPProgress}/{num2} | Skill: {level} ({accumulator}/{nextLevelRequirement})");
		}
	}

	public static float SkillFloors_GetSkillFloor(SkillType type)
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		if (!SkillFloors_SkillFloorDictionary.TryGetValue(type, out var value))
		{
			return 0f;
		}
		return value.SkillFloors_Floor_Level;
	}

	public static float SkillFloors_CalculateRequiredFloorXP(float currentFloorLevel)
	{
		return Mathf.Pow(Mathf.Floor(currentFloorLevel + 1f), 1.5f) * 0.5f + 0.5f;
	}
}
public class SkillFloors_SkillFloorData
{
	public float SkillFloors_Floor_Level;

	public float SkillFloors_Floor_XPProgress;
}
[HarmonyPatch(typeof(Skill), "Raise")]
public class SkillFloors_Patch_SkillFloor_Raise
{
	private static void Postfix(Skill __instance, float factor)
	{
		float increseStep = __instance.m_info.m_increseStep;
		float skillGainRate = Game.m_skillGainRate;
		float xpGained = increseStep * factor * skillGainRate;
		SkillFloors.SkillFloors_GainFloorXP(__instance, xpGained);
	}
}
[HarmonyPatch(typeof(Player), "OnDeath")]
public class SkillFloors_Patch_Player_OnDeath
{
	private static void Postfix(Player __instance)
	{
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: 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_003c: Unknown result type (might be due to invalid IL or missing references)
		foreach (Skill skill2 in ((Character)__instance).GetSkills().GetSkillList())
		{
			SkillType skill = skill2.m_info.m_skill;
			float num = SkillFloors.SkillFloors_GetSkillFloor(skill);
			if (skill2.m_level < num)
			{
				Debug.Log((object)$"[SkillFloors] Preventing {skill} from dropping below floor level {num}");
				skill2.m_level = num;
			}
		}
	}
}
[HarmonyPatch(typeof(SkillsDialog), "Setup")]
public class SkillFloors_Patch_SkillsDialog
{
	private static void Postfix(SkillsDialog __instance, Player player)
	{
		//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_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_0145: Unknown result type (might be due to invalid IL or missing references)
		//IL_0154: Unknown result type (might be due to invalid IL or missing references)
		//IL_0159: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
		List<Skill> skillList = ((Character)player).GetSkills().GetSkillList();
		for (int i = 0; i < skillList.Count && i < __instance.m_elements.Count; i++)
		{
			SkillType skill = skillList[i].m_info.m_skill;
			float num = SkillFloors.SkillFloors_GetSkillFloor(skill);
			GameObject val = __instance.m_elements[i];
			TMP_Text component = ((Component)Utils.FindChild(val.transform, "name", (IterativeSearchType)0)).GetComponent<TMP_Text>();
			if ((Object)(object)component != (Object)null && num > 0f)
			{
				string arg = Localization.instance.Localize("$skill_" + ((object)(SkillType)(ref skill)).ToString().ToLower());
				component.text = $"{arg} <color=#7D9FB8><size=85%>{Mathf.FloorToInt(num)}</size></color>";
			}
			if (!SkillFloors.SkillFloors_SkillFloorDictionary.TryGetValue(skill, out var value))
			{
				continue;
			}
			GuiBar component2 = ((Component)Utils.FindChild(val.transform, "currentlevel", (IterativeSearchType)0)).GetComponent<GuiBar>();
			if ((Object)(object)component2 != (Object)null)
			{
				Transform obj = Utils.FindChild(val.transform, "floorlevel", (IterativeSearchType)0);
				GuiBar val2 = ((obj != null) ? ((Component)obj).GetComponent<GuiBar>() : null);
				GuiBar val3;
				if ((Object)(object)val2 != (Object)null)
				{
					val3 = val2;
				}
				else
				{
					GameObject obj2 = Object.Instantiate<GameObject>(((Component)component2).gameObject, ((Component)component2).transform.parent);
					((Object)obj2).name = "floorlevel";
					val3 = obj2.GetComponent<GuiBar>();
					RectTransform component3 = obj2.GetComponent<RectTransform>();
					component3.anchoredPosition -= new Vector2(0f, 2f);
					component3.SetSizeWithCurrentAnchors((Axis)1, 2f);
				}
				float num2 = SkillFloors.SkillFloors_CalculateRequiredFloorXP(value.SkillFloors_Floor_Level);
				float value2 = Mathf.Clamp01(value.SkillFloors_Floor_XPProgress / num2);
				val3.SetValue(value2);
				val3.SetColor(new Color(0.66f, 0.76f, 0.84f, 1f));
			}
		}
	}
}
public static class SkillFloors_SaveLoad_JSDN
{
	private const string SkillFloors_SaveKey = "SkillFloors_SkillFloorData_JSON";

	public static void SkillFloors_Save(Player player)
	{
		//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_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0016: Expected O, but got Unknown
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0023: Expected O, but got Unknown
		JsonSerializerSettings val = new JsonSerializerSettings
		{
			Converters = new List<JsonConverter> { (JsonConverter)new StringEnumConverter() },
			Formatting = (Formatting)0
		};
		string value = JsonConvert.SerializeObject((object)SkillFloors.SkillFloors_SkillFloorDictionary, val);
		player.m_customData["SkillFloors_SkillFloorData_JSON"] = value;
	}

	public static void SkillFloors_Load(Player player)
	{
		//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_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: Expected O, but got Unknown
		//IL_0031: Expected O, but got Unknown
		if (player.m_customData.TryGetValue("SkillFloors_SkillFloorData_JSON", out var value))
		{
			JsonSerializerSettings val = new JsonSerializerSettings
			{
				Converters = new List<JsonConverter> { (JsonConverter)new StringEnumConverter() }
			};
			Dictionary<SkillType, SkillFloors_SkillFloorData> dictionary = JsonConvert.DeserializeObject<Dictionary<SkillType, SkillFloors_SkillFloorData>>(value, val);
			if (dictionary != null)
			{
				SkillFloors.SkillFloors_SkillFloorDictionary = dictionary;
			}
		}
	}
}
[HarmonyPatch(typeof(Player), "Save")]
public class SkillFloors_Patch_Player_Save
{
	private static void Prefix(Player __instance)
	{
		SkillFloors_SaveLoad_JSDN.SkillFloors_Save(__instance);
	}
}
[HarmonyPatch(typeof(Player), "Load")]
public class SkillFloors_Patch_Player_Load
{
	private static void Postfix(Player __instance)
	{
		SkillFloors_SaveLoad_JSDN.SkillFloors_Load(__instance);
	}
}