Decompiled source of SparkleCommandoTweaks v1.11.1

plugins/SparkleCommandoTweaks.dll

Decompiled 2 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using EntityStates;
using EntityStates.Commando.CommandoWeapon;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using R2API;
using RoR2;
using RoR2.Projectile;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("SparkleCommandoTweaks")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.11.1.0")]
[assembly: AssemblyInformationalVersion("1.11.1")]
[assembly: AssemblyProduct("SparkleCommandoTweaks")]
[assembly: AssemblyTitle("SparkleCommandoTweaks")]
[assembly: AssemblyVersion("1.11.1.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 SparkleCommandoTweaks
{
	internal static class CommandoBarrageTweaks
	{
		private const int VanillaBulletCount = 6;

		private static ManualLogSource _log;

		private static ConfigEntry<bool> _enabled;

		private static ConfigEntry<float> _multiplier;

		private static ConfigEntry<int> _bulletCount;

		private static FieldInfo _baseBulletCountField;

		private static bool _bulletCountLogged;

		private static int _patchedCount;

		internal static void Init(ConfigFile config, ManualLogSource log)
		{
			_log = log;
			_enabled = config.Bind<bool>("Special.火力压制", "Enabled", true, "是否让「火力压制」从攻速加成上额外获得收益(AttackSpeedGainMultiplier)并调整子弹数。");
			_multiplier = config.Bind<float>("Special.火力压制", "AttackSpeedGainMultiplier", 1.5f, "攻速收益倍率。1.5 = +10% 攻击速度起到原版 +15% 的效果(有效攻速 = 1 + 倍率 × (攻速加成));1 = 原版。");
			_bulletCount = config.Bind<int>("Special.火力压制", "BulletCount", 7, "火力压制一次射出的子弹数基准(原版 6)。实际发射数 = 子弹数 × 攻击速度(原版行为:射击次数随攻速增加)。");
		}

		internal static void Patch(Harmony harmony)
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Expected O, but got Unknown
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Expected O, but got Unknown
			MethodInfo methodInfo = AccessTools.Method(typeof(FireBarrage), "OnEnter", (Type[])null, (Type[])null);
			if (methodInfo == null)
			{
				_log.LogError((object)"找不到 FireBarrage.OnEnter,「火力压制」攻速收益调整未生效。");
				return;
			}
			harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(CommandoBarrageTweaks), "FireBarrageOnEnterTranspiler", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null);
			_log.LogInfo((object)"补丁已挂载:FireBarrage.OnEnter <- CommandoBarrageTweaks.FireBarrageOnEnterTranspiler()(攻速收益)");
			_baseBulletCountField = AccessTools.Field(typeof(FireBarrage), "baseBulletCount");
			if (_baseBulletCountField == null)
			{
				_log.LogError((object)"找不到 FireBarrage.baseBulletCount 静态字段,「火力压制」子弹数未修改。");
				return;
			}
			harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(AccessTools.Method(typeof(CommandoBarrageTweaks), "FireBarrageOnEnterPrefix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			_log.LogInfo((object)("补丁已挂载:FireBarrage.OnEnter <- CommandoBarrageTweaks.FireBarrageOnEnterPrefix()(子弹数基准 " + 6 + " → " + _bulletCount.Value + ")"));
		}

		public static void FireBarrageOnEnterPrefix()
		{
			try
			{
				if (_enabled.Value && !(_baseBulletCountField == null))
				{
					int num = Math.Max(0, _bulletCount.Value);
					_baseBulletCountField.SetValue(null, num);
					if (!_bulletCountLogged)
					{
						_bulletCountLogged = true;
						_log.LogInfo((object)("「火力压制」子弹数基准已改为 " + num + "(原版 " + 6 + ",实际发射数仍会再乘以攻击速度)。"));
					}
				}
			}
			catch (Exception ex)
			{
				_log.LogWarning((object)("修改「火力压制」子弹数异常: " + ex.GetType().Name + " / " + ex.Message));
			}
		}

		public static float GetAttackSpeedGainMultiplier(EntityState self)
		{
			if (self == null || !_enabled.Value)
			{
				return 1f;
			}
			float value = _multiplier.Value;
			if (!(value <= 0f))
			{
				return value;
			}
			return 1f;
		}

		public static IEnumerable<CodeInstruction> FireBarrageOnEnterTranspiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Expected O, but got Unknown
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Expected O, but got Unknown
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Expected O, but got Unknown
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			int num = 0;
			for (int i = 0; i < list.Count; i++)
			{
				CodeInstruction val = list[i];
				if (val.opcode == OpCodes.Ldfld && val.operand is FieldInfo { Name: "attackSpeedStat" })
				{
					int num2 = i + 1;
					if (num2 < list.Count && !(list[num2].opcode != OpCodes.Div))
					{
						list.InsertRange(i + 1, new List<CodeInstruction>
						{
							new CodeInstruction(OpCodes.Ldarg_0, (object)null),
							new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(CommandoBarrageTweaks), "GetAttackSpeedGainMultiplier", (Type[])null, (Type[])null)),
							new CodeInstruction(OpCodes.Mul, (object)null)
						});
						num++;
						i += 3;
					}
				}
			}
			_patchedCount++;
			_log.LogInfo((object)("FireBarrage.OnEnter 攻速收益已注入 " + num + " 处" + ((num == 1) ? "(仅射击间隔 durationBetweenShots,子弹数保持原版)" : "(数量异常,请检查 DLL 版本是否匹配)") + "。"));
			return list;
		}
	}
	internal static class CommandoGrenadeTweaks
	{
		private const string GrenadePrefabName = "CommandoGrenadeProjectile";

		private static ManualLogSource _log;

		private static ConfigEntry<bool> _enabled;

		private static GameObject _grenadePrefab;

		private static int _patchedCount;

		internal static void Init(ConfigFile config, ManualLogSource log)
		{
			_log = log;
			_enabled = config.Bind<bool>("Special.碎片击伤手雷", "Enabled", true, "是否让「碎片击伤手雷」在碰撞地形或敌人时立即引爆(原版碰到了还要等一会才爆)。");
		}

		internal static void Patch(Harmony harmony)
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Expected O, but got Unknown
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Expected O, but got Unknown
			MethodInfo methodInfo = AccessTools.Method(typeof(GenericProjectileBaseState), "FireProjectile", (Type[])null, (Type[])null);
			if (methodInfo == null)
			{
				_log.LogError((object)"找不到 GenericProjectileBaseState.FireProjectile,手雷改动未生效。");
				return;
			}
			harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(AccessTools.Method(typeof(CommandoGrenadeTweaks), "FireProjectilePrefix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			_log.LogInfo((object)"补丁已挂载:GenericProjectileBaseState.FireProjectile <- CommandoGrenadeTweaks(手雷)");
			MethodInfo methodInfo2 = AccessTools.Method(typeof(ProjectileImpactExplosion), "Start", (Type[])null, (Type[])null);
			if (methodInfo2 == null)
			{
				_log.LogError((object)"找不到 ProjectileImpactExplosion.Start,手雷改动未生效。");
				return;
			}
			harmony.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(CommandoGrenadeTweaks), "ImpactExplosionStartPostfix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			_log.LogInfo((object)"补丁已挂载:ProjectileImpactExplosion.Start <- CommandoGrenadeTweaks.ImpactExplosionStartPostfix()");
		}

		public static void FireProjectilePrefix(GenericProjectileBaseState __instance)
		{
			try
			{
				if ((Object)(object)_grenadePrefab == (Object)null && __instance is ThrowGrenade && (Object)(object)__instance.projectilePrefab != (Object)null)
				{
					_grenadePrefab = __instance.projectilePrefab;
					_log.LogInfo((object)("已捕获「碎片击伤手雷」射弹预制体: " + ((Object)_grenadePrefab).name));
					ProjectileImpactExplosion component = _grenadePrefab.GetComponent<ProjectileImpactExplosion>();
					if ((Object)(object)component == (Object)null)
					{
						_log.LogWarning((object)"手雷射弹上没有 ProjectileImpactExplosion,引爆时机可能改不动(请把这条日志发给我)。");
						return;
					}
					_log.LogInfo((object)("手雷原版引爆参数: destroyOnWorld=" + component.destroyOnWorld + " destroyOnEnemy=" + component.destroyOnEnemy + " impactOnWorld=" + component.impactOnWorld + " timerAfterImpact=" + component.timerAfterImpact + " lifetimeAfterImpact=" + component.lifetimeAfterImpact + " lifetime=" + component.lifetime));
				}
			}
			catch (Exception ex)
			{
				_log.LogWarning((object)("捕获手雷预制体异常: " + ex.Message));
			}
		}

		public static void ImpactExplosionStartPostfix(ProjectileImpactExplosion __instance)
		{
			try
			{
				if (_enabled.Value && !((Object)(object)__instance == (Object)null) && IsGrenade(((Component)__instance).gameObject))
				{
					__instance.destroyOnWorld = true;
					__instance.impactOnWorld = true;
					__instance.destroyOnEnemy = true;
					__instance.timerAfterImpact = false;
					__instance.lifetimeAfterImpact = 0f;
					__instance.minimumPhysicsStepsToKeepAliveAfterImpact = 0u;
					_patchedCount++;
					if (_patchedCount == 1 || _patchedCount % 10 == 0)
					{
						_log.LogInfo((object)("手雷已改为碰撞即引爆(累计 " + _patchedCount + " 枚)。"));
					}
				}
			}
			catch (Exception ex)
			{
				_log.LogWarning((object)("改写手雷引爆参数异常: " + ex.Message));
			}
		}

		private static bool IsGrenade(GameObject projectile)
		{
			if ((Object)(object)projectile == (Object)null)
			{
				return false;
			}
			if ((Object)(object)_grenadePrefab != (Object)null)
			{
				ProjectileController component = projectile.GetComponent<ProjectileController>();
				if ((Object)(object)component != (Object)null)
				{
					GameObject projectilePrefab = ProjectileCatalog.GetProjectilePrefab(component.catalogIndex);
					if ((Object)(object)projectilePrefab != (Object)null)
					{
						if (projectilePrefab != _grenadePrefab)
						{
							return string.Equals(((Object)projectilePrefab).name, "CommandoGrenadeProjectile", StringComparison.Ordinal);
						}
						return true;
					}
				}
			}
			return ((Object)projectile).name.StartsWith("CommandoGrenadeProjectile", StringComparison.Ordinal);
		}
	}
	internal static class CommandoPhaseRoundTweaks
	{
		private const string PhaseRoundPrefabName = "CommandoFMJ";

		private const string SecondaryDescriptionToken = "COMMANDO_SECONDARY_DESCRIPTION";

		private static ManualLogSource _log;

		private static ConfigEntry<bool> _enabled;

		private static ConfigEntry<float> _secondShotDelay;

		private static ConfigEntry<float> _speedMultiplier;

		private static GameObject _phaseRoundPrefab;

		private static readonly FieldInfo _firedProjectileField = AccessTools.Field(typeof(GenericProjectileBaseState), "firedProjectile");

		private static readonly FieldInfo _stopwatchField = AccessTools.Field(typeof(GenericProjectileBaseState), "stopwatch");

		private static readonly FieldInfo _delayField = AccessTools.Field(typeof(GenericProjectileBaseState), "delayBeforeFiringProjectile");

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

		private static readonly MethodInfo _setForwardSpeedMethod = AccessTools.Method(typeof(ProjectileSimple), "SetForwardSpeed", (Type[])null, (Type[])null);

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

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

		private static int _scheduledCount;

		private static int _boostedCount;

		private static bool _loggedMissingComponents;

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

		internal static void Init(ConfigFile config, ManualLogSource log)
		{
			_log = log;
			_enabled = config.Bind<bool>("Secondary.相位子弹", "Enabled", true, "是否启用「相位子弹」调整(连续发射两枚 + 射弹飞行速度提升)。");
			_secondShotDelay = config.Bind<float>("Secondary.相位子弹", "SecondShotDelay", 0.1f, "第二枚射弹相对第一枚的延迟(秒)。0.1 = 连发间隔 0.1 秒;0 = 几乎同时射出。");
			_speedMultiplier = config.Bind<float>("Secondary.相位子弹", "ProjectileSpeedMultiplier", 2f, "射弹飞行速度倍率。2 = +100% 飞行速度;1 = 原版。");
		}

		internal static void ApplyLanguage()
		{
			LanguageAPI.Add("COMMANDO_SECONDARY_DESCRIPTION", "Fire <style=cIsDamage>two</style> piercing shots for a total of <style=cIsDamage>2x300% damage</style>. Damage increases by <style=cIsDamage>40%</style> for each enemy pierced.", "en");
			LanguageAPI.Add("COMMANDO_SECONDARY_DESCRIPTION", "发射<style=cIsDamage>两次</style><style=cIsDamage>穿甲</style>射击,合计造成<style=cIsDamage>2x300%的伤害</style>。每次穿透敌人,造成的伤害提高<style=cIsDamage>40%</style>。", "zh-CN");
			_log.LogInfo((object)"「相位子弹」技能描述已覆盖: COMMANDO_SECONDARY_DESCRIPTION");
		}

		internal static void Patch(Harmony harmony)
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Expected O, but got Unknown
			//IL_0070: Expected O, but got Unknown
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Expected O, but got Unknown
			MethodInfo methodInfo = AccessTools.Method(typeof(GenericProjectileBaseState), "FireProjectile", (Type[])null, (Type[])null);
			if (methodInfo == null)
			{
				_log.LogError((object)"找不到 GenericProjectileBaseState.FireProjectile,「相位子弹」调整未生效。");
				return;
			}
			harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(AccessTools.Method(typeof(CommandoPhaseRoundTweaks), "FireProjectilePrefix", (Type[])null, (Type[])null)), new HarmonyMethod(AccessTools.Method(typeof(CommandoPhaseRoundTweaks), "FireProjectilePostfix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			_log.LogInfo((object)"补丁已挂载:GenericProjectileBaseState.FireProjectile <- CommandoPhaseRoundTweaks(相位子弹)");
			MethodInfo methodInfo2 = AccessTools.Method(typeof(ProjectileSimple), "Start", (Type[])null, (Type[])null);
			if (methodInfo2 == null)
			{
				_log.LogError((object)"找不到 ProjectileSimple.Start,射弹加速未生效。");
				return;
			}
			harmony.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(CommandoPhaseRoundTweaks), "ProjectileSimpleStartPostfix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			_log.LogInfo((object)"补丁已挂载:ProjectileSimple.Start <- CommandoPhaseRoundTweaks.ProjectileSimpleStartPostfix()");
		}

		public static void FireProjectilePrefix(GenericProjectileBaseState __instance)
		{
			try
			{
				if ((Object)(object)_phaseRoundPrefab == (Object)null && __instance is FireFMJ && (Object)(object)__instance.projectilePrefab != (Object)null)
				{
					_phaseRoundPrefab = __instance.projectilePrefab;
					_log.LogInfo((object)("已捕获「相位子弹」射弹预制体: " + ((Object)_phaseRoundPrefab).name));
					ProjectileSimple component = _phaseRoundPrefab.GetComponent<ProjectileSimple>();
					if ((Object)(object)component == (Object)null)
					{
						_log.LogWarning((object)"「相位子弹」射弹上没有 ProjectileSimple,飞行速度可能改不动(请把这条日志发给我)。");
					}
					else
					{
						_log.LogInfo((object)("「相位子弹」原版飞行速度 = " + component.desiredForwardSpeed));
					}
				}
			}
			catch (Exception ex)
			{
				_log.LogWarning((object)("捕获射弹预制体异常: " + ex.Message));
			}
		}

		public static void FireProjectilePostfix(GenericProjectileBaseState __instance)
		{
			try
			{
				if (!_enabled.Value || __instance == null || !(__instance is FireFMJ))
				{
					return;
				}
				StrongBox<int> value = _fireCounts.GetValue(__instance, _makeCount);
				value.Value++;
				if (value.Value > 1)
				{
					return;
				}
				if (_firedProjectileField == null || _stopwatchField == null || _delayField == null)
				{
					if (!_loggedMissingComponents)
					{
						_loggedMissingComponents = true;
						_log.LogError((object)"找不到 GenericProjectileBaseState 的 firedProjectile / stopwatch / delayBeforeFiringProjectile 字段。");
					}
					return;
				}
				float num = (float)_stopwatchField.GetValue(__instance);
				float num2 = Math.Max(0f, _secondShotDelay.Value);
				float num3 = num + num2;
				_firedProjectileField.SetValue(__instance, false);
				_delayField.SetValue(__instance, num3);
				if (_durationField != null && (float)_durationField.GetValue(__instance) < num3 + 0.05f)
				{
					_durationField.SetValue(__instance, num3 + 0.05f);
				}
				_scheduledCount++;
				if (_scheduledCount == 1 || _scheduledCount % 20 == 0)
				{
					_log.LogInfo((object)("「相位子弹」已排入第二枚射弹(间隔 " + num2 + "s,累计 " + _scheduledCount + " 次)。"));
				}
			}
			catch (Exception ex)
			{
				_log.LogWarning((object)("编排第二枚射弹异常: " + ex.Message));
			}
		}

		public static void ProjectileSimpleStartPostfix(ProjectileSimple __instance)
		{
			try
			{
				if (!_enabled.Value || (Object)(object)__instance == (Object)null || !IsPhaseRound(((Component)__instance).gameObject))
				{
					return;
				}
				float value = _speedMultiplier.Value;
				if (!(Math.Abs(value - 1f) < 0.0001f))
				{
					float desiredForwardSpeed = __instance.desiredForwardSpeed;
					__instance.desiredForwardSpeed = desiredForwardSpeed * value;
					if (_setForwardSpeedMethod != null)
					{
						_setForwardSpeedMethod.Invoke(__instance, new object[1] { __instance.desiredForwardSpeed });
					}
					_boostedCount++;
					if (_boostedCount == 1 || _boostedCount % 20 == 0)
					{
						_log.LogInfo((object)("「相位子弹」射弹已加速: " + desiredForwardSpeed + " -> " + __instance.desiredForwardSpeed + " (x" + value + ",累计 " + _boostedCount + " 枚)"));
					}
				}
			}
			catch (Exception ex)
			{
				_log.LogWarning((object)("加速射弹异常: " + ex.Message));
			}
		}

		private static bool IsPhaseRound(GameObject projectile)
		{
			if ((Object)(object)projectile == (Object)null)
			{
				return false;
			}
			if ((Object)(object)_phaseRoundPrefab != (Object)null)
			{
				ProjectileController component = projectile.GetComponent<ProjectileController>();
				if ((Object)(object)component != (Object)null)
				{
					GameObject projectilePrefab = ProjectileCatalog.GetProjectilePrefab(component.catalogIndex);
					if ((Object)(object)projectilePrefab != (Object)null)
					{
						if (projectilePrefab != _phaseRoundPrefab)
						{
							return string.Equals(((Object)projectilePrefab).name, "CommandoFMJ", StringComparison.Ordinal);
						}
						return true;
					}
				}
			}
			return ((Object)projectile).name.StartsWith("CommandoFMJ", StringComparison.Ordinal);
		}
	}
	internal static class CommandoSupplyPassive
	{
		internal const string PassiveNameToken = "COMMANDO_PASSIVE_NAME";

		internal const string PassiveDescriptionToken = "COMMANDO_PASSIVE_DESCRIPTION";

		private const string CommandoBodyName = "CommandoBody";

		private static readonly string[] ItemPool = new string[10] { "ArmorPlate", "BleedOnHit", "StunChanceOnHit", "StickyBomb", "IgniteOnKill", "SprintBonus", "Missile", "Bandolier", "Phasing", "SecondarySkillMagazine" };

		private static readonly string[] ItemDisplayNames = new string[10] { "推斥装甲板", "三尖匕首", "眩晕手雷", "黏弹", "汽油", "能量饮料", "ATG 导弹 MK1(空对地导弹1号)", "子弹带", "老旧战争潜行装置", "备用弹夹" };

		private static ManualLogSource _log;

		private static ConfigEntry<bool> _enabled;

		private static ConfigEntry<int> _itemCount;

		private static Sprite _icon;

		private static bool _prefabPatched;

		private static Run _lastRun;

		private static bool _grantedThisRun;

		private static bool _poolWarned;

		private static bool _poolValidated;

		private static List<int> _validPool;

		private static List<int> _pending;

		private static float _retryUntil;

		private static bool _retryLogged;

		internal static void Init(ConfigFile config, ManualLogSource log)
		{
			_log = log;
			_enabled = config.Bind<bool>("Passive.补给", "Enabled", true, "是否启用指挥官被动「补给」(开局随机获得 3 件实用物品)。");
			_itemCount = config.Bind<int>("Passive.补给", "ItemCount", 3, "开局随机发放的物品件数(不会重复,每件被选中的概率均等;最多等于物品池大小 " + ItemPool.Length + ")。");
		}

		internal static void ApplyLanguage()
		{
			LanguageAPI.Add("COMMANDO_PASSIVE_NAME", "Supply", "en");
			LanguageAPI.Add("COMMANDO_PASSIVE_DESCRIPTION", "Start each run with a few handy items to aid you in combat.", "en");
			LanguageAPI.Add("COMMANDO_PASSIVE_NAME", "补给", "zh-CN");
			LanguageAPI.Add("COMMANDO_PASSIVE_DESCRIPTION", "获得数件实用物品协助战斗。", "zh-CN");
			_log.LogInfo((object)"被动文本已注册: COMMANDO_PASSIVE_NAME / COMMANDO_PASSIVE_DESCRIPTION");
		}

		internal static void LoadIcon()
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Expected O, but got Unknown
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				string text = Path.Combine(Path.GetDirectoryName(typeof(CommandoSupplyPassive).Assembly.Location), "passiveIcon.png");
				if (!File.Exists(text))
				{
					_log.LogWarning((object)("找不到被动图标文件: " + text));
					return;
				}
				byte[] array = File.ReadAllBytes(text);
				Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
				if (!ImageConversion.LoadImage(val, array))
				{
					_log.LogWarning((object)("被动图标解码失败: " + text));
					return;
				}
				((Texture)val).wrapMode = (TextureWrapMode)1;
				_icon = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f);
				((Object)_icon).name = "texSparkleCommandoSupplyIcon";
				_log.LogInfo((object)("被动图标已加载: " + text + " (" + ((Texture)val).width + "x" + ((Texture)val).height + ")"));
			}
			catch (Exception ex)
			{
				_log.LogError((object)("加载被动图标异常: " + ex));
			}
		}

		internal static void TryPatchPrefab()
		{
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: 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_00b3: Unknown result type (might be due to invalid IL or missing references)
			if (_prefabPatched)
			{
				return;
			}
			try
			{
				if (!((ResourceAvailability)(ref BodyCatalog.availability)).available)
				{
					return;
				}
				GameObject val = BodyCatalog.FindBodyPrefab("CommandoBody");
				if ((Object)(object)val == (Object)null)
				{
					_log.LogWarning((object)"BodyCatalog 里找不到 CommandoBody,被动槽位未挂载。");
					_prefabPatched = true;
					return;
				}
				SkillLocator component = val.GetComponent<SkillLocator>();
				if ((Object)(object)component == (Object)null)
				{
					_log.LogError((object)"CommandoBody 上没有 SkillLocator,被动槽位未挂载。");
					_prefabPatched = true;
					return;
				}
				PassiveSkill passiveSkill = component.passiveSkill;
				passiveSkill.enabled = true;
				passiveSkill.skillNameToken = "COMMANDO_PASSIVE_NAME";
				passiveSkill.skillDescriptionToken = "COMMANDO_PASSIVE_DESCRIPTION";
				passiveSkill.keywordToken = string.Empty;
				passiveSkill.icon = _icon;
				component.passiveSkill = passiveSkill;
				_prefabPatched = true;
				_log.LogInfo((object)("已为 CommandoBody 启用被动「补给」 icon=" + ((Object)(object)_icon != (Object)null)));
			}
			catch (Exception ex)
			{
				_prefabPatched = true;
				_log.LogError((object)("挂载被动槽位异常: " + ex));
			}
		}

		internal static void Tick()
		{
			TryPatchPrefab();
			if (!_enabled.Value)
			{
				return;
			}
			try
			{
				TrackRunInstance();
				TryGrantItems();
			}
			catch (Exception ex)
			{
				_log.LogWarning((object)("「补给」发放异常: " + ex.GetType().Name + " / " + ex.Message));
			}
		}

		private static void TrackRunInstance()
		{
			Run instance = Run.instance;
			if (instance != _lastRun)
			{
				_lastRun = instance;
				_grantedThisRun = false;
				_pending = null;
				_retryLogged = false;
				if ((Object)(object)instance != (Object)null)
				{
					_log.LogInfo((object)"新的一局开始(Run 实例已更新),「补给」待发放。");
				}
			}
		}

		private static bool EnsurePoolValidated()
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			if (_poolValidated)
			{
				return true;
			}
			if (!((ResourceAvailability)(ref ItemCatalog.availability)).available)
			{
				return false;
			}
			_poolValidated = true;
			_validPool = new List<int>();
			StringBuilder stringBuilder = new StringBuilder();
			for (int i = 0; i < ItemPool.Length; i++)
			{
				string text = ItemPool[i];
				try
				{
					if ((Object)(object)ItemCatalog.GetItemDef(ItemCatalog.FindItemIndex(text)) == (Object)null)
					{
						if (stringBuilder.Length > 0)
						{
							stringBuilder.Append("、");
						}
						stringBuilder.Append(ItemDisplayNames[i] + "(" + text + ")");
					}
					else
					{
						_validPool.Add(i);
					}
				}
				catch (Exception ex)
				{
					_log.LogWarning((object)("「补给」物品池校验 " + text + " 异常: " + ex.GetType().Name + " / " + ex.Message));
				}
			}
			_log.LogInfo((object)("「补给」物品池校验完成:有效 " + _validPool.Count + "/" + ItemPool.Length + " 件 -> " + JoinNames(_validPool) + ((stringBuilder.Length > 0) ? (";已剔除无效项 -> " + stringBuilder) : "")));
			return true;
		}

		private static void TryGrantItems()
		{
			if (_grantedThisRun || !EnsurePoolValidated())
			{
				return;
			}
			if (_validPool.Count == 0)
			{
				_grantedThisRun = true;
				return;
			}
			CharacterBody val = null;
			Inventory val2 = null;
			foreach (CharacterBody readOnlyInstances in CharacterBody.readOnlyInstancesList)
			{
				if (!((Object)(object)readOnlyInstances == (Object)null) && IsCommando(readOnlyInstances))
				{
					Inventory inventory = readOnlyInstances.inventory;
					if ((Object)(object)inventory == (Object)null && (Object)(object)readOnlyInstances.master != (Object)null)
					{
						inventory = readOnlyInstances.master.inventory;
					}
					if (!((Object)(object)inventory == (Object)null))
					{
						val = readOnlyInstances;
						val2 = inventory;
						break;
					}
				}
			}
			if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null)
			{
				return;
			}
			int num = Mathf.Clamp(_itemCount.Value, 0, _validPool.Count);
			if (num <= 0)
			{
				_grantedThisRun = true;
				return;
			}
			if (_pending == null)
			{
				List<int> list = new List<int>(_validPool);
				_pending = new List<int>();
				for (int i = 0; i < num; i++)
				{
					if (list.Count <= 0)
					{
						break;
					}
					int index = Random.Range(0, list.Count);
					_pending.Add(list[index]);
					list.RemoveAt(index);
				}
				_retryUntil = Time.unscaledTime + 10f;
				_log.LogInfo((object)("「补给」本局抽签结果 -> " + JoinNames(_pending) + "(准备发放)"));
			}
			List<int> list2 = new List<int>();
			List<int> list3 = new List<int>();
			foreach (int item in _pending)
			{
				if (TryGiveOne(val2, item))
				{
					list2.Add(item);
				}
				else
				{
					list3.Add(item);
				}
			}
			_pending = list3;
			if (_pending.Count == 0)
			{
				_grantedThisRun = true;
				_log.LogInfo((object)("「补给」已发放 " + list2.Count + " 件实用物品 -> " + JoinNames(list2) + "(对象:" + ((Object)val).name + ",本局后续不再发放)"));
			}
			else if (Time.unscaledTime > _retryUntil)
			{
				_grantedThisRun = true;
				_log.LogError((object)("「补给」发放超时:仍有 " + _pending.Count + " 件没发出去 -> " + JoinNames(_pending) + "(已发 " + list2.Count + " 件)"));
			}
			else if (!_retryLogged)
			{
				_retryLogged = true;
				_log.LogInfo((object)("「补给」有 " + _pending.Count + " 件暂未发成功,稍后重试 -> " + JoinNames(_pending)));
			}
		}

		private static bool TryGiveOne(Inventory inventory, int poolIndex)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: 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_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			string text = ItemPool[poolIndex];
			string text2 = ItemDisplayNames[poolIndex];
			try
			{
				ItemIndex val = ItemCatalog.FindItemIndex(text);
				if ((Object)(object)ItemCatalog.GetItemDef(val) == (Object)null)
				{
					if (!_poolWarned)
					{
						_poolWarned = true;
						_log.LogWarning((object)("「补给」找不到物品定义: " + text2 + "(" + text + ")—— internal 名可能在这版游戏里变了。"));
					}
					return false;
				}
				int itemCountPermanent = inventory.GetItemCountPermanent(val);
				inventory.GiveItemString(text);
				int itemCountPermanent2 = inventory.GetItemCountPermanent(val);
				if (itemCountPermanent2 > itemCountPermanent)
				{
					return true;
				}
				if (!_poolWarned)
				{
					_poolWarned = true;
					_log.LogWarning((object)("「补给」发放 " + text2 + "(" + text + ")后物品数没有增加(" + itemCountPermanent + " -> " + itemCountPermanent2 + "),稍后重试。"));
				}
				return false;
			}
			catch (Exception ex)
			{
				if (!_poolWarned)
				{
					_poolWarned = true;
					_log.LogWarning((object)("「补给」发放 " + text2 + "(" + text + ")失败: " + ex.GetType().Name + " / " + ex.Message));
				}
				return false;
			}
		}

		private static string JoinNames(List<int> poolIndices)
		{
			StringBuilder stringBuilder = new StringBuilder();
			for (int i = 0; i < poolIndices.Count; i++)
			{
				if (i > 0)
				{
					stringBuilder.Append("、");
				}
				stringBuilder.Append(ItemDisplayNames[poolIndices[i]]);
			}
			return stringBuilder.ToString();
		}

		internal static bool IsCommando(CharacterBody body)
		{
			if ((Object)(object)body == (Object)null)
			{
				return false;
			}
			string name = ((Object)body).name;
			if (!string.IsNullOrEmpty(name) && name.StartsWith("CommandoBody", StringComparison.Ordinal))
			{
				return true;
			}
			string baseNameToken = body.baseNameToken;
			if (!string.IsNullOrEmpty(baseNameToken))
			{
				return baseNameToken.IndexOf("COMMANDO", StringComparison.Ordinal) >= 0;
			}
			return false;
		}
	}
	[BepInPlugin("com.sparkletwilight.sparklecommandotweaks", "SparkleCommandoTweaks", "1.11.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class SparkleCommandoTweaksPlugin : BaseUnityPlugin
	{
		public const string PluginGUID = "com.sparkletwilight.sparklecommandotweaks";

		public const string PluginName = "SparkleCommandoTweaks";

		public const string PluginVersion = "1.11.1";

		internal ManualLogSource Logger;

		public void Awake()
		{
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Expected O, but got Unknown
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Expected O, but got Unknown
			//IL_007a: Expected O, but got Unknown
			Logger = ((BaseUnityPlugin)this).Logger;
			CommandoSupplyPassive.Init(((BaseUnityPlugin)this).Config, Logger);
			CommandoSupplyPassive.ApplyLanguage();
			CommandoSupplyPassive.LoadIcon();
			CommandoPhaseRoundTweaks.Init(((BaseUnityPlugin)this).Config, Logger);
			CommandoPhaseRoundTweaks.ApplyLanguage();
			CommandoGrenadeTweaks.Init(((BaseUnityPlugin)this).Config, Logger);
			CommandoBarrageTweaks.Init(((BaseUnityPlugin)this).Config, Logger);
			Harmony val = new Harmony("com.sparkletwilight.sparklecommandotweaks");
			CommandoPhaseRoundTweaks.Patch(val);
			CommandoGrenadeTweaks.Patch(val);
			CommandoBarrageTweaks.Patch(val);
			Logger.LogInfo((object)"SparkleCommandoTweaks v1.11.1 已加载。被动「补给」(开局随机 3 件临时作战用具) + M2「相位子弹」连发两枚且射弹速度 +100%(描述已同步) + 替代 R「碎片击伤手雷」碰撞即引爆 + R「火力压制」攻速收益 ×1.5(仅射击间隔)且子弹数 6 → 7。");
		}

		public void Update()
		{
			CommandoSupplyPassive.Tick();
		}
	}
}