Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of SparkleCommandoTweaks v1.11.1
plugins/SparkleCommandoTweaks.dll
Decompiled 2 hours agousing 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(); } } }