Decompiled source of SparkleLoaderTweaks v1.1.0

plugins/SparkleLoaderTweaks.dll

Decompiled a day ago
using 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();
		}
	}
}