Decompiled source of SparkleCaptainTweaks v1.3.0

plugins/SparkleCaptainTweaks.dll

Decompiled 19 hours 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;
using EntityStates.Captain.Weapon;
using EntityStates.CaptainSupplyDrop;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using R2API;
using RoR2;
using RoR2.Orbs;
using RoR2.Projectile;
using RoR2.Skills;
using UnityEngine;
using UnityEngine.Networking;

[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("SparkleCaptainTweaks")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.3.0.0")]
[assembly: AssemblyInformationalVersion("1.3.0")]
[assembly: AssemblyProduct("SparkleCaptainTweaks")]
[assembly: AssemblyTitle("SparkleCaptainTweaks")]
[assembly: AssemblyVersion("1.3.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 SparkleCaptainTweaks
{
	internal static class CaptainOrbitalProbe
	{
		private const string UtilityToken = "CAPTAIN_UTILITY_NAME";

		private const float VanillaDamageCoefficient = 10f;

		private const float VanillaCooldown = 11f;

		private static ManualLogSource _log;

		private static ConfigEntry<bool> _damageEnabled;

		private static ConfigEntry<float> _damagePercent;

		private static ConfigEntry<bool> _cooldownEnabled;

		private static ConfigEntry<float> _cooldown;

		private static readonly FieldInfo _damageField = AccessTools.Field(typeof(AimThrowableBase), "damageCoefficient");

		private static float _base = -1f;

		private static bool _damageAppliedLogged;

		private static int _damageAppliedCount;

		private static bool _cooldownDone;

		private static bool _cooldownFailedLogged;

		private static bool DamageEnabled
		{
			get
			{
				if (_damageEnabled != null)
				{
					return _damageEnabled.Value;
				}
				return true;
			}
		}

		private static bool CooldownEnabled
		{
			get
			{
				if (_cooldownEnabled != null)
				{
					return _cooldownEnabled.Value;
				}
				return true;
			}
		}

		internal static void Init(ConfigFile config, ManualLogSource log)
		{
			_log = log;
			_damageEnabled = config.Bind<bool>("Utility.轨道探测器", "DamageEnabled", true, "是否把 Shift「轨道探测器」的伤害从每台 1000% 提升到 2000%。");
			_damagePercent = config.Bind<float>("Utility.轨道探测器", "DamagePercent", 2000f, "每台轨道探测器的伤害百分比。2000 = 每台 2000% 伤害;1000 = 原版。");
			_cooldownEnabled = config.Bind<bool>("Utility.轨道探测器", "CooldownEnabled", true, "是否把 Shift「轨道探测器」的冷却时间从 11 秒提升到 20 秒。");
			_cooldown = config.Bind<float>("Utility.轨道探测器", "Cooldown", 20f, "Shift「轨道探测器」的冷却时间(秒)。20 = 20 秒;11 = 原版。");
		}

		internal static string Summary()
		{
			string text = " [Shift伤害:原版1000%]";
			string text2 = " [Shift冷却:原版11s]";
			if (DamageEnabled)
			{
				float num = ((_base > 0f) ? _base : 10f);
				text = " [Shift伤害:" + (num * 100f).ToString("0") + "% → " + DamagePercent().ToString("0") + "%]";
			}
			if (CooldownEnabled)
			{
				text2 = " [Shift冷却:11s → " + Cooldown().ToString("0.##") + "s]";
			}
			return text + text2;
		}

		private static float DamagePercent()
		{
			if (_damagePercent == null)
			{
				return 2000f;
			}
			return _damagePercent.Value;
		}

		private static float Cooldown()
		{
			if (_cooldown == null)
			{
				return 20f;
			}
			return Math.Max(0f, _cooldown.Value);
		}

		internal static void Patch(Harmony harmony)
		{
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Expected O, but got Unknown
			if (!DamageEnabled)
			{
				Log((LogLevel)16, "Shift 探测器伤害:按配置保持原版,不挂补丁。");
				return;
			}
			if (_damageField == null)
			{
				Log((LogLevel)2, "Shift 探测器伤害补丁失败:取不到 AimThrowableBase.damageCoefficient。");
				return;
			}
			MethodInfo methodInfo = AccessTools.Method(typeof(AimThrowableBase), "FireProjectile", (Type[])null, (Type[])null);
			if (methodInfo == null)
			{
				Log((LogLevel)2, "Shift 探测器伤害补丁失败:取不到 AimThrowableBase.FireProjectile。");
				return;
			}
			harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(AccessTools.Method(typeof(CaptainOrbitalProbe), "FireProjectilePrefix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			Log((LogLevel)16, "补丁已挂载:EntityStates.AimThrowableBase.FireProjectile <- CaptainOrbitalProbe.FireProjectilePrefix(每台探测器伤害 → " + DamagePercent().ToString("0") + "%)");
		}

		internal static void Tick()
		{
			if (!CooldownEnabled || _cooldownDone)
			{
				return;
			}
			try
			{
				SkillDef val = FindUtilitySkillDef();
				if (!((Object)(object)val == (Object)null))
				{
					float baseRechargeInterval = val.baseRechargeInterval;
					float num = Cooldown();
					if (Math.Abs(baseRechargeInterval - num) < 0.001f)
					{
						_cooldownDone = true;
						return;
					}
					val.baseRechargeInterval = num;
					_cooldownDone = true;
					Log((LogLevel)16, "Shift「轨道探测器」冷却已改:" + baseRechargeInterval.ToString("0.##") + " 秒 → " + num.ToString("0.##") + " 秒(SkillDef: " + val.skillName + ",原版 " + 11f.ToString("0.##") + ")。");
					RefreshCaptainBodies();
				}
			}
			catch (Exception ex)
			{
				if (!_cooldownFailedLogged)
				{
					_cooldownFailedLogged = true;
					Log((LogLevel)4, "改 Shift 冷却时异常(下一帧会重试一次)—— " + ex.GetType().Name + " " + ex.Message);
				}
			}
		}

		private static SkillDef FindUtilitySkillDef()
		{
			IEnumerable<SkillDef> allSkillDefs = SkillCatalog.allSkillDefs;
			if (allSkillDefs == null)
			{
				return null;
			}
			SkillDef val = null;
			foreach (SkillDef item in allSkillDefs)
			{
				if (!((Object)(object)item == (Object)null) && string.Equals(item.skillNameToken, "CAPTAIN_UTILITY_NAME", StringComparison.Ordinal) && !(item.baseRechargeInterval <= 0.001f))
				{
					string text = StateTypeName(item);
					if (!string.IsNullOrEmpty(text) && text.IndexOf("SetupAirstrike", StringComparison.Ordinal) >= 0)
					{
						return item;
					}
					if ((Object)(object)val == (Object)null || item.baseRechargeInterval > val.baseRechargeInterval)
					{
						val = item;
					}
				}
			}
			return val;
		}

		private static string StateTypeName(SkillDef def)
		{
			try
			{
				string typeName = ((SerializableEntityStateType)(ref def.activationState)).typeName;
				if (!string.IsNullOrEmpty(typeName))
				{
					return typeName;
				}
				Type stateType = ((SerializableEntityStateType)(ref def.activationState)).stateType;
				return (stateType != null) ? stateType.FullName : null;
			}
			catch (Exception)
			{
				return null;
			}
		}

		private static void RefreshCaptainBodies()
		{
			try
			{
				ReadOnlyCollection<CharacterBody> readOnlyInstancesList = CharacterBody.readOnlyInstancesList;
				if (readOnlyInstancesList == null)
				{
					return;
				}
				int num = 0;
				foreach (CharacterBody item in readOnlyInstancesList)
				{
					if (!((Object)(object)item == (Object)null) && !((Object)(object)item.skillLocator == (Object)null) && ((Object)item).name != null && ((Object)item).name.IndexOf("CaptainBody", StringComparison.Ordinal) >= 0)
					{
						GenericSkill utility = item.skillLocator.utility;
						if (!((Object)(object)utility == (Object)null))
						{
							utility.RecalculateValues();
							num++;
						}
					}
				}
				if (num > 0)
				{
					Log((LogLevel)16, "已让场上 " + num + " 个船长按新冷却重算技能数值。");
				}
			}
			catch (Exception ex)
			{
				Log((LogLevel)4, "刷新船长技能数值时异常(已忽略)—— " + ex.GetType().Name + " " + ex.Message);
			}
		}

		public static void FireProjectilePrefix(AimThrowableBase __instance)
		{
			try
			{
				if (DamageEnabled && __instance != null && !(_damageField == null) && (__instance is CallAirstrike1 || __instance is CallAirstrike2 || __instance is CallAirstrike3))
				{
					if (_base < 0f)
					{
						_base = (float)_damageField.GetValue(__instance);
						Log((LogLevel)16, "Shift「轨道探测器」原版伤害系数 = " + _base.ToString("0.###") + "(原版 10 = 1000%;若不是 10 说明游戏改过数值,百分比仍按百分比生效)。");
					}
					float num = DamagePercent() / 100f;
					_damageField.SetValue(__instance, num);
					_damageAppliedCount++;
					if (!_damageAppliedLogged)
					{
						_damageAppliedLogged = true;
						Log((LogLevel)16, "Shift「轨道探测器」伤害已生效:" + (_base * 100f).ToString("0") + "% → " + (num * 100f).ToString("0") + "% 每台(" + ((object)__instance).GetType().Name + ")。");
					}
					else if (_damageAppliedCount % 20 == 0)
					{
						Log((LogLevel)16, "Shift「轨道探测器」伤害已应用 " + _damageAppliedCount + " 次,当前每台 " + (num * 100f).ToString("0") + "%。");
					}
				}
			}
			catch (Exception ex)
			{
				Log((LogLevel)4, "Shift 探测器:改写伤害系数时异常(已忽略)—— " + 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 CaptainShotgunCharge
	{
		private const float VanillaBaseChargeDuration = 1.2f;

		private static ManualLogSource _log;

		private static ConfigEntry<bool> _enabled;

		private static ConfigEntry<float> _multiplier;

		private static ConfigEntry<float> _minMultiplier;

		private static readonly FieldInfo _baseChargeDurationField = AccessTools.Field(typeof(ChargeCaptainShotgun), "baseChargeDuration");

		private static readonly FieldInfo _minBaseChargeDurationField = AccessTools.Field(typeof(ChargeCaptainShotgun), "baseMinChargeDuration");

		private static readonly FieldInfo _chargeDurationField = AccessTools.Field(typeof(ChargeCaptainShotgun), "chargeDuration");

		private static readonly FieldInfo _minChargeDurationField = AccessTools.Field(typeof(ChargeCaptainShotgun), "minChargeDuration");

		private static readonly FieldInfo _attackSpeedField = AccessTools.Field(typeof(ChargeCaptainShotgun), "attackSpeedStat");

		private static float _baseCharge = -1f;

		private static float _baseMinCharge = -1f;

		private static bool _missingFieldLogged;

		private static bool _appliedLogged;

		private static int _appliedCount;

		private static bool IsEnabled
		{
			get
			{
				if (_enabled != null)
				{
					return _enabled.Value;
				}
				return true;
			}
		}

		internal static void Init(ConfigFile config, ManualLogSource log)
		{
			_log = log;
			_enabled = config.Bind<bool>("Primary.火神霰弹枪", "Enabled", true, "是否缩短 M1「火神霰弹枪」的蓄力时间(1.2 秒 → 0.6 秒)。\n基础攻击间隔(开火动作的时长,原版 0.9 秒)不受影响。");
			_multiplier = config.Bind<float>("Primary.火神霰弹枪", "ChargeDurationMultiplier", 0.5f, "蓄力时间倍率。0.5 = 原版 1.2 秒变成 0.6 秒;1 = 原版。\n原版基准值是从游戏里读出来的(正常是 1.2),改这个值即可自由调整。");
			_minMultiplier = config.Bind<float>("Primary.火神霰弹枪", "MinChargeDurationMultiplier", 1f, "最短蓄力时间的倍率(原版 0.1 秒)。默认 1 = 保持原版,一般不用动。");
		}

		internal static string Summary()
		{
			if (!IsEnabled)
			{
				return " [M1蓄力:原版未改动]";
			}
			float num = ((_baseCharge > 0f) ? _baseCharge : 1.2f);
			float num2 = num * Multiplier();
			return " [M1蓄力:" + num.ToString("0.##") + "s → " + num2.ToString("0.##") + "s(攻击间隔不变)]";
		}

		private static float Multiplier()
		{
			if (_multiplier == null)
			{
				return 0.5f;
			}
			return _multiplier.Value;
		}

		private static float MinMultiplier()
		{
			if (_minMultiplier == null)
			{
				return 1f;
			}
			return _minMultiplier.Value;
		}

		internal static void Patch(Harmony harmony)
		{
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Expected O, but got Unknown
			//IL_00a6: Expected O, but got Unknown
			if (!IsEnabled)
			{
				Log((LogLevel)16, "M1 蓄力:按配置保持原版,不挂任何补丁。");
				return;
			}
			if (_baseChargeDurationField == null || _chargeDurationField == null)
			{
				Log((LogLevel)2, "M1 蓄力补丁失败:取不到 ChargeCaptainShotgun 的 baseChargeDuration / chargeDuration 字段,蓄力时间不会变。");
				return;
			}
			MethodInfo methodInfo = AccessTools.Method(typeof(ChargeCaptainShotgun), "OnEnter", (Type[])null, (Type[])null);
			if (methodInfo == null)
			{
				Log((LogLevel)2, "M1 蓄力补丁失败:取不到 ChargeCaptainShotgun.OnEnter。");
				return;
			}
			harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(AccessTools.Method(typeof(CaptainShotgunCharge), "OnEnterPrefix", (Type[])null, (Type[])null)), new HarmonyMethod(AccessTools.Method(typeof(CaptainShotgunCharge), "OnEnterPostfix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			Log((LogLevel)16, "补丁已挂载:EntityStates.Captain.Weapon.ChargeCaptainShotgun.OnEnter <- CaptainShotgunCharge(M1 蓄力时间 ×" + Multiplier().ToString("0.##") + ")");
		}

		public static void OnEnterPrefix()
		{
			try
			{
				if (IsEnabled && !(_baseChargeDurationField == null))
				{
					if (_baseCharge < 0f)
					{
						_baseCharge = (float)_baseChargeDurationField.GetValue(null);
						Log((LogLevel)16, "M1「火神霰弹枪」原版基础蓄力时间 = " + _baseCharge.ToString("0.###") + " 秒(原版 1.2;若不是 1.2 说明游戏改过数值,倍率仍按倍率生效)。");
					}
					if (_minBaseChargeDurationField != null && _baseMinCharge < 0f)
					{
						_baseMinCharge = (float)_minBaseChargeDurationField.GetValue(null);
					}
					float num = _baseCharge * Multiplier();
					_baseChargeDurationField.SetValue(null, num);
					if (_minBaseChargeDurationField != null && _baseMinCharge > 0f)
					{
						_minBaseChargeDurationField.SetValue(null, _baseMinCharge * MinMultiplier());
					}
				}
			}
			catch (Exception ex)
			{
				Log((LogLevel)4, "M1 蓄力:改写基础蓄力时间时异常(已忽略)—— " + ex.GetType().Name + " " + ex.Message);
			}
		}

		public static void OnEnterPostfix(ChargeCaptainShotgun __instance)
		{
			try
			{
				if (!IsEnabled || __instance == null || _chargeDurationField == null || _baseCharge <= 0f)
				{
					return;
				}
				if (_attackSpeedField == null)
				{
					if (!_missingFieldLogged)
					{
						_missingFieldLogged = true;
						Log((LogLevel)4, "M1 蓄力:取不到 BaseState.attackSpeedStat,只靠静态基准值那道保险(一般也够用)。");
					}
					return;
				}
				float num = 1f;
				object value = _attackSpeedField.GetValue(__instance);
				if (value is float)
				{
					num = (float)value;
				}
				if (num <= 0f)
				{
					num = 1f;
				}
				float num2 = _baseCharge * Multiplier() / num;
				float num3 = (float)_chargeDurationField.GetValue(__instance);
				if (Math.Abs(num3 - num2) > 0.001f)
				{
					_chargeDurationField.SetValue(__instance, num2);
				}
				if (_minChargeDurationField != null && _baseMinCharge > 0f)
				{
					float num4 = _baseMinCharge * MinMultiplier() / num;
					if (Math.Abs((float)_minChargeDurationField.GetValue(__instance) - num4) > 0.001f)
					{
						_minChargeDurationField.SetValue(__instance, num4);
					}
				}
				_appliedCount++;
				if (!_appliedLogged)
				{
					_appliedLogged = true;
					Log((LogLevel)16, "M1「火神霰弹枪」蓄力时间已生效:本次 " + num3.ToString("0.###") + " 秒 → " + num2.ToString("0.###") + " 秒(攻速 " + num.ToString("0.##") + ",基础值 " + _baseCharge.ToString("0.###") + " × " + Multiplier().ToString("0.##") + ",攻击间隔不动)。");
				}
				else if (_appliedCount % 40 == 0)
				{
					Log((LogLevel)16, "M1「火神霰弹枪」蓄力时间已应用 " + _appliedCount + " 次,最近一次 = " + num2.ToString("0.###") + " 秒。");
				}
			}
			catch (Exception ex)
			{
				Log((LogLevel)4, "M1 蓄力:核对蓄力时长时异常(已忽略)—— " + 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 CaptainSkillText
	{
		private const string SecondaryDescriptionToken = "CAPTAIN_SECONDARY_DESCRIPTION";

		private const string UtilityDescriptionToken = "CAPTAIN_UTILITY_DESCRIPTION";

		private const string SupplyRestockDescriptionToken = "CAPTAIN_SUPPLY_EQUIPMENT_RESTOCK_DESCRIPTION";

		private const string ZhSecondaryDescription = "<style=cIsDamage>震荡</style>。连续发射<style=cIsDamage>两枚</style>造成<style=cIsDamage>280%伤害</style>的快速电镖。命中时会连锁至多<style=cIsDamage>3</style>个敌人,每个造成<style=cIsDamage>80%</style>的伤害。如果弹射将能飞行到更远地点。";

		private const string EnSecondaryDescription = "<style=cIsDamage>Shocking</style>. Fire <style=cIsDamage>two</style> fast tazers, each dealing <style=cIsDamage>280% damage</style>. Chains to up to <style=cIsDamage>3</style> enemies for <style=cIsDamage>80%</style> damage each. Travels farther if bounced.";

		private const string ZhUtilityDescription = "<style=cIsDamage>眩晕</style>。向<style=cIsDamage>尤伊思顺风号</style>请求至多<style=cIsDamage>3台</style>轨道探测器。每台探测器将造成<style=cIsDamage>2000%伤害</style>。<style=cIsUtility>冷却20秒</style>。";

		private const string EnUtilityDescription = "<style=cIsDamage>Stunning</style>. Request up to <style=cIsDamage>3</style> Orbital Probes from the <style=cIsDamage>UES Safe Travels</style>. Each probe deals <style=cIsDamage>2000% damage</style>. <style=cIsUtility>20 second cooldown</style>.";

		private const string ZhSupplyRestockDescription = "使用时<style=cIsUtility>为装备充能</style>,并为<style=cIsUtility>每个技能补充一层</style>。";

		private const string EnSupplyRestockDescription = "<style=cIsUtility>Recharge Equipment</style> on use. Also restores <style=cIsUtility>one charge to every skill</style>.";

		private static ManualLogSource _log;

		private static ConfigEntry<bool> _enabled;

		private static string _appliedLanguage;

		internal static bool IsEnabled
		{
			get
			{
				if (_enabled != null)
				{
					return _enabled.Value;
				}
				return true;
			}
		}

		internal static void Init(ConfigFile config, ManualLogSource log)
		{
			_log = log;
			_enabled = config.Bind<bool>("SkillText", "Enabled", true, "是否把技能描述改成和模组效果一致的说法(M2「连发两枚 + 闪电链 + 280%」、Shift「每台 2000% + 冷却 20 秒」)。");
		}

		internal static void Tick()
		{
			if (!IsEnabled)
			{
				return;
			}
			try
			{
				string text = CurrentLanguage();
				if (!string.IsNullOrEmpty(text) && !string.Equals(_appliedLanguage, text, StringComparison.Ordinal))
				{
					_appliedLanguage = text;
					LanguageAPI.Add("CAPTAIN_SECONDARY_DESCRIPTION", "<style=cIsDamage>Shocking</style>. Fire <style=cIsDamage>two</style> fast tazers, each dealing <style=cIsDamage>280% damage</style>. Chains to up to <style=cIsDamage>3</style> enemies for <style=cIsDamage>80%</style> damage each. Travels farther if bounced.", "en");
					LanguageAPI.Add("CAPTAIN_SECONDARY_DESCRIPTION", "<style=cIsDamage>震荡</style>。连续发射<style=cIsDamage>两枚</style>造成<style=cIsDamage>280%伤害</style>的快速电镖。命中时会连锁至多<style=cIsDamage>3</style>个敌人,每个造成<style=cIsDamage>80%</style>的伤害。如果弹射将能飞行到更远地点。", "zh-CN");
					LanguageAPI.Add("CAPTAIN_UTILITY_DESCRIPTION", "<style=cIsDamage>Stunning</style>. Request up to <style=cIsDamage>3</style> Orbital Probes from the <style=cIsDamage>UES Safe Travels</style>. Each probe deals <style=cIsDamage>2000% damage</style>. <style=cIsUtility>20 second cooldown</style>.", "en");
					LanguageAPI.Add("CAPTAIN_UTILITY_DESCRIPTION", "<style=cIsDamage>眩晕</style>。向<style=cIsDamage>尤伊思顺风号</style>请求至多<style=cIsDamage>3台</style>轨道探测器。每台探测器将造成<style=cIsDamage>2000%伤害</style>。<style=cIsUtility>冷却20秒</style>。", "zh-CN");
					LanguageAPI.Add("CAPTAIN_SUPPLY_EQUIPMENT_RESTOCK_DESCRIPTION", "<style=cIsUtility>Recharge Equipment</style> on use. Also restores <style=cIsUtility>one charge to every skill</style>.", "en");
					LanguageAPI.Add("CAPTAIN_SUPPLY_EQUIPMENT_RESTOCK_DESCRIPTION", "使用时<style=cIsUtility>为装备充能</style>,并为<style=cIsUtility>每个技能补充一层</style>。", "zh-CN");
					Log((LogLevel)16, "技能描述已覆盖(当前语言 " + text + "):CAPTAIN_SECONDARY_DESCRIPTION + CAPTAIN_UTILITY_DESCRIPTION + CAPTAIN_SUPPLY_EQUIPMENT_RESTOCK_DESCRIPTION");
					CheckApplied(text, "CAPTAIN_SECONDARY_DESCRIPTION", "280%", "280%");
					CheckApplied(text, "CAPTAIN_UTILITY_DESCRIPTION", "2000%", "2000%");
					CheckApplied(text, "CAPTAIN_SUPPLY_EQUIPMENT_RESTOCK_DESCRIPTION", "补充一层", "one charge to every skill");
				}
			}
			catch (Exception ex)
			{
				Log((LogLevel)4, "改写技能描述时异常(已忽略)—— " + ex.GetType().Name + " " + ex.Message);
			}
		}

		private static void CheckApplied(string language, string token, string expectedZh, string expectedEn)
		{
			try
			{
				string text = Language.GetString(token);
				if (!string.IsNullOrEmpty(text) && text.IndexOf(expectedZh, StringComparison.Ordinal) < 0 && text.IndexOf(expectedEn, StringComparison.Ordinal) < 0)
				{
					Log((LogLevel)4, token + " 回读不一致(语言 " + language + "),实际生效的是:" + text);
				}
			}
			catch (Exception)
			{
			}
		}

		private static string CurrentLanguage()
		{
			try
			{
				string currentLanguageName = Language.currentLanguageName;
				if (!string.IsNullOrEmpty(currentLanguageName))
				{
					return currentLanguageName;
				}
				Language currentLanguage = Language.currentLanguage;
				if (currentLanguage != null && !string.IsNullOrEmpty(currentLanguage.selfName))
				{
					return currentLanguage.selfName;
				}
			}
			catch (Exception)
			{
			}
			return null;
		}

		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 CaptainSupplyRestockSkills
	{
		private static ManualLogSource _log;

		private static ConfigEntry<bool> _enabled;

		private static ConfigEntry<bool> _addOneStockOnly;

		private static ConfigEntry<bool> _includeSpecial;

		private static ConfigEntry<bool> _alwaysInteractable;

		private static ConfigEntry<bool> _ignoreEnergy;

		private static bool _appliedLogged;

		private static int _appliedCount;

		private static bool _interactLogged;

		private static readonly FieldInfo _energyComponentField = AccessTools.Field(typeof(BaseCaptainSupplyDropState), "energyComponent");

		private static readonly FieldInfo _activationCostField = AccessTools.Field(typeof(EquipmentRestockMainState), "activationCost");

		private static PropertyInfo _energyProperty;

		private static bool IsEnabled
		{
			get
			{
				if (_enabled != null)
				{
					return _enabled.Value;
				}
				return true;
			}
		}

		internal static void Init(ConfigFile config, ManualLogSource log)
		{
			_log = log;
			_enabled = config.Bind<bool>("Special.信标补给", "RestockSkillsEnabled", true, "是否让 R「信标:补给」在给装备充能的同时,也把所有技能的冷却补满。");
			_addOneStockOnly = config.Bind<bool>("Special.信标补给", "AddOneStockOnly", true, "补技能冷却的方式:true = 每个技能只补一层(默认,已满的技能不动);false = 直接把每个技能的层数和冷却恢复到满。");
			_includeSpecial = config.Bind<bool>("Special.信标补给", "IncludeSpecial", true, "是否连 R(补给信标本身)一起补。它本来就没有冷却、永远是满的,勾不勾都一样。");
			_alwaysInteractable = config.Bind<bool>("Special.信标补给", "AlwaysInteractable", true, "是否让补给信标随时都能交互。false = 原版条件(必须持有主动装备、且装备有待补的充能)。");
			_ignoreEnergy = config.Bind<bool>("Special.信标补给", "IgnoreEnergyRequirement", false, "连信标自身能量不足时也强行允许交互(true = 完全无条件,能量空了也能按)。默认 false:至少信标自己还有能量才让按。");
		}

		internal static string Summary()
		{
			string text = (AlwaysInteractable() ? " [信标:随时可交互]" : " [信标:原版交互条件]");
			if (!IsEnabled)
			{
				return text + " [信标补给:只充装备]";
			}
			return text + " [信标补给:装备 + 全部技能冷却" + (AddOneStockOnly() ? "(每层+1)" : "(补满)") + "]";
		}

		private static bool AddOneStockOnly()
		{
			if (_addOneStockOnly != null)
			{
				return _addOneStockOnly.Value;
			}
			return false;
		}

		private static bool IncludeSpecial()
		{
			if (_includeSpecial != null)
			{
				return _includeSpecial.Value;
			}
			return true;
		}

		private static bool AlwaysInteractable()
		{
			if (_alwaysInteractable != null)
			{
				return _alwaysInteractable.Value;
			}
			return true;
		}

		private static bool IgnoreEnergy()
		{
			if (_ignoreEnergy != null)
			{
				return _ignoreEnergy.Value;
			}
			return false;
		}

		internal static void Patch(Harmony harmony)
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			PatchInteractability(harmony);
			if (!IsEnabled)
			{
				Log((LogLevel)16, "信标补给:按配置只给装备充能,不补技能冷却。");
				return;
			}
			MethodInfo methodInfo = AccessTools.Method(typeof(EquipmentRestockMainState), "OnInteractionBegin", (Type[])null, (Type[])null);
			if (methodInfo == null)
			{
				Log((LogLevel)2, "信标补给补丁失败:取不到 EntityStates.CaptainSupplyDrop.EquipmentRestockMainState.OnInteractionBegin。");
				return;
			}
			harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(CaptainSupplyRestockSkills), "OnInteractionBeginPostfix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			Log((LogLevel)16, "补丁已挂载:EntityStates.CaptainSupplyDrop.EquipmentRestockMainState.OnInteractionBegin <- CaptainSupplyRestockSkills.OnInteractionBeginPostfix(信标补给顺手补满技能冷却)");
		}

		private static void PatchInteractability(Harmony harmony)
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Expected O, but got Unknown
			if (!AlwaysInteractable())
			{
				Log((LogLevel)16, "信标补给:按配置保持原版交互条件(要持有待充能的主动装备)。");
				return;
			}
			MethodInfo methodInfo = AccessTools.Method(typeof(EquipmentRestockMainState), "GetInteractability", (Type[])null, (Type[])null);
			if (methodInfo == null)
			{
				Log((LogLevel)2, "信标补给交互补丁失败:取不到 EquipmentRestockMainState.GetInteractability。");
				return;
			}
			harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(CaptainSupplyRestockSkills), "GetInteractabilityPostfix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			Log((LogLevel)16, "补丁已挂载:EntityStates.CaptainSupplyDrop.EquipmentRestockMainState.GetInteractability <- CaptainSupplyRestockSkills.GetInteractabilityPostfix(补给信标不再要求「有主动装备且它在冷却」" + (IgnoreEnergy() ? ",连能量也不卡" : ",但信标自身仍要有能量") + ")");
		}

		public static void GetInteractabilityPostfix(EquipmentRestockMainState __instance, ref Interactability __result)
		{
			try
			{
				if (AlwaysInteractable() && __instance != null && (int)__result == 1 && (IgnoreEnergy() || HasEnoughEnergy(__instance)))
				{
					__result = (Interactability)2;
					if (!_interactLogged)
					{
						_interactLogged = true;
						Log((LogLevel)16, "补给信标交互条件已放宽:即使没有主动装备(或装备没在冷却)也能交互补技能。");
					}
				}
			}
			catch (Exception ex)
			{
				Log((LogLevel)4, "补给信标:放宽交互条件时异常(已忽略)—— " + ex.GetType().Name + " " + ex.Message);
			}
		}

		private static bool HasEnoughEnergy(EquipmentRestockMainState instance)
		{
			if (_energyComponentField == null)
			{
				return true;
			}
			object value = _energyComponentField.GetValue(instance);
			if (value == null)
			{
				return true;
			}
			if (_energyProperty == null)
			{
				_energyProperty = AccessTools.Property(value.GetType(), "energy");
			}
			if (_energyProperty == null)
			{
				return true;
			}
			object value2 = _energyProperty.GetValue(value, null);
			if (!(value2 is float))
			{
				return true;
			}
			float num = 0f;
			if (_activationCostField != null)
			{
				object value3 = _activationCostField.GetValue(instance);
				if (value3 is float)
				{
					num = (float)value3;
				}
			}
			return (float)value2 >= num;
		}

		public static void OnInteractionBeginPostfix(object[] __args)
		{
			try
			{
				if (!IsEnabled || __args == null || __args.Length == 0)
				{
					return;
				}
				CharacterBody val = FindBody(__args[0]);
				if ((Object)(object)val == (Object)null || (Object)(object)val.skillLocator == (Object)null)
				{
					return;
				}
				int num = RestockAllSkills(val.skillLocator);
				if (num > 0)
				{
					_appliedCount++;
					if (!_appliedLogged)
					{
						_appliedLogged = true;
						Log((LogLevel)16, "R「信标:补给」已给 " + val.GetDisplayName() + " 补了 " + num + " 个技能的冷却(" + (AddOneStockOnly() ? "每层 +1" : "补到满") + ")。");
					}
					else if (_appliedCount % 10 == 0)
					{
						Log((LogLevel)16, "R「信标:补给」补技能冷却已触发 " + _appliedCount + " 次。");
					}
				}
			}
			catch (Exception ex)
			{
				Log((LogLevel)4, "信标补给:补技能冷却时异常(已忽略)—— " + ex.GetType().Name + " " + ex.Message);
			}
		}

		private static CharacterBody FindBody(object raw)
		{
			Component val = (Component)((raw is Component) ? raw : null);
			if ((Object)(object)val == (Object)null)
			{
				GameObject val2 = (GameObject)((raw is GameObject) ? raw : null);
				if ((Object)(object)val2 != (Object)null)
				{
					val = (Component)(object)val2.transform;
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			return val.GetComponent<CharacterBody>();
		}

		private static int RestockAllSkills(SkillLocator locator)
		{
			int num = 0;
			num += RestockSkill(locator.primary);
			num += RestockSkill(locator.secondary);
			num += RestockSkill(locator.utility);
			if (IncludeSpecial())
			{
				num += RestockSkill(locator.special);
			}
			return num;
		}

		private static int RestockSkill(GenericSkill skill)
		{
			if ((Object)(object)skill == (Object)null)
			{
				return 0;
			}
			if (AddOneStockOnly())
			{
				if (skill.stock >= skill.maxStock)
				{
					return 0;
				}
				skill.AddOneStock();
				return 1;
			}
			int maxStock = skill.maxStock;
			if (maxStock <= 0)
			{
				return 0;
			}
			if (skill.stock >= maxStock)
			{
				return 0;
			}
			skill.stock = maxStock;
			skill.rechargeStopwatch = 0f;
			return 1;
		}

		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 CaptainTazerBurst
	{
		internal const string TazerProjectileName = "CaptainTazer";

		private static ManualLogSource _log;

		private static ConfigEntry<bool> _enabled;

		private static ConfigEntry<float> _secondShotDelay;

		private static readonly FieldInfo _hasFiredField = AccessTools.Field(typeof(FireTazer), "hasFired");

		private static readonly FieldInfo _delayField = AccessTools.Field(typeof(FireTazer), "delay");

		private static readonly FieldInfo _durationField = AccessTools.Field(typeof(FireTazer), "duration");

		private static readonly FieldInfo _projectilePrefabField = AccessTools.Field(typeof(FireTazer), "projectilePrefab");

		private static readonly ConditionalWeakTable<FireTazer, StrongBox<int>> _fireCounts = new ConditionalWeakTable<FireTazer, StrongBox<int>>();

		private static readonly ConditionalWeakTable<FireTazer, StrongBox<int>>.CreateValueCallback _makeCount = MakeCount;

		private static GameObject _tazerPrefab;

		private static int _scheduledCount;

		private static bool _missingFieldLogged;

		private static bool _prefabLogged;

		internal static GameObject TazerPrefab => _tazerPrefab;

		internal static bool IsEnabled
		{
			get
			{
				if (_enabled != null)
				{
					return _enabled.Value;
				}
				return true;
			}
		}

		private static StrongBox<int> MakeCount(FireTazer state)
		{
			return new StrongBox<int>(0);
		}

		internal static void Init(ConfigFile config, ManualLogSource log)
		{
			_log = log;
			_enabled = config.Bind<bool>("Secondary.能量电镖", "Enabled", true, "是否让 M2「能量电镖」一次技能连续射出两枚射弹。");
			_secondShotDelay = config.Bind<float>("Secondary.能量电镖", "SecondShotDelay", 0.1f, "第二枚射弹相对第一枚的延迟(秒)。0.1 = 连发间隔 0.1 秒;0 = 几乎同时射出。");
		}

		internal static string Summary()
		{
			if (!IsEnabled)
			{
				return " [M2电镖:原版单发]";
			}
			return " [M2电镖:连发 2 枚,间隔 " + SecondShotDelay().ToString("0.##") + "s]";
		}

		private static float SecondShotDelay()
		{
			if (_secondShotDelay == null)
			{
				return 0.1f;
			}
			return Math.Max(0f, _secondShotDelay.Value);
		}

		internal static void Patch(Harmony harmony)
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Expected O, but got Unknown
			MethodInfo methodInfo = AccessTools.Method(typeof(FireTazer), "Fire", (Type[])null, (Type[])null);
			if (methodInfo == null)
			{
				Log((LogLevel)2, "M2 电镖补丁失败:取不到 EntityStates.Captain.Weapon.FireTazer.Fire,连发和闪电链都不会生效。");
				return;
			}
			try
			{
				harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(CaptainTazerBurst), "FirePostfix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				Log((LogLevel)16, "补丁已挂载:EntityStates.Captain.Weapon.FireTazer.Fire <- CaptainTazerBurst.FirePostfix(记住电镖 prefab + 排入第二枚)");
			}
			catch (Exception ex)
			{
				Log((LogLevel)2, "M2 电镖补丁失败(FireTazer.Fire 没挂上,连发和闪电链都会失效)—— " + ex.GetType().Name + " " + ex.Message);
			}
		}

		public static void FirePostfix(FireTazer __instance)
		{
			try
			{
				if (__instance == null)
				{
					return;
				}
				LearnPrefab();
				if (!IsEnabled)
				{
					return;
				}
				StrongBox<int> value = _fireCounts.GetValue(__instance, _makeCount);
				value.Value++;
				if (value.Value > 1)
				{
					return;
				}
				if (_hasFiredField == null || _delayField == null)
				{
					if (!_missingFieldLogged)
					{
						_missingFieldLogged = true;
						Log((LogLevel)2, "M2 电镖:取不到 FireTazer 的 hasFired / delay 字段,连发不会生效。");
					}
					return;
				}
				float num = SecondShotDelay();
				float num2 = (float)_delayField.GetValue(__instance) + num;
				_hasFiredField.SetValue(__instance, false);
				_delayField.SetValue(__instance, num2);
				if (_durationField != null && (float)_durationField.GetValue(__instance) < num2 + 0.05f)
				{
					_durationField.SetValue(__instance, num2 + 0.05f);
				}
				_scheduledCount++;
				if (_scheduledCount == 1 || _scheduledCount % 20 == 0)
				{
					Log((LogLevel)16, "M2「能量电镖」已排入第二枚射弹(间隔 " + num.ToString("0.##") + " 秒,累计 " + _scheduledCount + " 次)。");
				}
			}
			catch (Exception ex)
			{
				Log((LogLevel)4, "M2 电镖:编排第二枚射弹时异常(已忽略)—— " + ex.GetType().Name + " " + ex.Message);
			}
		}

		private static void LearnPrefab()
		{
			try
			{
				if ((Object)(object)_tazerPrefab != (Object)null || _projectilePrefabField == null)
				{
					return;
				}
				object? value = _projectilePrefabField.GetValue(null);
				GameObject val = (GameObject)((value is GameObject) ? value : null);
				if (!((Object)(object)val == (Object)null))
				{
					_tazerPrefab = val;
					if (!_prefabLogged)
					{
						_prefabLogged = true;
						Log((LogLevel)16, "已记住「能量电镖」的射弹 prefab: " + ((Object)val).name);
					}
				}
			}
			catch (Exception ex)
			{
				Log((LogLevel)4, "记住电镖 prefab 时异常(已忽略)—— " + ex.GetType().Name + " " + ex.Message);
			}
		}

		internal 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 CaptainTazerChainLightning
	{
		private static ConfigEntry<bool> _enabled;

		private static ConfigEntry<float> _damageRatio;

		private static ConfigEntry<float> _procCoefficient;

		private static ConfigEntry<int> _chainTargets;

		private static ConfigEntry<float> _range;

		private static ConfigEntry<bool> _inheritCrit;

		private static ConfigEntry<bool> _excludePrimaryTarget;

		private static ConfigEntry<bool> _singleTargetFallback;

		private static ConfigEntry<bool> _electrical;

		private static ConfigEntry<string> _projectileName;

		private static ManualLogSource _log;

		private static readonly HashSet<string> _seenProjectiles = new HashSet<string>();

		private static FieldInfo _controllerField;

		private static FieldInfo _damageField;

		private static bool _fieldsTried;

		private static bool _firedLogged;

		private static int _firedCount;

		internal static bool IsEnabled
		{
			get
			{
				if (_enabled != null)
				{
					return _enabled.Value;
				}
				return true;
			}
		}

		internal static void Init(ConfigFile config, ManualLogSource log)
		{
			_log = log;
			_enabled = config.Bind<bool>("ChainLightning", "Enabled", true, "是否让 M2「能量电镖」命中后甩出一道尤克里里式连锁闪电。");
			_damageRatio = config.Bind<float>("ChainLightning", "DamageRatio", 0.8f, "闪电每一跳的伤害 = 电镖原本伤害 × 这个值。尤克里里是 0.8(原版还会保底 1 点伤害)。");
			_procCoefficient = config.Bind<float>("ChainLightning", "ProcCoefficient", 0.2f, "闪电的触发系数。尤克里里是 0.2(填 0 就等于完全不触发道具)。");
			_chainTargets = config.Bind<int>("ChainLightning", "ChainTargets", 3, "这道闪电一共能打到几个敌人(不含被电镖直接命中的那个)。");
			_range = config.Bind<float>("ChainLightning", "Range", 20f, "每次弹跳的搜索半径(米)。尤克里里基础 20。");
			_inheritCrit = config.Bind<bool>("ChainLightning", "InheritCrit", true, "true = 电镖那一下暴击的话,闪电也跟着暴击(尤克里里就是这么干的)。");
			_excludePrimaryTarget = config.Bind<bool>("ChainLightning", "ExcludePrimaryTarget", true, "true = 被电镖直接命中的那个敌人不会再被闪电打一次(跟尤克里里一样);\nfalse = 闪电也可能回头打他。");
			_singleTargetFallback = config.Bind<bool>("ChainLightning", "SingleTargetFallback", false, "附近没有别的敌人时,要不要让闪电回头打被直接命中的那个?\nfalse(默认)= 跟尤克里里一致:只有 1 个敌人时不会有任何闪电。");
			_electrical = config.Bind<bool>("ChainLightning", "Electrical", true, "闪电要不要带 <b>Electrical</b>(电击)伤害标记。\ntrue(默认)= 带。原版电镖本身就带这个标记,带上才统一;\n带它会让 <c>HealthComponent.CheckElectrocutionSpread</c> 以 50% 概率在 15 米内\n再放一次范围伤害并挂上持续伤害(就是原版电镖的电击扩散)。\nfalse = 闪电只是纯伤害,不会额外扩散。");
			_projectileName = config.Bind<string>("ChainLightning", "ProjectileName", "CaptainTazer", "电镖射弹的对象名(兜底用,不区分大小写)。游戏更新后改名了可以在这里改。");
		}

		internal static string Summary()
		{
			if (!IsEnabled)
			{
				return " [M2闪电链:关闭]";
			}
			return " [M2闪电链:命中后弹 " + ChainTargets() + " 个 / 半径 " + Range().ToString("0.#") + "m / 每跳 " + DamageRatio().ToString("0.##") + " 倍伤害,触发系数 " + ProcCoefficient().ToString("0.##") + "]";
		}

		private static float DamageRatio()
		{
			if (_damageRatio == null)
			{
				return 0.8f;
			}
			return _damageRatio.Value;
		}

		private static float ProcCoefficient()
		{
			if (_procCoefficient == null)
			{
				return 0.2f;
			}
			return _procCoefficient.Value;
		}

		private static int ChainTargets()
		{
			int num = ((_chainTargets != null) ? _chainTargets.Value : 3);
			if (num >= 1)
			{
				return num;
			}
			return 1;
		}

		private static float Range()
		{
			if (_range == null)
			{
				return 20f;
			}
			return _range.Value;
		}

		private static bool InheritCrit()
		{
			if (_inheritCrit != null)
			{
				return _inheritCrit.Value;
			}
			return true;
		}

		private static bool ExcludePrimaryTarget()
		{
			if (_excludePrimaryTarget != null)
			{
				return _excludePrimaryTarget.Value;
			}
			return true;
		}

		private static bool SingleTargetFallback()
		{
			if (_singleTargetFallback != null)
			{
				return _singleTargetFallback.Value;
			}
			return false;
		}

		private static bool Electrical()
		{
			if (_electrical != null)
			{
				return _electrical.Value;
			}
			return true;
		}

		internal static void Patch(Harmony harmony)
		{
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Expected O, but got Unknown
			if (!IsEnabled)
			{
				Log((LogLevel)16, "M2 闪电链:按配置保持原版,不挂任何补丁。");
				return;
			}
			MethodInfo methodInfo = AccessTools.Method(typeof(ProjectileExplosion), "DetonateServer", (Type[])null, (Type[])null);
			if (methodInfo == null)
			{
				Log((LogLevel)2, "M2 闪电链补丁失败:取不到 ProjectileExplosion.DetonateServer。");
				return;
			}
			try
			{
				harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(CaptainTazerChainLightning), "DetonateServerPostfix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				Log((LogLevel)16, "补丁已挂载:ProjectileExplosion.DetonateServer <- CaptainTazerChainLightning.DetonateServerPostfix(电镖命中后甩闪电链)");
			}
			catch (Exception ex)
			{
				Log((LogLevel)2, "M2 闪电链补丁失败(DetonateServer 没挂上,功能将完全失效)—— " + ex.GetType().Name + " " + ex.Message);
			}
		}

		public static void DetonateServerPostfix(ProjectileExplosion __instance)
		{
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (!IsEnabled || (Object)(object)__instance == (Object)null || !NetworkServer.active)
				{
					return;
				}
				ProjectileController projectileController = GetProjectileController(__instance);
				ProjectileDamage projectileDamage = GetProjectileDamage(__instance);
				if ((Object)(object)projectileController == (Object)null || (Object)(object)projectileDamage == (Object)null)
				{
					return;
				}
				GameObject projectilePrefab = ProjectileCatalog.GetProjectilePrefab(projectileController.catalogIndex);
				if ((Object)(object)projectilePrefab == (Object)null)
				{
					return;
				}
				bool flag = IsTazer(projectilePrefab);
				if (!_seenProjectiles.Contains(((Object)projectilePrefab).name))
				{
					_seenProjectiles.Add(((Object)projectilePrefab).name);
					Log((LogLevel)16, "M2 闪电链:DetonateServer 收到射弹「" + ((Object)projectilePrefab).name + "」—— " + (flag ? "能量电镖,会引雷" : "不是能量电镖,跳过"));
				}
				if (flag)
				{
					float num = projectileDamage.damage * __instance.blastDamageCoefficient;
					if (!(num <= 0f))
					{
						float lightningDamage = Mathf.Max(1f, num * DamageRatio());
						FireChain(((Component)__instance).transform.position, TeamOf(projectileController), projectileController.owner, InheritCrit() && projectileDamage.crit, lightningDamage, __instance.blastRadius, num);
					}
				}
			}
			catch (Exception ex)
			{
				Log((LogLevel)4, "M2 闪电链:引雷时异常(已忽略)—— " + ex.GetType().Name + " " + ex.Message);
			}
		}

		private static void FireChain(Vector3 position, TeamIndex teamIndex, GameObject attacker, bool crit, float lightningDamage, float blastRadius, float originalDamage)
		{
			//IL_000a: 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_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected O, but got Unknown
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			HurtBox val = (ExcludePrimaryTarget() ? FindNearestEnemy(position, teamIndex, blastRadius) : null);
			Vector3 val2 = (((Object)(object)val != (Object)null) ? ((Component)val).transform.position : position);
			LightningOrb val3 = new LightningOrb();
			((Orb)val3).origin = val2;
			val3.damageValue = lightningDamage;
			val3.isCrit = crit;
			val3.teamIndex = teamIndex;
			val3.attacker = attacker;
			val3.bouncesRemaining = ChainTargets() - 1;
			val3.bouncedObjects = new List<HealthComponent>();
			if ((Object)(object)val != (Object)null && (Object)(object)val.healthComponent != (Object)null)
			{
				val3.bouncedObjects.Add(val.healthComponent);
			}
			val3.procChainMask = default(ProcChainMask);
			((ProcChainMask)(ref val3.procChainMask)).AddProc((ProcType)3);
			val3.procCoefficient = ProcCoefficient();
			val3.damageType = default(DamageTypeCombo);
			if (Electrical())
			{
				val3.damageType.damageTypeExtended = (DamageTypeExtended)8192;
			}
			val3.lightningType = (LightningType)0;
			val3.damageColorIndex = (DamageColorIndex)3;
			val3.range = Range();
			HurtBox val4 = val3.PickNextTarget(val2);
			if ((Object)(object)val4 == (Object)null && SingleTargetFallback() && (Object)(object)val != (Object)null)
			{
				val3.bouncedObjects = new List<HealthComponent>();
				val4 = val;
			}
			if ((Object)(object)val4 == (Object)null)
			{
				Log((LogLevel)32, "M2 闪电链:半径 " + Range().ToString("0.#") + " 米内没有第二个敌人可弹,这一发没有闪电(想要单挑时也出闪电就把 cfg 里的 SingleTargetFallback 改成 true)。");
				return;
			}
			((Orb)val3).target = val4;
			OrbManager.instance.AddOrb((Orb)(object)val3);
			_firedCount++;
			if (!_firedLogged)
			{
				_firedLogged = true;
				Log((LogLevel)16, "M2 闪电链已生效:电镖命中,原伤害 " + originalDamage.ToString("0.#") + " → 闪电每跳 " + lightningDamage.ToString("0.#") + "(最多打 " + ChainTargets() + " 个目标,半径 " + Range().ToString("0.#") + " 米" + (Electrical() ? ",带电击标记" : ",不带电击标记") + ",触发系数 " + ProcCoefficient().ToString("0.##") + ")");
			}
			else if (_firedCount % 20 == 0)
			{
				Log((LogLevel)16, "M2 闪电链已放出 " + _firedCount + " 次,最近一次每跳 " + lightningDamage.ToString("0.#") + " 伤害,目标 " + ((Object)val4).name);
			}
		}

		private static HurtBox FindNearestEnemy(Vector3 position, TeamIndex teamIndex, float radius)
		{
			//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_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: 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_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: 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)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			BullseyeSearch val = new BullseyeSearch
			{
				searchOrigin = position,
				searchDirection = Vector3.zero,
				teamMaskFilter = TeamMask.allButNeutral
			};
			((TeamMask)(ref val.teamMaskFilter)).RemoveTeam(teamIndex);
			val.filterByLoS = false;
			val.sortMode = (SortMode)1;
			val.maxDistanceFilter = ((radius > 0f) ? radius : 1f);
			val.RefreshCandidates();
			using (IEnumerator<HurtBox> enumerator = val.GetResults().GetEnumerator())
			{
				if (enumerator.MoveNext())
				{
					return enumerator.Current;
				}
			}
			return null;
		}

		private static void EnsureFields()
		{
			if (!_fieldsTried)
			{
				_fieldsTried = true;
				_controllerField = AccessTools.Field(typeof(ProjectileExplosion), "projectileController");
				_damageField = AccessTools.Field(typeof(ProjectileExplosion), "projectileDamage");
				if (_controllerField == null || _damageField == null)
				{
					Log((LogLevel)2, "M2 闪电链:取不到 ProjectileExplosion 的 projectileController / projectileDamage 字段,认不出射弹也算不出伤害。");
				}
			}
		}

		private static ProjectileController GetProjectileController(ProjectileExplosion explosion)
		{
			EnsureFields();
			if (!(_controllerField != null))
			{
				return null;
			}
			object? value = _controllerField.GetValue(explosion);
			return (ProjectileController)((value is ProjectileController) ? value : null);
		}

		private static ProjectileDamage GetProjectileDamage(ProjectileExplosion explosion)
		{
			EnsureFields();
			if (!(_damageField != null))
			{
				return null;
			}
			object? value = _damageField.GetValue(explosion);
			return (ProjectileDamage)((value is ProjectileDamage) ? value : null);
		}

		private static bool IsTazer(GameObject prefab)
		{
			if ((Object)(object)prefab == (Object)null)
			{
				return false;
			}
			if (prefab == CaptainTazerBurst.TazerPrefab)
			{
				return true;
			}
			string text = ((_projectileName != null) ? _projectileName.Value : "CaptainTazer");
			if (string.IsNullOrEmpty(text) || string.IsNullOrEmpty(((Object)prefab).name))
			{
				return false;
			}
			return string.Equals(((Object)prefab).name, text, StringComparison.OrdinalIgnoreCase);
		}

		private static TeamIndex TeamOf(ProjectileController controller)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)controller != (Object)null)
			{
				TeamFilter teamFilter = controller.teamFilter;
				if ((Object)(object)teamFilter != (Object)null)
				{
					return teamFilter.teamIndex;
				}
				if ((Object)(object)controller.owner != (Object)null)
				{
					return TeamComponent.GetObjectTeam(controller.owner);
				}
			}
			return (TeamIndex)0;
		}

		internal 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 CaptainTazerDamage
	{
		private const float VanillaCoefficient = 1f;

		private static ManualLogSource _log;

		private static ConfigEntry<bool> _enabled;

		private static ConfigEntry<float> _damagePercent;

		private static readonly FieldInfo _damageField = AccessTools.Field(typeof(FireTazer), "damageCoefficient");

		private static float _base = -1f;

		private static bool _appliedLogged;

		private static int _appliedCount;

		private static bool IsEnabled
		{
			get
			{
				if (_enabled != null)
				{
					return _enabled.Value;
				}
				return true;
			}
		}

		internal static void Init(ConfigFile config, ManualLogSource log)
		{
			_log = log;
			_enabled = config.Bind<bool>("Secondary.能量电镖", "DamageEnabled", true, "是否把 M2「能量电镖」的伤害从每发 100% 提升到 280%。");
			_damagePercent = config.Bind<float>("Secondary.能量电镖", "DamagePercent", 280f, "每发电镖的伤害百分比。280 = 每发 280% 伤害;100 = 原版。");
		}

		internal static string Summary()
		{
			if (!IsEnabled)
			{
				return " [M2伤害:原版100%]";
			}
			float num = ((_base > 0f) ? _base : 1f);
			return " [M2伤害:" + (num * 100f).ToString("0") + "% → " + DamagePercent().ToString("0") + "%]";
		}

		private static float DamagePercent()
		{
			if (_damagePercent == null)
			{
				return 280f;
			}
			return _damagePercent.Value;
		}

		private static float Multiplier()
		{
			return Math.Max(0f, DamagePercent()) / 100f;
		}

		internal static void Patch(Harmony harmony)
		{
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Expected O, but got Unknown
			if (!IsEnabled)
			{
				Log((LogLevel)16, "M2 伤害:按配置保持原版,不挂补丁。");
				return;
			}
			if (_damageField == null)
			{
				Log((LogLevel)2, "M2 伤害补丁失败:取不到 FireTazer.damageCoefficient,伤害不会变。");
				return;
			}
			MethodInfo methodInfo = AccessTools.Method(typeof(FireTazer), "Fire", (Type[])null, (Type[])null);
			if (methodInfo == null)
			{
				Log((LogLevel)2, "M2 伤害补丁失败:取不到 EntityStates.Captain.Weapon.FireTazer.Fire。");
				return;
			}
			harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(AccessTools.Method(typeof(CaptainTazerDamage), "FirePrefix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			Log((LogLevel)16, "补丁已挂载:EntityStates.Captain.Weapon.FireTazer.Fire <- CaptainTazerDamage.FirePrefix(每发伤害 → " + DamagePercent().ToString("0") + "%)");
		}

		public static void FirePrefix()
		{
			try
			{
				if (IsEnabled && !(_damageField == null))
				{
					if (_base < 0f)
					{
						_base = (float)_damageField.GetValue(null);
						Log((LogLevel)16, "M2「能量电镖」原版伤害系数 = " + _base.ToString("0.###") + "(原版 1 = 100%;若不是 1 说明游戏改过数值,百分比仍按百分比生效)。");
					}
					float num = _base * Multiplier();
					_damageField.SetValue(null, num);
					_appliedCount++;
					if (!_appliedLogged)
					{
						_appliedLogged = true;
						Log((LogLevel)16, "M2「能量电镖」伤害已生效:" + (_base * 100f).ToString("0") + "% → " + (num * 100f).ToString("0") + "% 每发。");
					}
					else if (_appliedCount % 60 == 0)
					{
						Log((LogLevel)16, "M2「能量电镖」伤害已应用 " + _appliedCount + " 次,当前每发 " + (num * 100f).ToString("0") + "%。");
					}
				}
			}
			catch (Exception ex)
			{
				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);
			}
		}
	}
	[BepInPlugin("com.sparkletwilight.sparklecaptaintweaks", "SparkleCaptainTweaks", "1.3.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class SparkleCaptainTweaksPlugin : BaseUnityPlugin
	{
		public const string PluginGUID = "com.sparkletwilight.sparklecaptaintweaks";

		public const string PluginName = "SparkleCaptainTweaks";

		public const string PluginVersion = "1.3.0";

		internal ManualLogSource Logger;

		public void Awake()
		{
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Expected O, but got Unknown
			Logger = ((BaseUnityPlugin)this).Logger;
			CaptainShotgunCharge.Init(((BaseUnityPlugin)this).Config, Logger);
			CaptainTazerBurst.Init(((BaseUnityPlugin)this).Config, Logger);
			CaptainTazerDamage.Init(((BaseUnityPlugin)this).Config, Logger);
			CaptainTazerChainLightning.Init(((BaseUnityPlugin)this).Config, Logger);
			CaptainOrbitalProbe.Init(((BaseUnityPlugin)this).Config, Logger);
			CaptainSupplyRestockSkills.Init(((BaseUnityPlugin)this).Config, Logger);
			CaptainSkillText.Init(((BaseUnityPlugin)this).Config, Logger);
			Harmony harmony = new Harmony("com.sparkletwilight.sparklecaptaintweaks");
			SafePatch("M1 蓄力时间", delegate
			{
				CaptainShotgunCharge.Patch(harmony);
			});
			SafePatch("M2 连发", delegate
			{
				CaptainTazerBurst.Patch(harmony);
			});
			SafePatch("M2 伤害", delegate
			{
				CaptainTazerDamage.Patch(harmony);
			});
			SafePatch("M2 闪电链", delegate
			{
				CaptainTazerChainLightning.Patch(harmony);
			});
			SafePatch("Shift 轨道探测器", delegate
			{
				CaptainOrbitalProbe.Patch(harmony);
			});
			SafePatch("R 信标补给", delegate
			{
				CaptainSupplyRestockSkills.Patch(harmony);
			});
			Logger.LogInfo((object)("SparkleCaptainTweaks v1.3.0 已加载。" + CaptainShotgunCharge.Summary() + CaptainTazerBurst.Summary() + CaptainTazerDamage.Summary() + CaptainTazerChainLightning.Summary() + CaptainOrbitalProbe.Summary() + CaptainSupplyRestockSkills.Summary()));
		}

		public void Update()
		{
			CaptainSkillText.Tick();
			CaptainOrbitalProbe.Tick();
		}

		private void SafePatch(string label, Action patch)
		{
			try
			{
				patch();
			}
			catch (Exception ex)
			{
				Logger.LogError((object)("SparkleCaptainTweaks:「" + label + "」挂补丁时抛异常,已跳过该模块 —— " + ex.GetType().Name + " " + ex.Message));
			}
		}
	}
}