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 SparkleLoaderTweaks v1.1.0
plugins/SparkleLoaderTweaks.dll
Decompiled a day agousing System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using EntityStates.Loader; using HarmonyLib; using Microsoft.CodeAnalysis; using RoR2; using RoR2.Skills; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("SparkleLoaderTweaks")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("SparkleLoaderTweaks")] [assembly: AssemblyTitle("SparkleLoaderTweaks")] [assembly: AssemblyVersion("1.0.0.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 SparkleLoaderTweaks { internal static class LoaderSecondaryStock { internal const string HookToken = "LOADER_SECONDARY_NAME"; internal const string YankHookToken = "LOADER_YANKHOOK_NAME"; internal const int VanillaMaxStock = 1; private static ManualLogSource _log; private static ConfigEntry<bool> _enabled; private static ConfigEntry<bool> _hookEnabled; private static ConfigEntry<bool> _yankHookEnabled; private static ConfigEntry<int> _bonusStock; private static ConfigEntry<bool> _fillImmediately; private static bool _skillDefsDone; private static bool _skillDefFailedLogged; private static int _frameCount; private static bool _hookApplied; private static bool _yankHookApplied; private static int _hookBase = -1; private static int _yankHookBase = -1; private static int _bodiesRefreshed; private static bool _bodiesFailedLogged; private static readonly Dictionary<int, byte> _handled = new Dictionary<int, byte>(); private static bool Enabled { get { if (_enabled != null) { return _enabled.Value; } return true; } } private static bool HookEnabled { get { if (_hookEnabled != null) { return _hookEnabled.Value; } return true; } } private static bool YankHookEnabled { get { if (_yankHookEnabled != null) { return _yankHookEnabled.Value; } return true; } } private static bool FillImmediately { get { if (_fillImmediately != null) { return _fillImmediately.Value; } return true; } } internal static void Init(ConfigFile config, ManualLogSource log) { _log = log; _enabled = config.Bind<bool>("次要技能.M2充能", "Enabled", true, "是否让装卸工的两个 M2「格斗拳」「刺拳」都能多攒充能层数。"); _hookEnabled = config.Bind<bool>("次要技能.M2充能", "ApplyToHook", true, "是否作用于默认 M2「格斗拳」(LOADER_SECONDARY_NAME)。"); _yankHookEnabled = config.Bind<bool>("次要技能.M2充能", "ApplyToYankHook", true, "是否作用于替代 M2「刺拳」(LOADER_YANKHOOK_NAME)。"); _bonusStock = config.Bind<int>("次要技能.M2充能", "BonusStock", 1, "额外充能层数:1 = 由原版的 1 层变成 2 层;2 = 3 层;0 = 原版。"); _fillImmediately = config.Bind<bool>("次要技能.M2充能", "FillImmediately", true, "改动生效的那一刻是否直接把充能补满(否则要等一个冷却周期才回满)。"); } internal static string Summary() { if (!Enabled) { return " [M2充能:原版]"; } string text = " [M2充能:"; string text2 = ""; if (HookEnabled) { text2 += "格斗拳"; } if (YankHookEnabled) { if (text2.Length > 0) { text2 += "/"; } text2 += "刺拳"; } if (text2.Length == 0) { return " [M2充能:未启用任何技能]"; } return text + text2 + " " + 1 + "→" + TargetStock(_hookBase) + "层]"; } private static int BonusStock() { if (_bonusStock == null) { return 1; } return Math.Max(0, _bonusStock.Value); } private static int TargetStock(int baseStock) { int num = ((baseStock <= 0) ? 1 : baseStock); return Math.Max(1, num + BonusStock()); } internal static void Tick() { if (!Enabled) { return; } if (!_skillDefsDone) { ApplySkillDefs(); } if (_skillDefsDone) { _frameCount++; if (_frameCount % 10 == 0) { RefreshLoaderBodies(); } } } private static void ApplySkillDefs() { try { if (!((ResourceAvailability)(ref SkillCatalog.skillsDefined)).available) { return; } IEnumerable<SkillDef> allSkillDefs = SkillCatalog.allSkillDefs; if (allSkillDefs == null) { return; } foreach (SkillDef item in allSkillDefs) { if ((Object)(object)item == (Object)null || string.IsNullOrEmpty(item.skillNameToken)) { continue; } bool flag = string.Equals(item.skillNameToken, "LOADER_SECONDARY_NAME", StringComparison.Ordinal); bool flag2 = string.Equals(item.skillNameToken, "LOADER_YANKHOOK_NAME", StringComparison.Ordinal); if (!flag && !flag2) { continue; } if (flag) { if (_hookBase < 0) { _hookBase = item.baseMaxStock; } if (HookEnabled && (!_hookApplied || item.baseMaxStock != TargetStock(_hookBase))) { ApplyOne(item, _hookBase, ref _hookApplied, "默认 M2「格斗拳」"); } } else { if (_yankHookBase < 0) { _yankHookBase = item.baseMaxStock; } if (YankHookEnabled && (!_yankHookApplied || item.baseMaxStock != TargetStock(_yankHookBase))) { ApplyOne(item, _yankHookBase, ref _yankHookApplied, "替代 M2「刺拳」"); } } } bool flag3 = true; if (HookEnabled && !_hookApplied) { flag3 = false; } if (YankHookEnabled && !_yankHookApplied) { flag3 = false; } if (flag3) { _skillDefsDone = true; } } catch (Exception ex) { if (!_skillDefFailedLogged) { _skillDefFailedLogged = true; Log((LogLevel)4, "装卸工 M2 充能:改 SkillDef 时异常(下一帧会重试)—— " + ex.GetType().Name + " " + ex.Message); } } } private static void ApplyOne(SkillDef def, int baseStock, ref bool applied, string label) { int num = TargetStock(baseStock); if (def.baseMaxStock == num) { applied = true; return; } int baseMaxStock = def.baseMaxStock; def.baseMaxStock = num; applied = true; Log((LogLevel)16, label + " 充能上限已改:" + baseMaxStock + " 层 → " + num + " 层(SkillDef " + def.skillName + ",冷却 " + def.baseRechargeInterval.ToString("0.##") + " 秒;原版 " + 1 + " 层)。"); } private static void RefreshLoaderBodies() { try { ReadOnlyCollection<CharacterBody> readOnlyInstancesList = CharacterBody.readOnlyInstancesList; if (readOnlyInstancesList == null) { return; } for (int i = 0; i < readOnlyInstancesList.Count; i++) { CharacterBody val = readOnlyInstancesList[i]; if ((Object)(object)val == (Object)null || (Object)(object)val.skillLocator == (Object)null) { continue; } GenericSkill secondary = val.skillLocator.secondary; if ((Object)(object)secondary == (Object)null || (Object)(object)secondary.skillDef == (Object)null) { continue; } string skillNameToken = secondary.skillDef.skillNameToken; bool flag = string.Equals(skillNameToken, "LOADER_SECONDARY_NAME", StringComparison.Ordinal); bool flag2 = string.Equals(skillNameToken, "LOADER_YANKHOOK_NAME", StringComparison.Ordinal); if ((!flag && !flag2) || (flag && !HookEnabled) || (flag2 && !YankHookEnabled)) { continue; } int instanceID = ((Object)secondary).GetInstanceID(); if (!_handled.ContainsKey(instanceID)) { _handled[instanceID] = 1; if (_handled.Count > 512) { _handled.Clear(); _handled[instanceID] = 1; } int num = TargetStock(flag ? _hookBase : _yankHookBase); secondary.RecalculateValues(); if (FillImmediately && secondary.stock < secondary.maxStock) { secondary.stock = Math.Min(secondary.maxStock, Mathf.Max(secondary.stock, num)); secondary.rechargeStopwatch = 0f; } _bodiesRefreshed++; if (_bodiesRefreshed == 1) { Log((LogLevel)16, "装卸工已按新层数重算 M2 数值:目标 " + num + " 层,当前 " + secondary.stock + "/" + secondary.maxStock + "(技能 " + secondary.skillDef.skillName + ")。"); } } } } catch (Exception ex) { if (!_bodiesFailedLogged) { _bodiesFailedLogged = true; Log((LogLevel)4, "装卸工 M2 充能:刷新场上角色时异常(已忽略)—— " + ex.GetType().Name + " " + ex.Message); } } } private static void Log(LogLevel level, string message) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) if (_log != null) { _log.Log(level, (object)message); } } } internal static class LoaderThunderGauntlet { private const float VanillaKnockback = 7000f; private static ManualLogSource _log; private static ConfigEntry<bool> _enabled; private static ConfigEntry<float> _multiplier; private static readonly FieldInfo _knockbackField = AccessTools.Field(typeof(SwingZapFist), "selfKnockback"); private static float _base = -1f; private static float _lastWritten = float.MinValue; private static bool _baseLogged; private static bool _appliedLogged; private static bool _failedLogged; private static bool Enabled { get { if (_enabled != null) { return _enabled.Value; } return true; } } internal static void Init(ConfigFile config, ManualLogSource log) { _log = log; _enabled = config.Bind<bool>("辅助技能.雷电铁手套", "NoSelfKnockback", true, "替代 Shift「雷电铁手套」命中敌人后是否不再把自己弹开(原版会反向把自己推开)。"); _multiplier = config.Bind<float>("辅助技能.雷电铁手套", "SelfKnockbackMultiplier", 0f, "自身击退力度倍率:0 = 完全不弹开;1 = 原版(7000);0.5 = 只有原版一半。 NoSelfKnockback 为 false 时这项不生效。"); } internal static string Summary() { if (!Enabled) { return " [雷电铁手套:自身击退原样]"; } float num = ((_base > 0f) ? _base : 7000f); float num2 = num * Multiplier(); return " [雷电铁手套:自身击退 " + num.ToString("0") + " → " + num2.ToString("0") + "]"; } private static float Multiplier() { if (_multiplier == null) { return 0f; } return Math.Max(0f, _multiplier.Value); } internal static void Tick() { if (!Enabled) { return; } try { if (_knockbackField == null) { if (!_failedLogged) { _failedLogged = true; Log((LogLevel)2, "雷电铁手套:取不到 SwingZapFist.selfKnockback 字段,改动不生效。"); } return; } float num = (float)_knockbackField.GetValue(null); if (num <= 0f) { return; } if (Math.Abs(num - _lastWritten) > 0.001f) { _base = num; if (!_baseLogged) { _baseLogged = true; Log((LogLevel)16, "雷电铁手套原版自身击退力 = " + num.ToString("0.##") + "(原版 7000;若不是说明游戏改过数值,倍率仍按百分比生效)。"); } } float num2 = _base * Multiplier(); if (!(Math.Abs(num - num2) <= 0.001f)) { _knockbackField.SetValue(null, num2); _lastWritten = num2; if (!_appliedLogged) { _appliedLogged = true; Log((LogLevel)16, "雷电铁手套自身击退已改为 " + _base.ToString("0.##") + " → " + num2.ToString("0.##") + "(命中后不再把自己弹开;SwingZapFist.selfKnockback)。"); } } } catch (Exception ex) { if (!_failedLogged) { _failedLogged = true; Log((LogLevel)4, "雷电铁手套:改 selfKnockback 时异常(已忽略)—— " + ex.GetType().Name + " " + ex.Message); } } } private static void Log(LogLevel level, string message) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) if (_log != null) { _log.Log(level, (object)message); } } } [BepInPlugin("com.sparkletwilight.sparkleloadertweaks", "SparkleLoaderTweaks", "1.1.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class SparkleLoaderTweaksPlugin : BaseUnityPlugin { public const string PluginGUID = "com.sparkletwilight.sparkleloadertweaks"; public const string PluginName = "SparkleLoaderTweaks"; public const string PluginVersion = "1.1.0"; public void Awake() { LoaderSecondaryStock.Init(((BaseUnityPlugin)this).Config, ((BaseUnityPlugin)this).Logger); LoaderThunderGauntlet.Init(((BaseUnityPlugin)this).Config, ((BaseUnityPlugin)this).Logger); ((BaseUnityPlugin)this).Logger.LogInfo((object)("SparkleLoaderTweaks v1.1.0 已加载。" + LoaderSecondaryStock.Summary() + LoaderThunderGauntlet.Summary())); } public void Update() { LoaderSecondaryStock.Tick(); LoaderThunderGauntlet.Tick(); } } }