Decompiled source of SparkleArtificerTweaks v1.10.0

plugins/SparkleArtificerTweaks.dll

Decompiled 21 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.Mage;
using EntityStates.Mage.Weapon;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using R2API;
using RoR2;
using RoR2.Orbs;
using RoR2.Projectile;
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("SparkleArtificerTweaks")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.10.0.0")]
[assembly: AssemblyInformationalVersion("1.10.0")]
[assembly: AssemblyProduct("SparkleArtificerTweaks")]
[assembly: AssemblyTitle("SparkleArtificerTweaks")]
[assembly: AssemblyVersion("1.10.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 SparkleArtificerTweaks
{
	public static class ArtificerChainLightning
	{
		private const string PlasmaLabel = "等离子弹";

		private const string NanoLabel = "充能完毕的纳米炸弹";

		private const int IgniteOnHitBit = 128;

		private const int PercentIgniteOnHitBit = 8192;

		private const int ElectricalBit = 8192;

		private static ConfigEntry<bool> _enabled;

		private static ConfigEntry<bool> _plasmaEnabled;

		private static ConfigEntry<bool> _nanoEnabled;

		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> _plasmaElectrical;

		private static ConfigEntry<bool> _plasmaNoIgnite;

		private static ConfigEntry<bool> _nanoNoIgnite;

		private static ConfigEntry<float> _nanoRangeBonus;

		private static ConfigEntry<int> _nanoTargetsBonus;

		private static ConfigEntry<string> _plasmaProjectileName;

		private static ConfigEntry<string> _nanoProjectileName;

		private static ManualLogSource _log;

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

		private static GameObject _plasmaPrefab;

		private static GameObject _nanoPrefab;

		private static FieldInfo _controllerField;

		private static FieldInfo _damageField;

		private static FieldInfo _applyDotField;

		private static FieldInfo _dotIndexField;

		private static bool _fieldsTried;

		private static bool _plasmaFiredLogged;

		private static bool _nanoFiredLogged;

		private static bool _firedLogged;

		private static bool _igniteLogged;

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

		public static void Init(ConfigFile cfg, ManualLogSource logger)
		{
			_log = logger;
			_enabled = cfg.Bind<bool>("ChainLightning", "Enabled", true, "是否启用「等离子弹 / 纳米炸弹命中后甩出一道尤克里里式连锁闪电」。");
			_plasmaEnabled = cfg.Bind<bool>("ChainLightning", "PlasmaBolt", true, "等离子弹(主要技能·电)也吃这个效果。");
			_nanoEnabled = cfg.Bind<bool>("ChainLightning", "ChargedNanoBomb", true, "充能完毕的纳米炸弹(辅助技能·电)也吃这个效果。");
			_damageRatio = cfg.Bind<float>("ChainLightning", "DamageRatio", 0.8f, "闪电每一跳的伤害 = 原本爆炸伤害 × 这个值。\n尤克里里是 0.8(原版还会保底 1 点伤害)。运行期读取。");
			_procCoefficient = cfg.Bind<float>("ChainLightning", "ProcCoefficient", 0.2f, "闪电的触发系数。尤克里里是 0.2(填 0 就等于完全不触发道具)。运行期读取。");
			_chainTargets = cfg.Bind<int>("ChainLightning", "ChainTargets", 3, "这道闪电一共能打到几个敌人(不含被射弹直接命中的那个)。\n尤克里里 1 层是 3 个,每多一层 +2。运行期读取。");
			_range = cfg.Bind<float>("ChainLightning", "Range", 20f, "每次弹跳的搜索半径(米)。尤克里里基础 20,每层 +2。运行期读取。");
			_inheritCrit = cfg.Bind<bool>("ChainLightning", "InheritCrit", true, "true = 射弹那一下暴击的话,闪电也跟着暴击(尤克里里就是这么干的)。");
			_excludePrimaryTarget = cfg.Bind<bool>("ChainLightning", "ExcludePrimaryTarget", true, "true = 被射弹直接命中的那个敌人不会再被闪电打一次(跟尤克里里一样);\nfalse = 闪电也可能回头打他。");
			_singleTargetFallback = cfg.Bind<bool>("ChainLightning", "SingleTargetFallback", false, "附近没有别的敌人时,要不要让闪电回头打被直接命中的那个?\nfalse(默认)= 跟尤克里里完全一致:只有 1 个敌人时不会有任何闪电;\ntrue = 至少能看到一道闪电(打在被命中的那个身上)。运行期读取。");
			_plasmaElectrical = cfg.Bind<bool>("ChainLightning", "PlasmaBoltElectrical", false, "等离子弹的闪电要不要带 <b>Electrical</b>(电)伤害标记。\nfalse(默认)= 不带。原因:原版 FireLightningBolt.ModifyProjectileInfo 会在运行时把\n等离子弹的伤害类型覆盖成 DamageTypeCombo.GenericPrimary(Generic + Primary,没有 Electrical),\n而这个标记一旦带上,HealthComponent.CheckElectrocutionSpread 就会以 50% 概率在 15 米内\n再放一次范围伤害并挂上持续伤害 —— 等于让等离子弹「点燃」了敌人,这是原版没有的。\ntrue = 跟尤克里里完全一致(带 Electrical 标记,会有电击扩散)。");
			_nanoRangeBonus = cfg.Bind<float>("ChainLightning", "NanoBombRangeBonus", 10f, "充能完毕的纳米炸弹的闪电,搜索半径在这个基础上再加多少米(基础值见 Range)。\n默认 +10 → 纳米炸弹是 30 米,等离子弹仍是 20 米。运行期读取。");
			_nanoTargetsBonus = cfg.Bind<int>("ChainLightning", "NanoBombChainTargetsBonus", 2, "充能完毕的纳米炸弹的闪电,最多能打的敌人数在这个基础上再加几个(基础值见 ChainTargets)。\n默认 +2 → 纳米炸弹是 5 个,等离子弹仍是 3 个。运行期读取。");
			_plasmaNoIgnite = cfg.Bind<bool>("ChainLightning", "PlasmaBoltNoIgnite", true, "等离子弹「直接命中」的那一下,强制不点燃敌人。\ntrue(默认)= 结算爆炸伤害之前,把伤害类型里的点燃标记\n(IgniteOnHit / PercentIgniteOnHit)和电击标记(Electrical)全部清掉。\n为什么需要:射弹 prefab 上写死的是 {damageType=0, damageTypeExtended=8192(Electrical)},\n而 Electrical 会让 HealthComponent.CheckElectrocutionSpread 以 50% 概率在 15 米内\n再放一次范围伤害并挂上持续伤害 —— 看起来就跟「点燃」一样。\n开火时 FireLightningBolt 本来会把它覆盖成 GenericPrimary,但只要这条覆盖没走到\n(prefab 默认值生效的路径),等离子弹就会烧起来。false = 完全不动原版伤害类型。");
			_nanoNoIgnite = cfg.Bind<bool>("ChainLightning", "NanoBombNoIgnite", false, "充能完毕的纳米炸弹要不要也做上面那个「禁止点燃/电击」清理。\nfalse(默认)= 保持原版(纳米炸弹本来就该带电击,会电击扩散);true = 也把它的 Electrical 标记清掉。");
			_plasmaProjectileName = cfg.Bind<string>("ChainLightning", "PlasmaBoltProjectileName", "MageLightningboltBasic", "等离子弹的射弹对象名(兜底用,不区分大小写)。游戏更新后改名了可以在这里改。");
			_nanoProjectileName = cfg.Bind<string>("ChainLightning", "NanoBombProjectileName", "MageLightningBombProjectile", "纳米炸弹的射弹对象名(兜底用,不区分大小写)。");
		}

		public static string Summary()
		{
			if (!IsEnabled)
			{
				return " [连锁闪电:原版未改动]";
			}
			string text = "";
			if (PlasmaEnabled())
			{
				text += "等离子弹";
			}
			if (NanoEnabled())
			{
				text = text + ((text.Length > 0) ? "/" : "") + "纳米炸弹";
			}
			if (text.Length == 0)
			{
				return " [连锁闪电:两个技能都关了]";
			}
			string text2 = "等离子弹 打 " + ChainTargets() + " 个 / 半径 " + Range().ToString("0.#") + (PlasmaElectrical() ? "(带电击标记)" : "(不带电击标记)");
			if (NanoEnabled())
			{
				text2 = text2 + ",纳米炸弹 打 " + (ChainTargets() + NanoTargetsBonus()) + " 个 / 半径 " + (Range() + NanoRangeBonus()).ToString("0.#");
			}
			return " [连锁闪电:" + text + " 命中后弹雷 —— " + text2 + "," + DamageRatio().ToString("0.##") + " 倍伤害,触发系数 " + ProcCoefficient().ToString("0.##") + "]";
		}

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

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

		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 PlasmaElectrical()
		{
			if (_plasmaElectrical != null)
			{
				return _plasmaElectrical.Value;
			}
			return false;
		}

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

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

		private static float NanoRangeBonus()
		{
			if (_nanoRangeBonus == null)
			{
				return 10f;
			}
			return _nanoRangeBonus.Value;
		}

		private static int NanoTargetsBonus()
		{
			if (_nanoTargetsBonus == null)
			{
				return 2;
			}
			return _nanoTargetsBonus.Value;
		}

		public static void Patch(Harmony harmony)
		{
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Expected O, but got Unknown
			//IL_00bf: Expected O, but got Unknown
			if (!IsEnabled)
			{
				Log((LogLevel)16, "连锁闪电:按配置保持原版,不挂任何补丁。");
				return;
			}
			PatchLearn(harmony, typeof(FireLightningBolt), "ModifyProjectileInfo", "PlasmaBoltPostfix", "等离子弹");
			PatchLearn(harmony, typeof(ThrowNovabomb), "ModifyProjectile", "NanoBombPostfix", "充能完毕的纳米炸弹");
			MethodInfo methodInfo = AccessTools.Method(typeof(ProjectileExplosion), "DetonateServer", (Type[])null, (Type[])null);
			if (methodInfo == null)
			{
				Log((LogLevel)2, "连锁闪电补丁失败:取不到 ProjectileExplosion.DetonateServer。");
				return;
			}
			try
			{
				harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(AccessTools.Method(typeof(ArtificerChainLightning), "DetonateServerPrefix", (Type[])null, (Type[])null)), new HarmonyMethod(AccessTools.Method(typeof(ArtificerChainLightning), "DetonateServerPostfix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				Log((LogLevel)16, "补丁已挂载:ProjectileExplosion.DetonateServer <- DetonateServerPrefix(清掉点燃/电击标记) + DetonateServerPostfix(命中后甩一道尤克里里式连锁闪电)");
			}
			catch (Exception ex)
			{
				Log((LogLevel)2, "连锁闪电补丁失败(ProjectileExplosion.DetonateServer 没挂上,功能将完全失效)—— " + ex.GetType().Name + " " + ex.Message);
			}
		}

		private static void PatchLearn(Harmony harmony, Type stateType, string methodName, string postfixName, string label)
		{
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Expected O, but got Unknown
			MethodInfo methodInfo = AccessTools.Method(stateType, methodName, (Type[])null, (Type[])null);
			if (methodInfo == null)
			{
				Log((LogLevel)4, "连锁闪电:取不到 " + stateType.Name + "." + methodName + "(" + label + "的射弹认不出来,不影响功能,还有 cfg 里的名字兜底)。");
				return;
			}
			try
			{
				harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(ArtificerChainLightning), postfixName, (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				Log((LogLevel)16, "补丁已挂载:" + stateType.Name + "." + methodName + " <- " + postfixName + "(记住" + label + "的射弹)");
			}
			catch (Exception ex)
			{
				Log((LogLevel)4, "连锁闪电:认" + label + "射弹的补丁没挂上(不影响功能,还有 cfg 里的名字兜底)—— " + ex.GetType().Name + " " + ex.Message);
			}
		}

		public static void PlasmaBoltPostfix(object[] __args)
		{
			Learn(ref _plasmaPrefab, ref _plasmaFiredLogged, __args, "等离子弹");
		}

		public static void NanoBombPostfix(object[] __args)
		{
			Learn(ref _nanoPrefab, ref _nanoFiredLogged, __args, "充能完毕的纳米炸弹");
		}

		private static void Learn(ref GameObject slot, ref bool logged, object[] args, string label)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: 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_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (IsEnabled && args != null && args.Length != 0 && args[0] is FireProjectileInfo val && !((Object)(object)val.projectilePrefab == (Object)null) && !((Object)(object)slot == (Object)(object)val.projectilePrefab))
				{
					slot = val.projectilePrefab;
					if (!logged)
					{
						logged = true;
						Log((LogLevel)16, "连锁闪电:已记住" + label + "的射弹 —— " + ((Object)val.projectilePrefab).name);
					}
				}
			}
			catch (Exception ex)
			{
				Log((LogLevel)4, "连锁闪电:记录" + label + "射弹时异常(已忽略)—— " + ex.GetType().Name + " " + ex.Message);
			}
		}

		public static void DetonateServerPrefix(ProjectileExplosion __instance)
		{
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Expected I4, but got Unknown
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Expected I4, but got Unknown
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Expected I4, but got Unknown
			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 = PlasmaEnabled() && IsPlasma(projectilePrefab);
				bool flag2 = NanoEnabled() && IsNano(projectilePrefab);
				if ((flag || flag2) && !(flag ? (!PlasmaNoIgnite()) : (!NanoNoIgnite())))
				{
					DamageTypeCombo damageType = projectileDamage.damageType;
					int num = (int)damageType.damageType;
					int num2 = (int)damageType.damageTypeExtended;
					int num3 = num & -129 & -8193;
					int num4 = num2 & -8193;
					if (!_igniteLogged)
					{
						_igniteLogged = true;
						Log((LogLevel)16, "禁止点燃(" + (flag ? "等离子弹" : "充能完毕的纳米炸弹") + "):实际伤害类型 = {damageType=" + num + ", damageTypeExtended=" + num2 + ", damageSource=" + (int)damageType.damageSource + "} → 清理后 = {" + num3 + ", " + num4 + ", source 不变};射弹组件 applyDot=" + DotInfo(__instance) + "。");
					}
					if (num3 != num || num4 != num2)
					{
						damageType.damageType = (DamageType)num3;
						damageType.damageTypeExtended = (DamageTypeExtended)num4;
						projectileDamage.damageType = damageType;
					}
				}
			}
			catch (Exception ex)
			{
				Log((LogLevel)4, "禁止点燃:清理伤害类型时异常(已忽略)—— " + ex.GetType().Name + " " + ex.Message);
			}
		}

		private static string DotInfo(ProjectileExplosion explosion)
		{
			EnsureFields();
			string obj = ((_applyDotField != null) ? Convert.ToString(_applyDotField.GetValue(explosion)) : "?");
			string text = ((_dotIndexField != null) ? Convert.ToString(_dotIndexField.GetValue(explosion)) : "?");
			return obj + ",dotIndex=" + text;
		}

		public static void DetonateServerPostfix(ProjectileExplosion __instance)
		{
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: 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))
				{
					bool flag = PlasmaEnabled() && IsPlasma(projectilePrefab);
					bool flag2 = NanoEnabled() && IsNano(projectilePrefab);
					if (!_seenProjectiles.Contains(((Object)projectilePrefab).name))
					{
						_seenProjectiles.Add(((Object)projectilePrefab).name);
						Log((LogLevel)16, "连锁闪电:DetonateServer 收到射弹「" + ((Object)projectilePrefab).name + "」—— " + (flag ? "等离子弹,会引雷" : (flag2 ? "纳米炸弹,会引雷" : "不是目标技能,跳过")));
					}
					if (flag || flag2)
					{
						float num = projectileDamage.damage * __instance.blastDamageCoefficient;
						float lightningDamage = Mathf.Max(1f, num * DamageRatio());
						TeamIndex teamIndex = TeamOf(projectileController);
						FireChain(((Component)__instance).transform.position, range: Range() + (flag2 ? NanoRangeBonus() : 0f), targets: ChainTargets() + (flag2 ? NanoTargetsBonus() : 0), electrical: !flag || PlasmaElectrical(), teamIndex: teamIndex, attacker: projectileController.owner, crit: InheritCrit() && projectileDamage.crit, lightningDamage: lightningDamage, blastRadius: __instance.blastRadius, label: flag ? "等离子弹" : "充能完毕的纳米炸弹", originalDamage: num);
					}
				}
			}
			catch (Exception ex)
			{
				Log((LogLevel)4, "连锁闪电:引雷时异常(已忽略)—— " + ex.GetType().Name + " " + ex.Message);
			}
		}

		private static void FireChain(Vector3 position, TeamIndex teamIndex, GameObject attacker, bool crit, float lightningDamage, float blastRadius, string label, float originalDamage, float range, int targets, bool electrical)
		{
			//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_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: 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 = targets - 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, "连锁闪电:半径 " + range.ToString("0.#") + " 米内没有第二个敌人可弹,这一发没有闪电(想要单挑时也出闪电就把 cfg 里的 SingleTargetFallback 改成 true)。");
				return;
			}
			((Orb)val3).target = val4;
			OrbManager.instance.AddOrb((Orb)(object)val3);
			Log((LogLevel)32, "连锁闪电已放出:" + label + " 命中,原伤害 " + originalDamage.ToString("0.#") + " → 每跳 " + lightningDamage.ToString("0.#") + ",目标 " + ((Object)val4).name);
			if (!_firedLogged)
			{
				_firedLogged = true;
				Log((LogLevel)16, "连锁闪电已生效:" + label + " 命中,原伤害 " + originalDamage.ToString("0.#") + " → 闪电每跳 " + lightningDamage.ToString("0.#") + "(最多打 " + targets + " 个目标,半径 " + range.ToString("0.#") + (electrical ? ",带电击标记" : ",不带电击标记") + ",触发系数 " + ProcCoefficient().ToString("0.##") + ")");
			}
		}

		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();
			HurtBox result = null;
			using (IEnumerator<HurtBox> enumerator = val.GetResults().GetEnumerator())
			{
				if (enumerator.MoveNext())
				{
					result = enumerator.Current;
				}
			}
			return result;
		}

		private static void EnsureFields()
		{
			if (!_fieldsTried)
			{
				_fieldsTried = true;
				_controllerField = AccessTools.Field(typeof(ProjectileExplosion), "projectileController");
				_damageField = AccessTools.Field(typeof(ProjectileExplosion), "projectileDamage");
				_applyDotField = AccessTools.Field(typeof(ProjectileExplosion), "applyDot");
				_dotIndexField = AccessTools.Field(typeof(ProjectileExplosion), "dotIndex");
				if (_controllerField == null || _damageField == null)
				{
					Log((LogLevel)2, "连锁闪电:取不到 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 IsPlasma(GameObject prefab)
		{
			if (!((Object)(object)prefab == (Object)(object)_plasmaPrefab))
			{
				return NameMatches(prefab, _plasmaProjectileName, "MageLightningboltBasic");
			}
			return true;
		}

		private static bool IsNano(GameObject prefab)
		{
			if (!((Object)(object)prefab == (Object)(object)_nanoPrefab))
			{
				return NameMatches(prefab, _nanoProjectileName, "MageLightningBombProjectile");
			}
			return true;
		}

		private static bool NameMatches(GameObject prefab, ConfigEntry<string> entry, string fallback)
		{
			string value = ((entry != null) ? entry.Value : fallback);
			if (string.IsNullOrEmpty(value) || string.IsNullOrEmpty(((Object)prefab).name))
			{
				return false;
			}
			return ((Object)prefab).name.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0;
		}

		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;
		}

		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);
			}
		}
	}
	public static class ArtificerFlamethrower
	{
		private const string SkillLabel = "火焰喷射器";

		private const float FallbackDuration = 3f;

		private const float AlwaysProc = 100f;

		private static ConfigEntry<bool> _enabled;

		private static ConfigEntry<float> _duration;

		private static ConfigEntry<bool> _keepTickDamage;

		private static ConfigEntry<float> _rangeMultiplier;

		private static ConfigEntry<bool> _igniteEveryTick;

		private static ConfigEntry<bool> _keepProcBudget;

		private static ConfigEntry<bool> _holdAim;

		private static ManualLogSource _log;

		private static float _baseDuration = -1f;

		private static float _baseMaxDistance = -1f;

		private static float _baseProcCoefficient = -1f;

		private static float _baseIgniteChance = -1f;

		private static bool _logged;

		private static bool _fieldsTried;

		private static FieldInfo _durationField;

		private static FieldInfo _tickDamageField;

		private static FieldInfo _tickFrequencyField;

		private static FieldInfo _totalDamageField;

		private static FieldInfo _entryDurationField;

		private static FieldInfo _procField;

		private static FieldInfo _maxDistanceField;

		private static FieldInfo _igniteField;

		private static PropertyInfo _characterBodyProperty;

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

		public static void Init(ConfigFile cfg, ManualLogSource logger)
		{
			_log = logger;
			_enabled = cfg.Bind<bool>("Flamethrower", "Enabled", true, "是否启用「火焰喷射器」这几处改动(时长 / 射程 / 每一跳点燃)。false = 保持原版。");
			_duration = cfg.Bind<float>("Flamethrower", "Duration", 3f, "喷射持续多少秒(原版 3)。运行期读取,改完下一次开火就生效。\n默认 3 秒 + 每一跳伤害不变 = 每秒伤害和原版一模一样。\n想喷得更久就调大(比如 30),总伤害会跟着线性增长。");
			_keepTickDamage = cfg.Bind<bool>("Flamethrower", "KeepTickDamage", true, "每一跳的伤害要不要保持原版不变。\ntrue(默认)= 每一跳伤害跟原版 3 秒时一模一样(每秒伤害恒定),喷得越久总伤害越高。\nfalse = 用原版那套「总伤害固定、按 tick 摊薄」:拉长时长只会让每一跳变轻,总伤害不变。");
			_rangeMultiplier = cfg.Bind<float>("Flamethrower", "RangeMultiplier", 2f, "射程 = 原版 maxDistance(20 米)× 这个值。2 = 翻倍到 40 米。填 1 = 保持原版。");
			_igniteEveryTick = cfg.Bind<bool>("Flamethrower", "IgniteEveryTick", true, "每一跳都附带点燃。\n原版 ignitePercentChance = 50,也就是每一跳只有一半几率带 IgniteOnHit 标记;\ntrue = 把这个概率设成 100,每一跳都点燃。false = 保持原版的 50%。");
			_keepProcBudget = cfg.Bind<bool>("Flamethrower", "KeepProcBudget", true, "道具触发要不要保持原版的「总预算」。\ntrue(默认)= 拉长时长时把 procCoefficientPerTick 按倍率摊薄,整个技能触发道具的总次数和原版 3 秒时一样。\nfalse = 每一跳的触发系数不变,喷得越久触发次数越多。\n(Duration 保持 3 秒时这一项不起作用,触发系数就是原版的 1.0。)");
			_holdAim = cfg.Bind<bool>("Flamethrower", "HoldAim", true, "把瞄准锁定拉长到和喷射一样的时间。\n原版 OnEnter 里 SetAimTimer 用的是还没赋值的 flamethrowerDuration(等于只锁 1 秒左右),喷久了会提前解锁、转不动视角。true = 按实际时长重设一次。");
		}

		public static string Summary()
		{
			if (!IsEnabled)
			{
				return "";
			}
			string text = " [火焰喷射器:" + Duration().ToString("0.#") + "秒";
			float num = RangeMultiplier();
			if (num > 0f && Mathf.Abs(num - 1f) >= 0.0001f)
			{
				text = text + " · 射程×" + num.ToString("0.##");
			}
			if (IgniteEveryTick())
			{
				text += " · 每一跳点燃";
			}
			if (KeepTickDamage())
			{
				text += " · 每秒伤害不变";
			}
			return text + "]";
		}

		public 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, "火焰喷射器:按配置保持原版,不挂任何补丁。");
				return;
			}
			MethodInfo methodInfo = AccessTools.Method(typeof(Flamethrower), "OnEnter", (Type[])null, (Type[])null);
			if (methodInfo == null)
			{
				Log((LogLevel)2, "火焰喷射器:取不到 Flamethrower.OnEnter,改动不会生效。");
				return;
			}
			try
			{
				harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(ArtificerFlamethrower), "OnEnterPostfix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				Log((LogLevel)16, "补丁已挂载:Flamethrower.OnEnter -> OnEnterPostfix(火焰喷射器 · 时长 / 射程 / 点燃)");
			}
			catch (Exception ex)
			{
				Log((LogLevel)2, "火焰喷射器补丁失败(改动不会生效)—— " + ex.GetType().Name + " " + ex.Message);
			}
		}

		public static void OnEnterPostfix(Flamethrower __instance)
		{
			try
			{
				if (!IsEnabled || __instance == null || !PrepareFields())
				{
					return;
				}
				float num = Float(_durationField, __instance);
				if (_baseDuration <= 0f)
				{
					_baseDuration = ((num > 0f) ? num : 3f);
				}
				float num2 = Duration();
				bool flag = num2 > 0f && Mathf.Abs(num - num2) >= 0.0001f;
				if (flag)
				{
					_durationField.SetValue(__instance, num2);
					float num3 = Float(_tickFrequencyField, __instance);
					float num4 = Float(_totalDamageField, __instance);
					int num5 = Mathf.CeilToInt((KeepTickDamage() ? num : num2) * num3);
					if (num5 > 0)
					{
						_tickDamageField.SetValue(__instance, num4 / (float)num5);
					}
				}
				if (_procField != null)
				{
					if (_baseProcCoefficient < 0f)
					{
						_baseProcCoefficient = Float(_procField, null);
					}
					float num6 = ((flag && num2 > 0f) ? (num / num2) : 1f);
					_procField.SetValue(null, KeepProcBudget() ? (_baseProcCoefficient * num6) : _baseProcCoefficient);
				}
				ApplyRange(__instance);
				ApplyIgnite();
				if (HoldAim() && _characterBodyProperty != null)
				{
					object? value = _characterBodyProperty.GetValue(__instance, null);
					CharacterBody val = (CharacterBody)((value is CharacterBody) ? value : null);
					if ((Object)(object)val != (Object)null)
					{
						val.SetAimTimer(Float(_entryDurationField, __instance) + (flag ? num2 : num) + 1f);
					}
				}
				if (!_logged)
				{
					_logged = true;
					Log((LogLevel)16, "火焰喷射器:时长 " + num.ToString("0.##") + " 秒 → " + (flag ? num2 : num).ToString("0.##") + " 秒,每一跳伤害系数 " + Float(_tickDamageField, __instance).ToString("0.####") + ",射程 " + Float(_maxDistanceField, __instance).ToString("0.#") + " 米,点燃概率 " + Float(_igniteField, null).ToString("0.#") + "%,每一跳触发系数 " + Float(_procField, null).ToString("0.####"));
				}
			}
			catch (Exception ex)
			{
				Log((LogLevel)4, "火焰喷射器:改动时异常(已忽略)—— " + ex.GetType().Name + " " + ex.Message);
			}
		}

		private static void ApplyRange(Flamethrower instance)
		{
			if (!(_maxDistanceField == null))
			{
				if (_baseMaxDistance < 0f)
				{
					_baseMaxDistance = Float(_maxDistanceField, instance);
				}
				float num = RangeMultiplier();
				if (!(num <= 0f) && !(Mathf.Abs(num - 1f) < 0.0001f))
				{
					_maxDistanceField.SetValue(instance, _baseMaxDistance * num);
				}
			}
		}

		private static void ApplyIgnite()
		{
			if (!(_igniteField == null))
			{
				if (_baseIgniteChance < 0f)
				{
					_baseIgniteChance = Float(_igniteField, null);
				}
				_igniteField.SetValue(null, IgniteEveryTick() ? 100f : _baseIgniteChance);
			}
		}

		private static bool PrepareFields()
		{
			if (_fieldsTried)
			{
				if (_durationField != null)
				{
					return _tickDamageField != null;
				}
				return false;
			}
			_fieldsTried = true;
			Type? typeFromHandle = typeof(Flamethrower);
			_durationField = AccessTools.Field(typeFromHandle, "flamethrowerDuration");
			_tickDamageField = AccessTools.Field(typeFromHandle, "tickDamageCoefficient");
			_tickFrequencyField = AccessTools.Field(typeFromHandle, "tickFrequency");
			_totalDamageField = AccessTools.Field(typeFromHandle, "totalDamageCoefficient");
			_entryDurationField = AccessTools.Field(typeFromHandle, "entryDuration");
			_procField = AccessTools.Field(typeFromHandle, "procCoefficientPerTick");
			_maxDistanceField = AccessTools.Field(typeFromHandle, "maxDistance");
			_igniteField = AccessTools.Field(typeFromHandle, "ignitePercentChance");
			_characterBodyProperty = AccessTools.Property(typeof(EntityState), "characterBody");
			if (_durationField == null || _tickDamageField == null)
			{
				Log((LogLevel)2, "火焰喷射器:反射取不到 flamethrowerDuration / tickDamageCoefficient,改动不会生效。");
				return false;
			}
			if (_maxDistanceField == null)
			{
				Log((LogLevel)4, "火焰喷射器:反射取不到 maxDistance,射程不会改。");
			}
			if (_igniteField == null)
			{
				Log((LogLevel)4, "火焰喷射器:反射取不到 ignitePercentChance,点燃不会改。");
			}
			return true;
		}

		private static float Float(FieldInfo field, object target)
		{
			if (field == null)
			{
				return 0f;
			}
			object value = field.GetValue(target);
			if (!(value is float))
			{
				return 0f;
			}
			return (float)value;
		}

		private static float Duration()
		{
			if (_duration == null)
			{
				return 3f;
			}
			return _duration.Value;
		}

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

		private static float RangeMultiplier()
		{
			if (_rangeMultiplier == null)
			{
				return 2f;
			}
			return _rangeMultiplier.Value;
		}

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

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

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

		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);
			}
		}
	}
	public static class ArtificerHoverSpeed
	{
		private const string ArtificerBodyToken = "MAGE_BODY_NAME";

		private static ConfigEntry<bool> _enabled;

		private static ConfigEntry<float> _multiplier;

		private static ConfigEntry<bool> _onlyArtificer;

		private static ConfigEntry<bool> _onlyWhileHovering;

		private static ManualLogSource _log;

		private static FieldInfo _moveSpeedField;

		private static MethodInfo _moveSpeedSetter;

		private static bool _moveSpeedWriterTried;

		private static readonly ConditionalWeakTable<CharacterBody, StrongBox<bool>> LastBoost = new ConditionalWeakTable<CharacterBody, StrongBox<bool>>();

		private static readonly ConditionalWeakTable<CharacterBody, StrongBox<EntityStateMachine[]>> MachineCache = new ConditionalWeakTable<CharacterBody, StrongBox<EntityStateMachine[]>>();

		private static float _nextTick;

		private static bool _appliedLogged;

		private static bool _machinesLogged;

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

		public static void Init(ConfigFile cfg, ManualLogSource logger)
		{
			_log = logger;
			_enabled = cfg.Bind<bool>("Hover", "Enabled", true, "是否启用「悬浮时移动速度 ×1.25」:工匠用被动(按住跳跃)悬在空中时,\n移动速度额外乘一个独立倍率,不与其他移速加成相加。");
			_multiplier = cfg.Bind<float>("Hover", "Multiplier", 1.25f, "悬浮时的移动速度倍率(1.25 = +25%)。独立乘区:在属性结算完成后单独乘最终移速,\n不与能量饮料之类的加成加算。填 1 = 不加成。这个值是运行期读取的(改 cfg 立即生效)。");
			_onlyArtificer = cfg.Bind<bool>("Hover", "OnlyArtificer", true, "只对工匠(Mage / Artificer)生效。false = 任何角色只要悬浮就加速(包括用喷射背包的其他角色)。");
			_onlyWhileHovering = cfg.Bind<bool>("Hover", "OnlyWhileHovering", true, "true = 只在被动悬浮真正生效(JetpackOn 状态)时加速;\nfalse = 放宽成只要双脚离地就加速(跳跃、坠落、被击飞都算)。");
		}

		public static string Summary()
		{
			if (!IsEnabled)
			{
				return " [悬浮:原版未改动]";
			}
			return " [悬浮:移速 ×" + Multiplier().ToString("0.##") + ((_onlyWhileHovering == null || _onlyWhileHovering.Value) ? "(被动悬浮中)" : "(离地即生效)") + "]";
		}

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

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

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

		public static void Patch(Harmony harmony)
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Expected O, but got Unknown
			if (!IsEnabled)
			{
				Log((LogLevel)16, "悬浮加速:按配置保持原版,不挂任何补丁。");
				return;
			}
			MethodInfo methodInfo = AccessTools.Method(typeof(CharacterBody), "RecalculateStats", (Type[])null, (Type[])null);
			if (methodInfo == null)
			{
				Log((LogLevel)2, "悬浮加速补丁失败:取不到 CharacterBody.RecalculateStats。");
				return;
			}
			harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(ArtificerHoverSpeed), "RecalculateStatsPostfix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			Log((LogLevel)16, "补丁已挂载:CharacterBody.RecalculateStats <- RecalculateStatsPostfix(悬浮时移速独立乘 " + Multiplier().ToString("0.##") + ")");
			EnsureMoveSpeedWriter();
		}

		public static void RecalculateStatsPostfix(CharacterBody __instance)
		{
			try
			{
				if ((Object)(object)__instance == (Object)null || !ShouldBoost(__instance))
				{
					return;
				}
				float num = Multiplier();
				if (!(num <= 0f) && !Mathf.Approximately(num, 1f))
				{
					float moveSpeed = __instance.moveSpeed;
					float num2 = moveSpeed * num;
					if (!(num2 <= moveSpeed) && SetMoveSpeed(__instance, num2) && !_appliedLogged)
					{
						_appliedLogged = true;
						Log((LogLevel)16, "悬浮加速已生效:" + BodyName(__instance) + " 移速 " + moveSpeed.ToString("0.##") + " → " + num2.ToString("0.##") + "(×" + num.ToString("0.##") + " 独立乘区)");
					}
				}
			}
			catch (Exception ex)
			{
				Log((LogLevel)4, "悬浮加速:属性结算异常(已忽略)—— " + ex.GetType().Name + " " + ex.Message);
			}
		}

		public static void Tick()
		{
			if (!IsEnabled || Time.unscaledTime < _nextTick)
			{
				return;
			}
			_nextTick = Time.unscaledTime + 0.1f;
			try
			{
				ReadOnlyCollection<CharacterBody> readOnlyInstancesList = CharacterBody.readOnlyInstancesList;
				for (int i = 0; i < readOnlyInstancesList.Count; i++)
				{
					CharacterBody val = readOnlyInstancesList[i];
					if ((Object)(object)val == (Object)null)
					{
						continue;
					}
					bool flag = ShouldBoost(val);
					if (!LastBoost.TryGetValue(val, out var value))
					{
						value = new StrongBox<bool>(flag);
						LastBoost.Add(val, value);
					}
					else if (value.Value != flag)
					{
						value.Value = flag;
						if (flag)
						{
							val.RecalculateStats();
						}
						else
						{
							val.RecalculateStats();
						}
					}
				}
			}
			catch (Exception ex)
			{
				Log((LogLevel)4, "悬浮加速:状态扫描异常(已忽略)—— " + ex.GetType().Name + " " + ex.Message);
			}
		}

		private static bool ShouldBoost(CharacterBody body)
		{
			if (!IsEnabled || (Object)(object)body == (Object)null)
			{
				return false;
			}
			if (OnlyArtificer() && !IsArtificer(body))
			{
				return false;
			}
			if (OnlyWhileHovering())
			{
				return IsHovering(body);
			}
			return IsAirborne(body);
		}

		private static bool IsHovering(CharacterBody body)
		{
			EntityStateMachine[] machines = GetMachines(body);
			if (machines == null)
			{
				return false;
			}
			foreach (EntityStateMachine val in machines)
			{
				if (!((Object)(object)val == (Object)null) && val.state is JetpackOn)
				{
					return true;
				}
			}
			return false;
		}

		private static EntityStateMachine[] GetMachines(CharacterBody body)
		{
			if (MachineCache.TryGetValue(body, out var value))
			{
				return value.Value;
			}
			EntityStateMachine[] components = ((Component)body).GetComponents<EntityStateMachine>();
			MachineCache.Add(body, new StrongBox<EntityStateMachine[]>(components));
			if (!_machinesLogged)
			{
				_machinesLogged = true;
				string text = "";
				for (int i = 0; i < components.Length; i++)
				{
					if (!((Object)(object)components[i] == (Object)null))
					{
						text = text + ((text.Length > 0) ? " / " : "") + components[i].customName;
					}
				}
				Log((LogLevel)16, "悬浮加速:已缓存 " + BodyName(body) + " 的状态机(" + components.Length + " 台:" + text + "),靠 JetpackOn 状态判断悬浮。");
			}
			return components;
		}

		private static bool IsAirborne(CharacterBody body)
		{
			CharacterMotor characterMotor = body.characterMotor;
			if ((Object)(object)characterMotor != (Object)null)
			{
				return !characterMotor.isGrounded;
			}
			return false;
		}

		private static bool IsArtificer(CharacterBody body)
		{
			if (!string.IsNullOrEmpty(body.baseNameToken) && string.Equals(body.baseNameToken, "MAGE_BODY_NAME", StringComparison.Ordinal))
			{
				return true;
			}
			if (!string.IsNullOrEmpty(((Object)body).name))
			{
				return ((Object)body).name.IndexOf("MageBody", StringComparison.OrdinalIgnoreCase) >= 0;
			}
			return false;
		}

		private static bool SetMoveSpeed(CharacterBody body, float value)
		{
			EnsureMoveSpeedWriter();
			if (_moveSpeedField != null)
			{
				_moveSpeedField.SetValue(body, value);
				return true;
			}
			if (_moveSpeedSetter != null)
			{
				_moveSpeedSetter.Invoke(body, new object[1] { value });
				return true;
			}
			return false;
		}

		private static void EnsureMoveSpeedWriter()
		{
			if (!_moveSpeedWriterTried)
			{
				_moveSpeedWriterTried = true;
				_moveSpeedField = AccessTools.Field(typeof(CharacterBody), "<moveSpeed>k__BackingField");
				if (_moveSpeedField == null)
				{
					_moveSpeedField = AccessTools.Field(typeof(CharacterBody), "moveSpeed");
				}
				_moveSpeedSetter = typeof(CharacterBody).GetProperty("moveSpeed", BindingFlags.Instance | BindingFlags.Public).GetSetMethod(nonPublic: true);
				if (_moveSpeedField == null && _moveSpeedSetter == null)
				{
					Log((LogLevel)2, "悬浮加速:取不到 CharacterBody.moveSpeed 的写入方式,加速不会生效。");
				}
			}
		}

		private static string BodyName(CharacterBody body)
		{
			if (!((Object)(object)body != (Object)null) || string.IsNullOrEmpty(((Object)body).name))
			{
				return "(未知角色)";
			}
			return ((Object)body).name;
		}

		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);
			}
		}
	}
	public static class ArtificerNanoSwarm
	{
		private const string SkillLabel = "攻击纳米枪";

		private const int Freeze2sBit = 256;

		private static ConfigEntry<bool> _enabled;

		private static ConfigEntry<float> _maxDamageMultiplier;

		private static ConfigEntry<bool> _frostEnabled;

		private static ConfigEntry<float> _frostDuration;

		private static ConfigEntry<int> _frostStacks;

		private static ConfigEntry<bool> _updateDescription;

		private static ConfigEntry<string> _projectileName;

		private static ManualLogSource _log;

		private const float FallbackMaxCoefficient = 12f;

		private static float _baseMaxCoefficient = -1f;

		private static bool _damageLogged;

		private static BuffDef _frostDef;

		private static bool _frostDefTried;

		private static bool _frostLogged;

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

		public static void Init(ConfigFile cfg, ManualLogSource logger)
		{
			_log = logger;
			_enabled = cfg.Bind<bool>("NanoSwarm", "Enabled", true, "是否启用「攻击纳米枪」(工匠的替代辅助技能·冰)的这两处改动。");
			_maxDamageMultiplier = cfg.Bind<float>("NanoSwarm", "MaxDamageMultiplier", 1.25f, "充能拉满时的最大伤害倍率 = 原版值 × 这个倍率。\n原版是 1200%,默认 1.25 → 1500%。填 1 = 保持原版。运行期读取。");
			_frostEnabled = cfg.Bind<bool>("NanoSwarm", "FrostOnHit", true, "命中敌人后再给一层霜冻。");
			_frostDuration = cfg.Bind<float>("NanoSwarm", "FrostDuration", 5f, "霜冻持续多少秒。运行期读取。");
			_frostStacks = cfg.Bind<int>("NanoSwarm", "FrostMaxStacks", 3, "霜冻最多叠几层(原版冰霜一发给 6 层 6 秒,这里默认 3 层 5 秒)。运行期读取。");
			_updateDescription = cfg.Bind<bool>("NanoSwarm", "UpdateSkillDescription", true, "把技能描述里的「400%-1200%」改成实际数值(比如「400%-1500%」)。\nfalse = 保持原版文案(游戏里显示的百分比会跟实际伤害对不上)。");
			_projectileName = cfg.Bind<string>("NanoSwarm", "ProjectileName", "MageIceBombProjectile", "纳米枪射弹的对象名(认伤害来源用,不区分大小写)。");
		}

		public static string Summary()
		{
			if (!IsEnabled)
			{
				return "";
			}
			string text = " [攻击纳米枪:最大伤害 " + ((_baseMaxCoefficient > 0f) ? (_baseMaxCoefficient * Multiplier() * 100f).ToString("0") : "1500") + "%";
			if (FrostEnabled())
			{
				text = text + " + 命中给 " + FrostDuration().ToString("0.#") + " 秒 " + FrostStacks() + " 层霜冻";
			}
			return text + "]";
		}

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

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

		private static float FrostDuration()
		{
			if (_frostDuration == null)
			{
				return 5f;
			}
			return _frostDuration.Value;
		}

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

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

		public static float MaxDamagePercent()
		{
			if (!IsEnabled)
			{
				return 1200f;
			}
			return ((_baseMaxCoefficient > 0f) ? _baseMaxCoefficient : 12f) * Multiplier() * 100f;
		}

		public static void Patch(Harmony harmony)
		{
			if (!IsEnabled)
			{
				Log((LogLevel)16, "攻击纳米枪:按配置保持原版,不挂任何补丁。");
				return;
			}
			PatchOne(harmony, typeof(BaseThrowBombState), "Fire", "ApplyMaxDamagePrefix", "抬高最大伤害倍率", asPrefix: true);
			PatchOne(harmony, typeof(GlobalEventManager), "OnHitEnemy", "OnHitEnemyPostfix", "命中后上霜冻");
		}

		private static void PatchOne(Harmony harmony, Type targetType, string methodName, string patchName, string what, bool asPrefix = false)
		{
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Expected O, but got Unknown
			MethodInfo methodInfo = AccessTools.Method(targetType, methodName, (Type[])null, (Type[])null);
			if (methodInfo == null)
			{
				Log((LogLevel)2, "攻击纳米枪:取不到 " + targetType.Name + "." + methodName + "," + what + "不会生效。");
				return;
			}
			try
			{
				HarmonyMethod val = new HarmonyMethod(AccessTools.Method(typeof(ArtificerNanoSwarm), patchName, (Type[])null, (Type[])null));
				harmony.Patch((MethodBase)methodInfo, asPrefix ? val : null, asPrefix ? null : val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				Log((LogLevel)16, "补丁已挂载:" + targetType.Name + "." + methodName + (asPrefix ? " <- " : " -> ") + patchName + "(攻击纳米枪 · " + what + ")");
			}
			catch (Exception ex)
			{
				Log((LogLevel)2, "攻击纳米枪补丁失败(" + what + " 不会生效)—— " + ex.GetType().Name + " " + ex.Message);
			}
		}

		public static void ApplyDescription(string language)
		{
			if (!IsEnabled || !UpdateDescription())
			{
				return;
			}
			if (string.IsNullOrEmpty(language))
			{
				Log((LogLevel)4, "攻击纳米枪:语言系统还没就绪,跳过文案更新。");
				return;
			}
			try
			{
				string text = Language.GetString("MAGE_SECONDARY_ICE_DESCRIPTION");
				if (string.IsNullOrEmpty(text))
				{
					Log((LogLevel)4, "攻击纳米枪:读不到原版技能描述,跳过文案更新。");
					return;
				}
				string text2 = ((_baseMaxCoefficient > 0f) ? (_baseMaxCoefficient * 100f).ToString("0") : "1200") + "%";
				string text3 = ((_baseMaxCoefficient > 0f) ? (_baseMaxCoefficient * Multiplier() * 100f).ToString("0") : "1500") + "%";
				if (text.IndexOf(text2, StringComparison.OrdinalIgnoreCase) >= 0)
				{
					LanguageAPI.Add("MAGE_SECONDARY_ICE_DESCRIPTION", text.Replace(text2, text3), language);
					Log((LogLevel)16, "攻击纳米枪:技能描述已更新为 " + text3 + "(语言 " + language + ")。");
				}
			}
			catch (Exception ex)
			{
				Log((LogLevel)4, "攻击纳米枪:更新技能描述时异常(已忽略)—— " + ex.GetType().Name + " " + ex.Message);
			}
		}

		public static void ApplyMaxDamagePrefix(BaseThrowBombState __instance)
		{
			try
			{
				if (!IsEnabled || __instance == null || !(__instance is ThrowIcebomb))
				{
					return;
				}
				float maxDamageCoefficient = __instance.maxDamageCoefficient;
				if (_baseMaxCoefficient <= 0f)
				{
					_baseMaxCoefficient = maxDamageCoefficient;
				}
				float num = _baseMaxCoefficient * Multiplier();
				if (!(Mathf.Abs(maxDamageCoefficient - num) < 0.0001f))
				{
					__instance.maxDamageCoefficient = num;
					if (!_damageLogged)
					{
						_damageLogged = true;
						Log((LogLevel)16, "攻击纳米枪:最大伤害倍率 " + (maxDamageCoefficient * 100f).ToString("0") + "% → " + (num * 100f).ToString("0") + "%(最小倍率不动,还是原版的 " + (__instance.minDamageCoefficient * 100f).ToString("0") + "%)");
					}
				}
			}
			catch (Exception ex)
			{
				Log((LogLevel)4, "攻击纳米枪:改最大伤害倍率时异常(已忽略)—— " + ex.GetType().Name + " " + ex.Message);
			}
		}

		public static void OnHitEnemyPostfix(object[] __args)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected O, but got Unknown
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Expected O, but got Unknown
			try
			{
				if (!IsEnabled || !FrostEnabled() || __args == null || __args.Length < 2)
				{
					return;
				}
				DamageInfo val = null;
				GameObject val2 = null;
				foreach (object obj in __args)
				{
					if (obj is DamageInfo)
					{
						val = (DamageInfo)obj;
					}
					else if (obj is GameObject)
					{
						val2 = (GameObject)obj;
					}
				}
				if (val == null || (Object)(object)val2 == (Object)null || !IsNanoSwarmHit(val))
				{
					return;
				}
				CharacterBody component = val2.GetComponent<CharacterBody>();
				if ((Object)(object)component == (Object)null || !NetworkServer.active)
				{
					return;
				}
				BuffDef val3 = FrostBuffDef();
				if (!((Object)(object)val3 == (Object)null))
				{
					component.AddTimedBuff(val3, FrostDuration(), FrostStacks());
					if (!_frostLogged)
					{
						_frostLogged = true;
						Log((LogLevel)16, "攻击纳米枪:命中已上霜冻 —— " + FrostDuration().ToString("0.#") + " 秒 / 最多 " + FrostStacks() + " 层,目标 " + ((Object)val2).name);
					}
				}
			}
			catch (Exception ex)
			{
				Log((LogLevel)4, "攻击纳米枪:上霜冻时异常(已忽略)—— " + ex.GetType().Name + " " + ex.Message);
			}
		}

		private static bool IsNanoSwarmHit(DamageInfo damageInfo)
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Invalid comparison between Unknown and I4
			GameObject inflictor = damageInfo.inflictor;
			if ((Object)(object)inflictor == (Object)null || string.IsNullOrEmpty(((Object)inflictor).name))
			{
				return false;
			}
			string value = ((_projectileName != null) ? _projectileName.Value : "MageIceBombProjectile");
			if (string.IsNullOrEmpty(value) || ((Object)inflictor).name.IndexOf(value, StringComparison.OrdinalIgnoreCase) < 0)
			{
				return false;
			}
			return (damageInfo.damageType.damageType & 0x100) > 0;
		}

		private static BuffDef FrostBuffDef()
		{
			if (_frostDefTried)
			{
				return _frostDef;
			}
			_frostDefTried = true;
			string[] array = new string[5] { "RoR2.DLC2Content+Buffs", "RoR2.RoR2Content+Buffs", "DLC2Content+Buffs", "RoR2Content+Buffs", "RoR2.Buffs" };
			foreach (string text in array)
			{
				Type type = AccessTools.TypeByName(text);
				if (type == null)
				{
					continue;
				}
				FieldInfo fieldInfo = AccessTools.Field(type, "Frost");
				if (!(fieldInfo == null))
				{
					object? value = fieldInfo.GetValue(null);
					_frostDef = (BuffDef)((value is BuffDef) ? value : null);
					if ((Object)(object)_frostDef != (Object)null)
					{
						Log((LogLevel)16, "攻击纳米枪:已取到霜冻 buff(" + text + ".Frost = " + ((Object)_frostDef).name + ")。");
						return _frostDef;
					}
				}
			}
			_frostDef = FindBuffByName("frost");
			if ((Object)(object)_frostDef != (Object)null)
			{
				Log((LogLevel)16, "攻击纳米枪:从 BuffCatalog 里找到霜冻 buff(" + ((Object)_frostDef).name + ")。");
				return _frostDef;
			}
			Log((LogLevel)2, "攻击纳米枪:拿不到霜冻 buff,上霜冻这一条不会生效。");
			return null;
		}

		private static BuffDef FindBuffByName(string keyword)
		{
			FieldInfo fieldInfo = AccessTools.Field(typeof(BuffCatalog), "buffDefs");
			if (fieldInfo == null)
			{
				return null;
			}
			if (!(fieldInfo.GetValue(null) is Array array))
			{
				return null;
			}
			foreach (object item in array)
			{
				BuffDef val = (BuffDef)((item is BuffDef) ? item : null);
				if ((Object)(object)val != (Object)null && !string.IsNullOrEmpty(((Object)val).name) && ((Object)val).name.IndexOf(keyword, StringComparison.OrdinalIgnoreCase) >= 0)
				{
					return val;
				}
			}
			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);
			}
		}
	}
	public static class ArtificerSkillText
	{
		private const string PlasmaBoltToken = "MAGE_PRIMARY_LIGHTNING_DESCRIPTION";

		private const string NanoBombToken = "MAGE_SECONDARY_LIGHTNING_DESCRIPTION";

		private const string NanoSwarmToken = "MAGE_SECONDARY_ICE_DESCRIPTION";

		private const string MaxPlaceholder = "{MAX}";

		private static ConfigEntry<bool> _enabled;

		private static ConfigEntry<bool> _onlyChinese;

		private static ConfigEntry<string> _plasmaBoltText;

		private static ConfigEntry<string> _nanoBombText;

		private static ConfigEntry<string> _nanoSwarmText;

		private static ManualLogSource _log;

		private static string _appliedLanguage;

		public static void Init(ConfigFile cfg, ManualLogSource logger)
		{
			_log = logger;
			_enabled = cfg.Bind<bool>("SkillText", "Enabled", true, "是否改写工匠三个技能在游戏里显示的技能描述。false = 全部保持原版文案。");
			_onlyChinese = cfg.Bind<bool>("SkillText", "OnlyChinese", true, "只在游戏语言是中文时改写。false = 不管什么语言都套用下面这几条中文文案。");
			_plasmaBoltText = cfg.Bind<string>("SkillText", "PlasmaBoltText", "发射一道能量矢,造成<style=cIsDamage>280%的伤害</style>并<style=cIsDamage>产生连锁闪电</style>。最多发射4次。", "等离子弹的技能描述。留空 = 保持原版。可写 \\n 换行,也保留 <style=cIsDamage> 这类原版富文本标记。");
			_nanoBombText = cfg.Bind<string>("SkillText", "NanoBombText", "<style=cIsDamage>眩晕</style>。发射一颗会<style=cIsDamage>产生连锁闪电</style>的纳米炸弹,根据充能造成<style=cIsDamage>400%-2000%</style>的伤害。", "充能完毕的纳米炸弹的技能描述。留空 = 保持原版。");
			_nanoSwarmText = cfg.Bind<string>("SkillText", "NanoSwarmText", "<style=cIsUtility>霜冻</style>。<style=cIsUtility>冰冻</style>。使用拥有<style=cIsDamage>穿透</style>效果的纳米枪发动攻击,根据充能造成<style=cIsDamage>400%-{MAX}%</style>的伤害。", "攻击纳米枪的技能描述。留空 = 保持原版。\n{MAX} 会自动换成实际最大伤害倍率(默认 1500,跟着 NanoSwarm.MaxDamageMultiplier 走)。");
		}

		public 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;
		}

		public static void Tick()
		{
			if (!Enabled())
			{
				return;
			}
			string text = CurrentLanguage();
			if (string.IsNullOrEmpty(text) || string.Equals(_appliedLanguage, text, StringComparison.Ordinal))
			{
				return;
			}
			_appliedLanguage = text;
			try
			{
				if (OnlyChinese() && !IsChinese(text))
				{
					Log((LogLevel)16, "技能文案:当前语言是 " + text + "(不是中文),按配置跳过改写。");
					return;
				}
				Apply("MAGE_PRIMARY_LIGHTNING_DESCRIPTION", Text(_plasmaBoltText, null), "等离子弹", text);
				Apply("MAGE_SECONDARY_LIGHTNING_DESCRIPTION", Text(_nanoBombText, null), "充能完毕的纳米炸弹", text);
				Apply("MAGE_SECONDARY_ICE_DESCRIPTION", Text(_nanoSwarmText, "{MAX}"), "攻击纳米枪", text);
			}
			catch (Exception ex)
			{
				Log((LogLevel)4, "技能文案:改写技能描述时异常(已忽略)—— " + ex.GetType().Name + " " + ex.Message);
			}
		}

		private static void Apply(string token, string text, string label, string language)
		{
			if (string.IsNullOrEmpty(text))
			{
				Log((LogLevel)16, "技能文案:" + label + " 的文案是空的,保持原版。");
				return;
			}
			LanguageAPI.Add(token, text, language);
			string text2 = ReadBack(token, text);
			Log((LogLevel)16, "技能文案:" + label + "(" + token + ",语言 " + language + ")已改为 —— " + Plain(text) + (string.Equals(text2, text, StringComparison.Ordinal) ? "" : (" ⚠\ufe0f 回读不一致,实际生效的是:" + Plain(text2))));
		}

		private static string ReadBack(string token, string expected)
		{
			try
			{
				return Language.GetString(token) ?? expected;
			}
			catch (Exception)
			{
				return expected;
			}
		}

		private static string Text(ConfigEntry<string> entry, string placeholder)
		{
			if (entry == null)
			{
				return null;
			}
			string value = entry.Value;
			if (string.IsNullOrEmpty(value))
			{
				return null;
			}
			value = value.Replace("\\n", "\n");
			if (!string.IsNullOrEmpty(placeholder) && value.IndexOf(placeholder, StringComparison.Ordinal) >= 0)
			{
				value = value.Replace(placeholder, MaxDamagePercent().ToString("0"));
			}
			return value;
		}

		private static float MaxDamagePercent()
		{
			float num = ArtificerNanoSwarm.MaxDamagePercent();
			if (!(num > 0f))
			{
				return 1500f;
			}
			return num;
		}

		private static string Plain(string text)
		{
			string text2 = text.Replace("\n", " ");
			while (true)
			{
				int num = text2.IndexOf("<", StringComparison.Ordinal);
				if (num < 0)
				{
					break;
				}
				int num2 = text2.IndexOf(">", num, StringComparison.Ordinal);
				if (num2 < 0)
				{
					break;
				}
				text2 = text2.Substring(0, num) + text2.Substring(num2 + 1);
			}
			return text2;
		}

		private static bool IsChinese(string languageName)
		{
			if (string.IsNullOrEmpty(languageName))
			{
				return false;
			}
			if (languageName.IndexOf("zh", StringComparison.OrdinalIgnoreCase) < 0 && languageName.IndexOf("CN", StringComparison.OrdinalIgnoreCase) < 0)
			{
				return languageName.IndexOf("Chinese", StringComparison.OrdinalIgnoreCase) >= 0;
			}
			return true;
		}

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

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

		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.sparkleartificertweaks", "SparkleArtificerTweaks", "1.10.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class SparkleArtificerTweaksPlugin : BaseUnityPlugin
	{
		public const string PluginGUID = "com.sparkletwilight.sparkleartificertweaks";

		public const string PluginName = "SparkleArtificerTweaks";

		public const string PluginVersion = "1.10.0";

		private bool _descriptionApplied;

		public void Awake()
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Expected O, but got Unknown
			ArtificerHoverSpeed.Init(((BaseUnityPlugin)this).Config, ((BaseUnityPlugin)this).Logger);
			ArtificerChainLightning.Init(((BaseUnityPlugin)this).Config, ((BaseUnityPlugin)this).Logger);
			ArtificerNanoSwarm.Init(((BaseUnityPlugin)this).Config, ((BaseUnityPlugin)this).Logger);
			ArtificerSkillText.Init(((BaseUnityPlugin)this).Config, ((BaseUnityPlugin)this).Logger);
			ArtificerFlamethrower.Init(((BaseUnityPlugin)this).Config, ((BaseUnityPlugin)this).Logger);
			Harmony harmony = new Harmony("com.sparkletwilight.sparkleartificertweaks");
			SafePatch("悬浮移速", delegate
			{
				ArtificerHoverSpeed.Patch(harmony);
			});
			SafePatch("连锁闪电", delegate
			{
				ArtificerChainLightning.Patch(harmony);
			});
			SafePatch("攻击纳米枪", delegate
			{
				ArtificerNanoSwarm.Patch(harmony);
			});
			SafePatch("火焰喷射器", delegate
			{
				ArtificerFlamethrower.Patch(harmony);
			});
			((BaseUnityPlugin)this).Logger.LogInfo((object)("SparkleArtificerTweaks v1.10.0 已加载。" + ArtificerHoverSpeed.Summary() + ArtificerChainLightning.Summary() + ArtificerFlamethrower.Summary()));
		}

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

		public void Update()
		{
			ArtificerHoverSpeed.Tick();
			if (!_descriptionApplied)
			{
				string text = ArtificerSkillText.CurrentLanguage();
				if (!string.IsNullOrEmpty(text))
				{
					_descriptionApplied = true;
					ArtificerNanoSwarm.ApplyDescription(text);
					((BaseUnityPlugin)this).Logger.LogInfo((object)("SparkleArtificerTweaks:" + ArtificerHoverSpeed.Summary() + ArtificerChainLightning.Summary() + ArtificerNanoSwarm.Summary() + ArtificerFlamethrower.Summary()));
				}
			}
			ArtificerSkillText.Tick();
		}
	}
}