Decompiled source of SparkleRailgunnerTweaks v1.3.0

plugins/SparkleRailgunnerTweaks.dll

Decompiled 19 hours ago
using System;
using System.Collections.Generic;
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 HarmonyLib;
using Microsoft.CodeAnalysis;
using R2API;
using RoR2;
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("SparkleRailgunnerTweaks")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.3.0.0")]
[assembly: AssemblyInformationalVersion("1.3.0")]
[assembly: AssemblyProduct("SparkleRailgunnerTweaks")]
[assembly: AssemblyTitle("SparkleRailgunnerTweaks")]
[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 SparkleRailgunnerTweaks
{
	public static class HH44AttackSpeed
	{
		private const string FireSnipeLightTypeName = "EntityStates.Railgunner.Weapon.FireSnipeLight";

		private const string GenericBulletBaseStateTypeName = "EntityStates.GenericBulletBaseState";

		private static ConfigEntry<bool> _enabled;

		private static ConfigEntry<float> _multiplier;

		private static ConfigEntry<bool> _scaleBonusOnly;

		private static ManualLogSource _log;

		private static Type _fireSnipeLightType;

		private static bool _typeResolveFailedLogged;

		private static FieldInfo _attackSpeedField;

		private static FieldInfo _durationField;

		private static bool _fieldsResolveFailedLogged;

		private static bool _firstShotLogged;

		private static float _lastLogAt = -999f;

		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>("HH44", "Enabled", true, "是否增强 HH44 的攻击速度收益。false = 保持原版(攻速只按原版公式生效)。");
			_multiplier = cfg.Bind<float>("HH44", "AttackSpeedMultiplier", 1.5f, "HH44 从攻击速度「加成部分」上获得的额外倍率。\n有效攻速 = 1 + 倍率 × (attackSpeedStat − 1):\n  基础间隔 0.5 秒;+100% 攻速时有效攻速 1 + 1.5×1 = 2.5,间隔 0.2 秒(原版 0.25 秒);\n  +200% 攻速时有效攻速 4,间隔 0.125 秒(原版 0.167 秒);0 攻速加成时与原版一致。");
			_scaleBonusOnly = cfg.Bind<bool>("HH44", "ScaleBonusOnly", true, "true = 只放大「攻速加成部分」:有效攻速 = 1 + 倍率 × (attackSpeedStat − 1)\n(+100% 攻速时有效攻速 2.5,间隔 0.2 秒;0 攻速加成时与原版一致)。\nfalse = 直接把 attackSpeedStat 整体乘倍率(间隔恒为原版的 1 / 倍率,\n  +100% 攻速时间隔 0.167 秒,但 0 攻速加成时也比原版快 50%)。");
		}

		public static string Summary()
		{
			if (_enabled == null || !_enabled.Value)
			{
				return " [HH44:原版未改动]";
			}
			float num = ((_multiplier == null) ? 1.5f : _multiplier.Value);
			bool flag = _scaleBonusOnly != null && _scaleBonusOnly.Value;
			return " [HH44:攻速收益×" + num.ToString("0.##") + (flag ? "(仅加成部分)" : "(整体)") + "]";
		}

		public static void Patch(Harmony harmony)
		{
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Expected O, but got Unknown
			_fireSnipeLightType = AccessTools.TypeByName("EntityStates.Railgunner.Weapon.FireSnipeLight");
			if (_fireSnipeLightType == null)
			{
				Log((LogLevel)2, "HH44 补丁失败:找不到状态类型 EntityStates.Railgunner.Weapon.FireSnipeLight。");
			}
			Type type = AccessTools.TypeByName("EntityStates.GenericBulletBaseState");
			MethodInfo methodInfo = ((type == null) ? null : AccessTools.Method(type, "OnEnter", (Type[])null, (Type[])null));
			if (methodInfo == null)
			{
				Log((LogLevel)2, "HH44 补丁失败:找不到 EntityStates.GenericBulletBaseState.OnEnter。");
				return;
			}
			harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(HH44AttackSpeed), "OnEnterPostfix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			Log((LogLevel)16, "补丁已挂载:EntityStates.GenericBulletBaseState.OnEnter <- OnEnterPostfix(仅对 EntityStates.Railgunner.Weapon.FireSnipeLight 生效,重写 duration)");
		}

		public static void OnEnterPostfix(GenericBulletBaseState __instance)
		{
			try
			{
				if (_enabled == null || !_enabled.Value || __instance == null)
				{
					return;
				}
				if (_fireSnipeLightType == null)
				{
					_fireSnipeLightType = AccessTools.TypeByName("EntityStates.Railgunner.Weapon.FireSnipeLight");
					if (_fireSnipeLightType == null)
					{
						if (!_typeResolveFailedLogged)
						{
							_typeResolveFailedLogged = true;
							Log((LogLevel)4, "HH44 未生效:解析不出 EntityStates.Railgunner.Weapon.FireSnipeLight。");
						}
						return;
					}
				}
				if (((object)__instance).GetType() != _fireSnipeLightType)
				{
					return;
				}
				float num = ((_multiplier == null) ? 1.5f : _multiplier.Value);
				if (!(num <= 0f) && EnsureFields())
				{
					float baseDuration = __instance.baseDuration;
					float num2 = (float)_attackSpeedField.GetValue(__instance);
					if (num2 <= 0f)
					{
						num2 = 1f;
					}
					bool flag = _scaleBonusOnly != null && _scaleBonusOnly.Value;
					float num3 = ((!flag) ? (num2 * num) : ((num2 > 1f) ? (1f + num * (num2 - 1f)) : num2));
					if (num3 < 0.01f)
					{
						num3 = 0.01f;
					}
					float num4 = baseDuration / num2;
					float num5 = baseDuration / num3;
					_durationField.SetValue(__instance, num5);
					if (!_firstShotLogged)
					{
						_firstShotLogged = true;
						Log((LogLevel)16, "HH44 攻速改写已生效:基础间隔 " + baseDuration.ToString("0.###") + "s / 攻速 " + num2.ToString("0.##") + " → 原版 " + num4.ToString("0.###") + "s → 实际 " + num5.ToString("0.###") + "s" + (flag ? "(仅放大加成部分)" : ("(整体×" + num.ToString("0.##") + ")")) + "。");
					}
					else
					{
						LogThrottled("HH44 开火:攻速 " + num2.ToString("0.##") + " → 间隔 " + num5.ToString("0.###") + "s(原版 " + num4.ToString("0.###") + "s)");
					}
				}
			}
			catch (Exception ex)
			{
				Log((LogLevel)4, "HH44 攻速改写异常(已忽略):" + ex.GetType().Name + " " + ex.Message);
			}
		}

		private static bool EnsureFields()
		{
			if (_attackSpeedField != null && _durationField != null)
			{
				return true;
			}
			Type type = AccessTools.TypeByName("EntityStates.GenericBulletBaseState");
			if (type == null)
			{
				return false;
			}
			_attackSpeedField = FindField(type, "attackSpeedStat");
			_durationField = FindField(type, "duration");
			if (_attackSpeedField == null || _durationField == null)
			{
				if (!_fieldsResolveFailedLogged)
				{
					_fieldsResolveFailedLogged = true;
					Log((LogLevel)2, "HH44 未生效:取不到字段 attackSpeedStat / duration(attackSpeedStat=" + ((_attackSpeedField == null) ? "缺失" : "OK") + ",duration=" + ((_durationField == null) ? "缺失" : "OK") + ")。");
				}
				return false;
			}
			return true;
		}

		private static FieldInfo FindField(Type type, string name)
		{
			Type type2 = type;
			while (type2 != null)
			{
				FieldInfo field = type2.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (field != null)
				{
					return field;
				}
				type2 = type2.BaseType;
			}
			return null;
		}

		private static void LogThrottled(string message)
		{
			if (!(Time.time - _lastLogAt < 3f))
			{
				_lastLogAt = Time.time;
				Log((LogLevel)16, 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);
			}
		}
	}
	public static class PolarFieldSelf
	{
		private sealed class ActiveField
		{
			public GameObject gameObject;

			public CharacterBody owner;

			public float expireTime;
		}

		private const string BlindingStateTypeName = "EntityStates.Railgunner.Weapon.FireMineBlinding";

		private const string RailgunnerBodyName = "RailgunnerBody";

		private const string BlindingSkillNameToken = "RAILGUNNER_UTILITY_ALT_NAME";

		private const string FieldPrefabName = "RailgunnerMineAltDetonated";

		private static ConfigEntry<bool> _enabled;

		private static ConfigEntry<bool> _followBody;

		private static ConfigEntry<float> _duration;

		private static ConfigEntry<float> _radiusMultiplier;

		private static ConfigEntry<float> _projectileSlowMultiplier;

		private static ConfigEntry<float> _cooldown;

		private static ConfigEntry<float> _verticalOffset;

		private static ConfigEntry<bool> _spawnEffect;

		private static ManualLogSource _log;

		private static GameObject _fieldPrefab;

		private static GameObject _effectPrefab;

		private static bool _resolveFailedLogged;

		private static bool _cooldownPatched;

		private static readonly List<ActiveField> _fields = new List<ActiveField>();

		private static bool _spawnLogged;

		private static float _lastLogAt = -999f;

		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>("PolarField", "Enabled", true, "是否启用「极性力场装置」改造。true = 不再扔出装置,改为以自身为中心产生力场;\nfalse = 保持原版(装置照常扔出)。");
			_followBody = cfg.Bind<bool>("PolarField", "FollowBody", true, "力场是否跟着磁轨炮手移动。true = 力场持续以你为中心;false = 留在释放瞬间的位置。");
			_duration = cfg.Bind<float>("PolarField", "Duration", 15f, "力场的持续时间(秒)。10 = 与原版一致(原版 BuffWard 的 expireDuration 就是 10 秒);\n15 = 延长到 15 秒。注意:力场对象是原版 BuffWard 到点自己销毁的,这里会同步改 BuffWard.expireDuration。");
			_radiusMultiplier = cfg.Bind<float>("PolarField", "RadiusMultiplier", 1.5f, "力场半径倍率。1 = 与原版一致(BuffWard 与球形触发器都是 15 米);1.5 = 扩大 50%(22.5 米)。");
			_projectileSlowMultiplier = cfg.Bind<float>("PolarField", "ProjectileSlowMultiplier", 2f, "力场对敌方射弹的减速强度倍率(越大越慢)。\n原版射弹在力场里只剩 10% 速度(slowDownCoefficient = 0.1);2 = 减速效果翻倍(只剩 5%,即 0.05)。");
			_cooldown = cfg.Bind<float>("PolarField", "Cooldown", 24f, "「极性力场装置」的基础冷却(秒),改的是 SkillDef.baseRechargeInterval。\n12 = 与原版一致;24 = 翻倍。冷却类道具会在新基准上继续结算。");
			_verticalOffset = cfg.Bind<float>("PolarField", "VerticalOffset", 0f, "力场中心相对角色脚下位置的高度偏移(米)。0 = 与原版效果相同(贴着脚)。");
			_spawnEffect = cfg.Bind<bool>("PolarField", "SpawnEffect", true, "生成力场时是否同时播放原版的力场特效(RailgunnerMineExplosionAlt)。");
		}

		public static string Summary()
		{
			if (_enabled == null || !_enabled.Value)
			{
				return " [极性力场:原版未改动]";
			}
			float num = ((_duration == null) ? 15f : _duration.Value);
			float num2 = ((_radiusMultiplier == null) ? 1f : _radiusMultiplier.Value);
			float num3 = ((_projectileSlowMultiplier == null) ? 1f : _projectileSlowMultiplier.Value);
			float num4 = ((_cooldown == null) ? 12f : _cooldown.Value);
			bool flag = _followBody == null || _followBody.Value;
			return " [极性力场:" + (flag ? "跟随角色" : "固定在释放点") + "/" + num.ToString("0.##") + "秒/半径×" + num2.ToString("0.##") + "/射弹减速×" + num3.ToString("0.##") + "/冷却" + num4.ToString("0.##") + "秒]";
		}

		public static void Patch(Harmony harmony)
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Expected O, but got Unknown
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Expected O, but got Unknown
			MethodInfo methodInfo = null;
			Type type = AccessTools.TypeByName("EntityStates.Railgunner.Weapon.FireMineBlinding");
			if (type != null)
			{
				methodInfo = AccessTools.Method(type, "ModifyProjectileInfo", (Type[])null, (Type[])null);
			}
			if (methodInfo == null)
			{
				Log((LogLevel)2, "「极性力场」补丁失败:找不到 EntityStates.Railgunner.Weapon.FireMineBlinding.ModifyProjectileInfo(游戏可能还没升到有 DLC1 的版本)。");
			}
			else
			{
				harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(PolarFieldSelf), "ModifyProjectilePostfix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				Log((LogLevel)16, "补丁已挂载:EntityStates.Railgunner.Weapon.FireMineBlinding.ModifyProjectileInfo <- ModifyProjectilePostfix(把投掷物换成力场本体、出生点改为自身)");
			}
			MethodInfo methodInfo2 = AccessTools.Method(typeof(ProjectileManager), "InitializeProjectile", (Type[])null, (Type[])null);
			if (methodInfo2 == null)
			{
				Log((LogLevel)2, "「极性力场」补丁失败:找不到 ProjectileManager.InitializeProjectile。");
				return;
			}
			harmony.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(PolarFieldSelf), "InitializeProjectilePostfix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			Log((LogLevel)16, "补丁已挂载:ProjectileManager.InitializeProjectile <- InitializeProjectilePostfix(登记生成的力场实例)");
		}

		public static void ModifyProjectilePostfix(ref FireProjectileInfo __0)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (_enabled == null || !_enabled.Value)
				{
					return;
				}
				GameObject val = ResolveFieldPrefabs(__0.projectilePrefab);
				if (!((Object)(object)val == (Object)null))
				{
					__0.projectilePrefab = val;
					__0.rotation = Quaternion.identity;
					__0.damage = 0f;
					__0.force = 0f;
					CharacterBody val2 = OwnerBody(__0.owner);
					if ((Object)(object)val2 != (Object)null)
					{
						float num = ((_verticalOffset == null) ? 0f : _verticalOffset.Value);
						__0.position = val2.corePosition + new Vector3(0f, num, 0f);
					}
				}
			}
			catch (Exception ex)
			{
				Log((LogLevel)4, "「极性力场」ModifyProjectileInfo 后处理异常(已忽略):" + ex.GetType().Name + " " + ex.Message);
			}
		}

		public static void InitializeProjectilePostfix(ProjectileController projectileController, FireProjectileInfo fireProjectileInfo)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (_enabled == null || !_enabled.Value || (Object)(object)projectileController == (Object)null || (Object)(object)_fieldPrefab == (Object)null || fireProjectileInfo.projectilePrefab != _fieldPrefab)
				{
					return;
				}
				GameObject gameObject = ((Component)projectileController).gameObject;
				if (!((Object)(object)gameObject == (Object)null))
				{
					CharacterBody owner = OwnerBody(fireProjectileInfo.owner);
					RemoveFieldsOfOwner(owner);
					float num = ((_duration == null) ? 15f : _duration.Value);
					ApplyFieldTuning(gameObject, num);
					if (_spawnEffect == null || _spawnEffect.Value)
					{
						SpawnEffect(gameObject);
					}
					ActiveField item = new ActiveField
					{
						gameObject = gameObject,
						owner = owner,
						expireTime = Time.time + num
					};
					_fields.Add(item);
					if (!_spawnLogged)
					{
						_spawnLogged = true;
						Log((LogLevel)16, "极性力场已生成 半径 " + CurrentRadius(gameObject).ToString("0.0") + " 持续 " + num.ToString("0.##") + " 秒 射弹速度倍率 " + CurrentSlowCoefficient(gameObject).ToString("0.###") + ((_followBody == null || _followBody.Value) ? ",跟随角色" : ",固定在释放点") + "(authority=" + NetworkServer.active + ")。");
					}
					else
					{
						LogThrottled("极性力场已生成(当前有效数量 " + CountAlive() + ")。");
					}
				}
			}
			catch (Exception ex)
			{
				Log((LogLevel)4, "「极性力场」InitializeProjectile 后处理异常(已忽略):" + ex.GetType().Name + " " + ex.Message);
			}
		}

		public static void FollowFields()
		{
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (_enabled == null || !_enabled.Value || _fields.Count == 0)
				{
					return;
				}
				bool flag = _followBody == null || _followBody.Value;
				bool active = NetworkServer.active;
				float num = ((_verticalOffset == null) ? 0f : _verticalOffset.Value);
				for (int num2 = _fields.Count - 1; num2 >= 0; num2--)
				{
					ActiveField activeField = _fields[num2];
					if (activeField == null || (Object)(object)activeField.gameObject == (Object)null)
					{
						_fields.RemoveAt(num2);
					}
					else if (Time.time >= activeField.expireTime)
					{
						DestroyField(activeField.gameObject);
						_fields.RemoveAt(num2);
					}
					else if (flag && active)
					{
						CharacterBody owner = activeField.owner;
						if ((Object)(object)owner != (Object)null && (Object)(object)owner.healthComponent != (Object)null && owner.healthComponent.alive)
						{
							activeField.gameObject.transform.position = owner.corePosition + new Vector3(0f, num, 0f);
						}
					}
				}
			}
			catch (Exception ex)
			{
				Log((LogLevel)4, "「极性力场」跟随刷新异常(已忽略):" + ex.GetType().Name + " " + ex.Message);
			}
		}

		private static GameObject ResolveFieldPrefabs(GameObject thrownPrefab)
		{
			if ((Object)(object)_fieldPrefab != (Object)null)
			{
				return _fieldPrefab;
			}
			if ((Object)(object)thrownPrefab != (Object)null)
			{
				ProjectileImpactExplosion component = thrownPrefab.GetComponent<ProjectileImpactExplosion>();
				if ((Object)(object)component != (Object)null)
				{
					if ((Object)(object)((ProjectileExplosion)component).childrenProjectilePrefab != (Object)null)
					{
						_fieldPrefab = ((ProjectileExplosion)component).childrenProjectilePrefab;
					}
					if ((Object)(object)((ProjectileExplosion)component).explosionEffect != (Object)null)
					{
						_effectPrefab = ((ProjectileExplosion)component).explosionEffect;
					}
				}
			}
			if ((Object)(object)_fieldPrefab == (Object)null)
			{
				_fieldPrefab = FindProjectilePrefabByName("RailgunnerMineAltDetonated");
			}
			if ((Object)(object)_fieldPrefab != (Object)null)
			{
				Log((LogLevel)16, "力场本体已定位:" + ((Object)_fieldPrefab).name + "(来自 " + (((Object)(object)thrownPrefab == (Object)null) ? "null" : ((Object)thrownPrefab).name) + "),特效:" + (((Object)(object)_effectPrefab == (Object)null) ? "无" : ((Object)_effectPrefab).name) + "。");
			}
			else if (!_resolveFailedLogged)
			{
				_resolveFailedLogged = true;
				Log((LogLevel)4, "力场本体定位失败,本次技能按原版处理(仍会扔出装置)。");
			}
			return _fieldPrefab;
		}

		private static GameObject FindProjectilePrefabByName(string keyword)
		{
			try
			{
				FieldInfo fieldInfo = AccessTools.Field(typeof(ProjectileCatalog), "projectilePrefabs");
				GameObject[] array = ((fieldInfo == null) ? null : (fieldInfo.GetValue(null) as GameObject[]));
				if (array == null)
				{
					return null;
				}
				foreach (GameObject val in array)
				{
					if ((Object)(object)val != (Object)null && ((Object)val).name.IndexOf(keyword, StringComparison.OrdinalIgnoreCase) >= 0)
					{
						return val;
					}
				}
			}
			catch (Exception ex)
			{
				Log((LogLevel)4, "ProjectileCatalog 扫描失败:" + ex.GetType().Name + " " + ex.Message);
			}
			return null;
		}

		private static void ApplyFieldTuning(GameObject go, float duration)
		{
			float num = ((_radiusMultiplier == null) ? 1f : _radiusMultiplier.Value);
			bool flag = Mathf.Abs(num - 1f) > 0.0001f;
			BuffWard component = go.GetComponent<BuffWard>();
			if ((Object)(object)component != (Object)null)
			{
				if (flag)
				{
					component.radius *= num;
				}
				if (Mathf.Abs(component.expireDuration - duration) > 0.0001f)
				{
					component.expireDuration = duration;
				}
			}
			if (flag)
			{
				SphereCollider component2 = go.GetComponent<SphereCollider>();
				if ((Object)(object)component2 != (Object)null)
				{
					component2.radius *= num;
				}
			}
			SlowDownProjectiles component3 = go.GetComponent<SlowDownProjectiles>();
			if (!((Object)(object)component3 != (Object)null))
			{
				return;
			}
			float num2 = ((_projectileSlowMultiplier == null) ? 1f : _projectileSlowMultiplier.Value);
			if (num2 > 0.0001f)
			{
				float num3 = Mathf.Clamp(component3.slowDownCoefficient / num2, 0.01f, 1f);
				if (Mathf.Abs(num3 - component3.slowDownCoefficient) > 0.0001f)
				{
					component3.slowDownCoefficient = num3;
				}
			}
		}

		private static float CurrentRadius(GameObject go)
		{
			BuffWard val = (((Object)(object)go == (Object)null) ? null : go.GetComponent<BuffWard>());
			if (!((Object)(object)val == (Object)null))
			{
				return val.radius;
			}
			return 0f;
		}

		private static float CurrentSlowCoefficient(GameObject go)
		{
			SlowDownProjectiles val = (((Object)(object)go == (Object)null) ? null : go.GetComponent<SlowDownProjectiles>());
			if (!((Object)(object)val == (Object)null))
			{
				return val.slowDownCoefficient;
			}
			return float.NaN;
		}

		public static void TryPatchCooldown()
		{
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			if (_cooldownPatched || _enabled == null || !_enabled.Value)
			{
				return;
			}
			try
			{
				if (!((ResourceAvailability)(ref BodyCatalog.availability)).available)
				{
					return;
				}
				GameObject val = BodyCatalog.FindBodyPrefab("RailgunnerBody");
				if ((Object)(object)val == (Object)null)
				{
					Log((LogLevel)4, "BodyCatalog 里找不到 RailgunnerBody,极性力场冷却未修改。");
					_cooldownPatched = true;
					return;
				}
				SkillLocator component = val.GetComponent<SkillLocator>();
				if ((Object)(object)component == (Object)null || (Object)(object)component.utility == (Object)null)
				{
					Log((LogLevel)2, "RailgunnerBody 上取不到 utility 技能槽,极性力场冷却未修改。");
					_cooldownPatched = true;
					return;
				}
				SkillFamily skillFamily = component.utility.skillFamily;
				if ((Object)(object)skillFamily == (Object)null || skillFamily.variants == null)
				{
					Log((LogLevel)2, "磁轨炮手 utility 技能族为空,极性力场冷却未修改。");
					_cooldownPatched = true;
					return;
				}
				float baseRechargeInterval = ((_cooldown == null) ? 12f : _cooldown.Value);
				bool flag = false;
				Variant[] variants = skillFamily.variants;
				for (int i = 0; i < variants.Length; i++)
				{
					SkillDef skillDef = variants[i].skillDef;
					if (!((Object)(object)skillDef == (Object)null) && IsBlindingSkillDef(skillDef))
					{
						float baseRechargeInterval2 = skillDef.baseRechargeInterval;
						skillDef.baseRechargeInterval = baseRechargeInterval;
						flag = true;
						Log((LogLevel)16, "极性力场冷却:" + baseRechargeInterval2.ToString("0.##") + "s -> " + baseRechargeInterval.ToString("0.##") + "s(SkillDef " + skillDef.skillNameToken + ")");
					}
				}
				if (!flag)
				{
					Log((LogLevel)4, "磁轨炮手 utility 技能族里没匹配到「极性力场装置」,冷却未修改。");
				}
				else
				{
					RefreshLiveBodies();
				}
				_cooldownPatched = true;
			}
			catch (Exception ex)
			{
				_cooldownPatched = true;
				Log((LogLevel)2, "修改极性力场冷却异常(已放弃重试):" + ex.GetType().Name + " " + ex.Message);
			}
		}

		private static bool IsBlindingSkillDef(SkillDef def)
		{
			try
			{
				Type type = AccessTools.TypeByName("EntityStates.Railgunner.Weapon.FireMineBlinding");
				if (type != null && ((SerializableEntityStateType)(ref def.activationState)).stateType == type)
				{
					return true;
				}
				string typeName = ((SerializableEntityStateType)(ref def.activationState)).typeName;
				if (!string.IsNullOrEmpty(typeName) && typeName == "EntityStates.Railgunner.Weapon.FireMineBlinding")
				{
					return true;
				}
			}
			catch (Exception)
			{
			}
			if (!string.IsNullOrEmpty(def.skillNameToken))
			{
				return def.skillNameToken == "RAILGUNNER_UTILITY_ALT_NAME";
			}
			return false;
		}

		private static void RefreshLiveBodies()
		{
			foreach (CharacterBody readOnlyInstances in CharacterBody.readOnlyInstancesList)
			{
				if (!((Object)(object)readOnlyInstances == (Object)null))
				{
					SkillLocator skillLocator = readOnlyInstances.skillLocator;
					if (!((Object)(object)skillLocator == (Object)null) && !((Object)(object)skillLocator.utility == (Object)null))
					{
						skillLocator.utility.RecalculateValues();
					}
				}
			}
		}

		private static void SpawnEffect(GameObject fieldObject)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_effectPrefab == (Object)null) && !((Object)(object)fieldObject == (Object)null))
			{
				GameObject val = Object.Instantiate<GameObject>(_effectPrefab, fieldObject.transform.position, Quaternion.identity);
				float num = ((_radiusMultiplier == null) ? 1f : _radiusMultiplier.Value);
				if (Mathf.Abs(num - 1f) > 0.0001f)
				{
					val.transform.localScale = val.transform.localScale * num;
				}
				if (_followBody == null || _followBody.Value)
				{
					val.transform.SetParent(fieldObject.transform, true);
				}
			}
		}

		private static void DestroyField(GameObject go)
		{
			if (!((Object)(object)go == (Object)null))
			{
				if (NetworkServer.active)
				{
					NetworkServer.Destroy(go);
				}
				else
				{
					Object.Destroy((Object)(object)go);
				}
			}
		}

		private static void RemoveFieldsOfOwner(CharacterBody owner)
		{
			if ((Object)(object)owner == (Object)null)
			{
				return;
			}
			for (int num = _fields.Count - 1; num >= 0; num--)
			{
				ActiveField activeField = _fields[num];
				if (activeField != null && (Object)(object)activeField.gameObject != (Object)null && activeField.owner == owner)
				{
					DestroyField(activeField.gameObject);
					_fields.RemoveAt(num);
				}
			}
		}

		private static int CountAlive()
		{
			int num = 0;
			for (int i = 0; i < _fields.Count; i++)
			{
				if (_fields[i] != null && (Object)(object)_fields[i].gameObject != (Object)null)
				{
					num++;
				}
			}
			return num;
		}

		private static CharacterBody OwnerBody(GameObject owner)
		{
			if (!((Object)(object)owner == (Object)null))
			{
				return owner.GetComponent<CharacterBody>();
			}
			return null;
		}

		private static void LogThrottled(string message)
		{
			if (!(Time.time - _lastLogAt < 3f))
			{
				_lastLogAt = Time.time;
				Log((LogLevel)16, 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);
			}
		}
	}
	public static class SkillDescriptions
	{
		private const string HH44Token = "RAILGUNNER_SECONDARY_ALT_DESCRIPTION";

		private const string FieldToken = "RAILGUNNER_UTILITY_ALT_DESCRIPTION";

		private const string DefaultHH44Zh = "启动你的<style=cIsUtility>近程瞄准镜</style>,高亮显示<style=cIsDamage>弱点</style>,并将你的武器转化为一门可造成<style=cIsDamage>400%伤害</style>的连续磁轨炮。<style=cIsUtility>从攻击速度获得更多收益</style>。";

		private const string DefaultHH44En = "Activate your <style=cIsUtility>short-range scope</style>, highlighting <style=cIsDamage>Weak Points</style> and transforming your weapon into a continuous <style=cIsDamage>400% damage</style> railgun. <style=cIsUtility>Gains increased benefit from attack speed.</style>";

		private const string DefaultFieldZh = "展开一个可使范围内<style=cIsUtility>所有敌人和射弹</style><style=cIsUtility>减速</style>的领域。";

		private const string DefaultFieldEn = "Deploy a field that <style=cIsUtility>slows down</style> all <style=cIsUtility>enemies and projectiles</style> within its radius.";

		private static ConfigEntry<bool> _enabled;

		private static ConfigEntry<string> _hh44Text;

		private static ConfigEntry<string> _fieldText;

		private static ManualLogSource _log;

		public static void Init(ConfigFile cfg, ManualLogSource logger)
		{
			_log = logger;
			_enabled = cfg.Bind<bool>("Descriptions", "Enabled", true, "是否改写技能说明文字。false = 完全保留原版文案。");
			_hh44Text = cfg.Bind<string>("Descriptions", "HH44Description", "启动你的<style=cIsUtility>近程瞄准镜</style>,高亮显示<style=cIsDamage>弱点</style>,并将你的武器转化为一门可造成<style=cIsDamage>400%伤害</style>的连续磁轨炮。<style=cIsUtility>从攻击速度获得更多收益</style>。", "「代号HH44神射手」(替代 M2)的说明文字。留空 = 不改写。\n支持 <style=cIsUtility> / <style=cIsDamage> 之类的富文本标签。");
			_fieldText = cfg.Bind<string>("Descriptions", "PolarFieldDescription", "展开一个可使范围内<style=cIsUtility>所有敌人和射弹</style><style=cIsUtility>减速</style>的领域。", "「极性力场装置」(替代辅助技能)的说明文字。留空 = 不改写。");
		}

		public static void Apply(bool hh44Enabled, bool polarFieldEnabled)
		{
			try
			{
				if (_enabled == null || !_enabled.Value)
				{
					Log((LogLevel)16, "技能说明:按配置保留原版文案。");
					return;
				}
				if (hh44Enabled)
				{
					string text = ((_hh44Text == null) ? "启动你的<style=cIsUtility>近程瞄准镜</style>,高亮显示<style=cIsDamage>弱点</style>,并将你的武器转化为一门可造成<style=cIsDamage>400%伤害</style>的连续磁轨炮。<style=cIsUtility>从攻击速度获得更多收益</style>。" : _hh44Text.Value);
					if (!string.IsNullOrEmpty(text))
					{
						LanguageAPI.Add("RAILGUNNER_SECONDARY_ALT_DESCRIPTION", text, "zh-CN");
						LanguageAPI.Add("RAILGUNNER_SECONDARY_ALT_DESCRIPTION", "Activate your <style=cIsUtility>short-range scope</style>, highlighting <style=cIsDamage>Weak Points</style> and transforming your weapon into a continuous <style=cIsDamage>400% damage</style> railgun. <style=cIsUtility>Gains increased benefit from attack speed.</style>", "en");
						Log((LogLevel)16, "技能说明已改写:RAILGUNNER_SECONDARY_ALT_DESCRIPTION(代号HH44神射手)。");
					}
				}
				if (polarFieldEnabled)
				{
					string text2 = ((_fieldText == null) ? "展开一个可使范围内<style=cIsUtility>所有敌人和射弹</style><style=cIsUtility>减速</style>的领域。" : _fieldText.Value);
					if (!string.IsNullOrEmpty(text2))
					{
						LanguageAPI.Add("RAILGUNNER_UTILITY_ALT_DESCRIPTION", text2, "zh-CN");
						LanguageAPI.Add("RAILGUNNER_UTILITY_ALT_DESCRIPTION", "Deploy a field that <style=cIsUtility>slows down</style> all <style=cIsUtility>enemies and projectiles</style> within its radius.", "en");
						Log((LogLevel)16, "技能说明已改写:RAILGUNNER_UTILITY_ALT_DESCRIPTION(极性力场装置)。");
					}
				}
			}
			catch (Exception ex)
			{
				Log((LogLevel)4, "技能说明改写失败(已忽略):" + 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.sparklerailgunnertweaks", "SparkleRailgunnerTweaks", "1.3.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class SparkleRailgunnerTweaksPlugin : BaseUnityPlugin
	{
		public const string PluginGUID = "com.sparkletwilight.sparklerailgunnertweaks";

		public const string PluginName = "SparkleRailgunnerTweaks";

		public const string PluginVersion = "1.3.0";

		public void Awake()
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Expected O, but got Unknown
			//IL_0057: Expected O, but got Unknown
			PolarFieldSelf.Init(((BaseUnityPlugin)this).Config, ((BaseUnityPlugin)this).Logger);
			HH44AttackSpeed.Init(((BaseUnityPlugin)this).Config, ((BaseUnityPlugin)this).Logger);
			SkillDescriptions.Init(((BaseUnityPlugin)this).Config, ((BaseUnityPlugin)this).Logger);
			SkillDescriptions.Apply(HH44AttackSpeed.IsEnabled, PolarFieldSelf.IsEnabled);
			Harmony val = new Harmony("com.sparkletwilight.sparklerailgunnertweaks");
			PolarFieldSelf.Patch(val);
			HH44AttackSpeed.Patch(val);
			((BaseUnityPlugin)this).Logger.LogInfo((object)("SparkleRailgunnerTweaks v1.3.0 已加载。" + PolarFieldSelf.Summary() + HH44AttackSpeed.Summary()));
		}

		public void Update()
		{
			PolarFieldSelf.TryPatchCooldown();
		}

		public void FixedUpdate()
		{
			PolarFieldSelf.FollowFields();
		}
	}
}