Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of ArcaneAttunement v1.0.3
plugins/ArcaneAttunement.dll
Decompiled a day agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Threading; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("Snook")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCopyright("Copyright Snook 2026. All rights reserved.")] [assembly: AssemblyDescription("Client-side baseline Eitr from Elemental Magic and Blood Magic.")] [assembly: AssemblyFileVersion("1.0.3.0")] [assembly: AssemblyInformationalVersion("1.0.3+3f6a3f63ea607c7cb6be11e9bd9c32777ef814af")] [assembly: AssemblyProduct("Arcane Attunement")] [assembly: AssemblyTitle("ArcaneAttunement")] [assembly: AssemblyVersion("1.0.3.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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 ArcaneAttunement { public enum Preset { Attuned, Balanced, PowerOverwhelming } public readonly struct PresetRates { public float EitrPerLevel { get; } public float RegenPercentPer5Levels { get; } public PresetRates(float eitrPerLevel, float regenPercentPer5Levels) { EitrPerLevel = eitrPerLevel; RegenPercentPer5Levels = regenPercentPer5Levels; } } public static class AttunementMath { public static PresetRates RatesFor(Preset preset) { return preset switch { Preset.Attuned => new PresetRates(0.5f, 1.5f), Preset.Balanced => new PresetRates(1f, 2f), Preset.PowerOverwhelming => new PresetRates(1.5f, 5f), _ => throw new ArgumentOutOfRangeException("preset", preset, "Unknown preset."), }; } public static float MaxEitrBonus(float elementalLevel, float bloodLevel, float eitrPerLevel) { return (elementalLevel + bloodLevel) * eitrPerLevel; } public static int RegenSteps(float elementalLevel, float bloodLevel) { return StepsPerFive(elementalLevel) + StepsPerFive(bloodLevel); } public static float RegenFraction(float elementalLevel, float bloodLevel, float regenPercentPer5Levels) { return (float)RegenSteps(elementalLevel, bloodLevel) * (regenPercentPer5Levels / 100f); } public static string ToConfigString(Preset preset) { if ((uint)preset <= 2u) { return preset.ToString(); } throw new ArgumentOutOfRangeException("preset", preset, "Unknown preset."); } public static bool TryParsePreset(string text, out Preset preset) { preset = Preset.Attuned; if (string.IsNullOrWhiteSpace(text)) { return false; } string text2 = text.Trim(); if (text2.Equals("Attuned", StringComparison.OrdinalIgnoreCase)) { preset = Preset.Attuned; return true; } if (text2.Equals("Balanced", StringComparison.OrdinalIgnoreCase)) { preset = Preset.Balanced; return true; } if (text2.Equals("PowerOverwhelming", StringComparison.OrdinalIgnoreCase)) { preset = Preset.PowerOverwhelming; return true; } return false; } private static int StepsPerFive(float level) { return (int)Math.Floor((double)level / 5.0); } } [HarmonyPatch(typeof(Player), "GetTotalFoodValue")] internal static class GetTotalFoodValuePatch { [HarmonyPriority(0)] private static void Postfix(Player __instance, ref float eitr, Skills ___m_skills) { if (!Plugin.Enabled) { return; } try { if (Plugin.IsLocal(__instance)) { eitr += SkillEitr.MaxBonus(___m_skills); } } catch (Exception exception) { Plugin.Fail(exception); } } } [HarmonyPatch(typeof(SEMan), "ModifyEitrRegen")] internal static class ModifyEitrRegenPatch { private static void Postfix(ref float eitrMultiplier, Character ___m_character) { if (!Plugin.Enabled) { return; } try { Player player = (Player)(object)((___m_character is Player) ? ___m_character : null); if (Plugin.IsLocal(player)) { eitrMultiplier += SkillEitr.RegenBonus(GameAccess.SkillsOf(player)); } } catch (Exception exception) { Plugin.Fail(exception); } } } internal static class GameAccess { private static FieldRef<Player> _localPlayer; private static FieldRef<Player, Skills> _skills; private static FieldRef<Skills, Dictionary<SkillType, Skill>> _skillData; private static FieldRef<Skill, float> _skillLevel; internal static void Init() { _localPlayer = AccessTools.StaticFieldRefAccess<Player>(RequireField(typeof(Player), "m_localPlayer")); _skills = AccessTools.FieldRefAccess<Player, Skills>("m_skills"); _skillData = AccessTools.FieldRefAccess<Skills, Dictionary<SkillType, Skill>>("m_skillData"); _skillLevel = AccessTools.FieldRefAccess<Skill, float>("m_level"); } internal static Player LocalPlayer() { return _localPlayer.Invoke(); } internal static Skills SkillsOf(Player player) { return _skills.Invoke(player); } internal static Dictionary<SkillType, Skill> SkillData(Skills skills) { return _skillData.Invoke(skills); } internal static float SkillLevel(Skill skill) { return _skillLevel.Invoke(skill); } private static FieldInfo RequireField(Type type, string name) { FieldInfo fieldInfo = AccessTools.Field(type, name); if (fieldInfo == null) { throw new MissingFieldException(type.FullName, name); } return fieldInfo; } } [BepInPlugin("snook.arcaneattunement", "Arcane Attunement", "1.0.3")] public sealed class Plugin : BaseUnityPlugin { public const string Guid = "snook.arcaneattunement"; public const string Name = "Arcane Attunement"; public const string Version = "1.0.3"; private static ManualLogSource Log; private static int _failureLogged; private static string _warnedPreset; internal static bool Enabled { get; private set; } internal static float EitrPerLevel { get; private set; } internal static float RegenPercentPer5Levels { get; private set; } private void Awake() { //IL_00a6: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; ConfigEntry<bool> obj = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Apply the skill Eitr bonus. Read when the game starts. Changing this requires a restart."); ConfigEntry<string> preset = ((BaseUnityPlugin)this).Config.Bind<string>("General", "Preset", "Balanced", "Accepted values: Attuned, Balanced, PowerOverwhelming.\nCase does not matter, and surrounding whitespace is ignored.\nAttuned: 0.5 Eitr per skill level, +1.5% Eitr regen per 5 levels.\nBalanced: 1.0 Eitr per skill level, +2% Eitr regen per 5 levels.\nPowerOverwhelming: 1.5 Eitr per skill level, +5% Eitr regen per 5 levels.\nA config manager applies this immediately. A hand edit of the file applies the next time the game starts."); Enabled = obj.Value; Preset preset2 = ApplyPreset(preset.Value); preset.SettingChanged += delegate { Preset preset3; bool num = AttunementMath.TryParsePreset(preset.Value, out preset3); ApplyPreset(preset.Value); if (num && Log != null) { Log.LogInfo((object)("Preset is now " + AttunementMath.ToConfigString(preset3) + ": " + EitrPerLevel.ToString("0.0") + " Eitr/level, +" + RegenPercentPer5Levels.ToString("0.0") + "% Eitr regen per 5 levels.")); } }; if (!Enabled) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"Arcane Attunement is disabled in config."); return; } try { GameAccess.Init(); new Harmony("snook.arcaneattunement").PatchAll(typeof(Plugin).Assembly); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Arcane Attunement 1.0.3 (" + AttunementMath.ToConfigString(preset2) + "): " + EitrPerLevel.ToString("0.0") + " Eitr/level, +" + RegenPercentPer5Levels.ToString("0.0") + "% Eitr regen per 5 levels.")); } catch (Exception exception) { Fail(exception); } } private static Preset ApplyPreset(string text) { if (!AttunementMath.TryParsePreset(text, out var preset)) { string text2 = text ?? string.Empty; if (!string.Equals(text2, _warnedPreset, StringComparison.Ordinal)) { _warnedPreset = text2; if (Log != null) { Log.LogWarning((object)("Preset '" + text2 + "' is not valid. Use Attuned, Balanced, or PowerOverwhelming. Balanced is used.")); } } preset = Preset.Balanced; } else { _warnedPreset = null; } PresetRates presetRates = AttunementMath.RatesFor(preset); EitrPerLevel = presetRates.EitrPerLevel; RegenPercentPer5Levels = presetRates.RegenPercentPer5Levels; return preset; } internal static bool IsLocal(Player player) { if (Enabled && (Object)(object)player != (Object)null) { return (Object)(object)player == (Object)(object)GameAccess.LocalPlayer(); } return false; } internal static void Fail(Exception exception) { Enabled = false; if (Interlocked.Exchange(ref _failureLogged, 1) == 0) { string text = "Arcane Attunement disabled itself after an error. Player loading and updates are left to run without the bonus.\n" + exception; if (Log != null) { Log.LogError((object)text); } } } } internal static class SkillEitr { internal static float Level(Skills skills, SkillType skillType) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)skills == (Object)null) { return 0f; } Dictionary<SkillType, Skill> dictionary = GameAccess.SkillData(skills); if (dictionary == null) { return 0f; } if (!dictionary.TryGetValue(skillType, out var value) || value == null) { return 0f; } return GameAccess.SkillLevel(value); } internal static float MaxBonus(Skills skills) { return AttunementMath.MaxEitrBonus(Level(skills, (SkillType)9), Level(skills, (SkillType)10), Plugin.EitrPerLevel); } internal static float RegenBonus(Skills skills) { return AttunementMath.RegenFraction(Level(skills, (SkillType)9), Level(skills, (SkillType)10), Plugin.RegenPercentPer5Levels); } } }