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 SkillXpMead v1.1.0
plugins/SkillXpMead/SkillXpMead.dll
Decompiled 2 months agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; 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 Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; 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("SkillXpMead")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("SkillXpMead")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("49bc217c-e6ea-4b2d-9b60-4089e4610b8d")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8.1", FrameworkDisplayName = ".NET Framework 4.8.1")] [assembly: AssemblyVersion("1.0.0.0")] namespace SkillXpMead; [BepInPlugin("com.example.skillxpmead", "Skill XP Mead", "1.1.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class SkillXpMeadPlugin : BaseUnityPlugin { [HarmonyPatch(typeof(Skills), "RaiseSkill")] private static class Skills_RaiseSkill_Patch { private static void Prefix(SkillType skillType, ref float factor) { Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null) && HasBoost(localPlayer)) { float num = Mathf.Max(0f, CfgMultiplier.Value); factor *= num; } } } public const string ModGuid = "com.example.skillxpmead"; public const string ModName = "Skill XP Mead"; public const string ModVersion = "1.1.0"; internal static ManualLogSource Log; private static ConfigEntry<float> CfgMultiplier; private static ConfigEntry<float> CfgDurationSeconds; private static ConfigEntry<string> CfgRecipe; private static ConfigEntry<int> CfgOutputAmount; private static ConfigEntry<int> CfgMinStationLevel; internal const string EffectInternalName = "SE_SkillXpBoost_DG"; internal const string ItemPrefabName = "DG_SkillXpMead"; private static readonly int EffectHash = Animator.StringToHash("SE_SkillXpBoost_DG"); internal static CustomStatusEffect SkillXpEffect; private Harmony _harmony; private void Awake() { //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; CfgMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("General", "SkillXpMultiplier", 5f, "XP gain multilpyer. 5 = +400% (x5)."); CfgDurationSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("General", "DurationSeconds", 300f, "Effect duration in seconds. 300 = 5 min."); CfgRecipe = ((BaseUnityPlugin)this).Config.Bind<string>("Recipe", "Ingredients", "Honey:10,Thistle:5,Raspberry:10", "Recipe in format: Prefab:Amount,Prefab:Amount,... Example: Honey:10,Thistle:5,Raspberry:10"); CfgOutputAmount = ((BaseUnityPlugin)this).Config.Bind<int>("Recipe", "OutputAmount", 1, "amount of potions per 1 craft."); CfgMinStationLevel = ((BaseUnityPlugin)this).Config.Bind<int>("Recipe", "MinStationLevel", 1, "min lvl of StationLevel."); AddStatusEffect(); PrefabManager.OnVanillaPrefabsAvailable += OnVanillaPrefabsAvailable; _harmony = new Harmony("com.example.skillxpmead"); _harmony.PatchAll(); Log.LogInfo((object)"Skill XP Mead 1.1.0 loaded"); } private void OnDestroy() { PrefabManager.OnVanillaPrefabsAvailable -= OnVanillaPrefabsAvailable; Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } private void AddStatusEffect() { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Expected O, but got Unknown SE_Stats val = ScriptableObject.CreateInstance<SE_Stats>(); ((Object)val).name = "SE_SkillXpBoost_DG"; TrySetNameHash((StatusEffect)(object)val, EffectHash); ((StatusEffect)val).m_name = "Mastery"; ((StatusEffect)val).m_tooltip = "Skill XP gain boosted"; ((StatusEffect)val).m_ttl = Mathf.Max(1f, CfgDurationSeconds.Value); ((StatusEffect)val).m_startMessageType = (MessageType)1; ((StatusEffect)val).m_startMessage = "You feel ready to learn anything."; ((StatusEffect)val).m_stopMessageType = (MessageType)1; ((StatusEffect)val).m_stopMessage = "The surge of mastery fades."; SkillXpEffect = new CustomStatusEffect((StatusEffect)(object)val, false); ItemManager.Instance.AddStatusEffect(SkillXpEffect); } private void OnVanillaPrefabsAvailable() { try { AddPotionItemInCauldron(); } catch (Exception ex) { Log.LogError((object)ex); } finally { PrefabManager.OnVanillaPrefabsAvailable -= OnVanillaPrefabsAvailable; } } private void AddPotionItemInCauldron() { //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0091: 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_00c0: Expected O, but got Unknown //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Expected O, but got Unknown string[] source = new string[3] { "MeadTasty", "MeadHealthMinor", "MeadStaminaMinor" }; string text = source.FirstOrDefault((string p) => (Object)(object)PrefabManager.Instance.GetPrefab(p) != (Object)null); if (string.IsNullOrEmpty(text)) { Log.LogError((object)"Can't find vanilla mead prefab to clone (MeadTasty/MeadHealthMinor/MeadStaminaMinor)."); return; } ItemConfig val = new ItemConfig { Name = "Mead of Mastery", Description = "Increases skill XP gain.", CraftingStation = "piece_cauldron", MinStationLevel = Math.Max(1, CfgMinStationLevel.Value), Amount = Math.Max(1, CfgOutputAmount.Value) }; List<(string, int)> list = ParseRecipe(CfgRecipe.Value); if (list.Count == 0) { Log.LogWarning((object)"Recipe config parsed as empty. Falling back to default Honey:10,Thistle:5,Raspberry:10"); list = new List<(string, int)> { ("Honey", 10), ("Thistle", 5), ("Raspberry", 10) }; } foreach (var item in list) { val.AddRequirement(item.Item1, item.Item2, 0); } CustomItem val2 = new CustomItem("DG_SkillXpMead", text, val); ItemManager.Instance.AddItem(val2); val2.ItemDrop.m_itemData.m_shared.m_consumeStatusEffect = SkillXpEffect.StatusEffect; try { Sprite[] icons = val2.ItemDrop.m_itemData.m_shared.m_icons; if (icons != null && icons.Length != 0 && (Object)(object)icons[0] != (Object)null) { SkillXpEffect.StatusEffect.m_icon = icons[0]; } } catch { } Log.LogInfo((object)string.Format("Added {0} (cloned from {1}) recipe='{2}' output={3}", "DG_SkillXpMead", text, CfgRecipe.Value, val.Amount)); Log.LogInfo((object)"NOTE: Changing recipe in config usually requires game restart to take effect."); } private static List<(string prefab, int amount)> ParseRecipe(string s) { List<(string, int)> list = new List<(string, int)>(); if (string.IsNullOrWhiteSpace(s)) { return list; } string[] array = s.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries); foreach (string text in array) { string text2 = text.Trim(); if (text2.Length == 0) { continue; } string[] array2 = (from x in text2.Split(new char[1] { ':' }, StringSplitOptions.RemoveEmptyEntries) select x.Trim()).ToArray(); if (array2.Length != 2) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)("Bad recipe part '" + text2 + "'. Expected Prefab:Amount")); } continue; } string item = array2[0]; if (!int.TryParse(array2[1], out var result) || result <= 0) { ManualLogSource log2 = Log; if (log2 != null) { log2.LogWarning((object)("Bad amount in recipe part '" + text2 + "'.")); } } else { list.Add((item, result)); } } return list; } private static void TrySetNameHash(StatusEffect effect, int hash) { try { FieldInfo field = ((object)effect).GetType().GetField("m_nameHash", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null && field.FieldType == typeof(int)) { field.SetValue(effect, hash); } } catch { } } internal static bool HasBoost(Player p) { if ((Object)(object)p == (Object)null) { return false; } SEMan sEMan = ((Character)p).GetSEMan(); if (sEMan == null) { return false; } try { if (sEMan.HaveStatusEffect(EffectHash)) { return true; } } catch { } try { return typeof(SEMan).GetField("m_statusEffects", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(sEMan) is List<StatusEffect> source && source.Any((StatusEffect se) => (Object)(object)se != (Object)null && ((Object)se).name == "SE_SkillXpBoost_DG"); } catch { return false; } } }