Decompiled source of EmissiveFX v1.0.1
EmissiveFX.dll
Decompiled 2 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using CellMenu; using Gear; using HarmonyLib; using Il2CppInterop.Runtime; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppSystem; using Il2CppSystem.Collections.Generic; using Microsoft.CodeAnalysis; using Player; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")] [assembly: AssemblyCompany("EmissiveFX")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("2.2.0.0")] [assembly: AssemblyInformationalVersion("2.2.0")] [assembly: AssemblyProduct("EmissiveFX")] [assembly: AssemblyTitle("EmissiveFX")] [assembly: AssemblyVersion("2.2.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 EmissiveFX { public enum SlotKind { Primary, Special, Tool, Melee, Other } [BepInPlugin("gtfoskin.emissivefx", "EmissiveFX", "1.0.1")] public class Plugin : BasePlugin { public const string GUID = "gtfoskin.emissivefx"; public static ManualLogSource Log; public static ConfigEntry<float> CfgPeriod; public static ConfigEntry<float> CfgMin; public static ConfigEntry<float> CfgMax; public static ConfigEntry<float> CfgCurve; public static ConfigEntry<bool> CfgEnabled; public const string ModeSolid = "Solid"; public const string ModeBreathing = "Breathing"; public const string ModeHeartbeat = "Heartbeat"; public const string ModeAlarm = "Alarm"; public const string ModeFlicker = "Flicker"; public const string ModeCharge = "Charge"; public const string ModeHue = "Hue"; public const string ModeTwinkle = "Twinkle"; public const string ModeSparks = "Sparks"; public const string ModeSweep = "Sweep"; public const string ModeLowHealth = "LowHealth"; public const string ModeChase = "Chase"; public const string ModeGradient = "Gradient"; public const string ModeRainbow = "Rainbow"; public const string ModeHeat = "Heat"; public const string ModeCold = "ColdFire"; public const string ModeEmber = "Ember"; public const string ModeNoise = "NoiseDrift"; public const string ModeAntiPhase = "AntiPhase"; public static ConfigEntry<string> CfgMode; public static ConfigEntry<string> CfgShaderFilter; public static ConfigEntry<string> CfgExcludeNames; public static ConfigEntry<bool> CfgEquipmentOnly; public static ConfigEntry<bool> CfgRequireEmissiveMap; public static ConfigEntry<bool> CfgVisibleOnly; public static ConfigEntry<float> CfgRetrySeconds; public static ConfigEntry<string> CfgScanMode; public const string ScanTest = "Test"; public const string ScanConfirmed = "Confirmed"; public const string ScanOff = "Off"; public static volatile bool NeedScan; public static volatile bool ManualScanPending; public static volatile string FrozenMode; public static string ActiveMode() { string frozenMode = FrozenMode; if (!string.IsNullOrEmpty(frozenMode)) { return frozenMode; } return CfgMode.Value ?? "Breathing"; } public override void Load() { Log = ((BasePlugin)this).Log; CfgPeriod = ((BasePlugin)this).Config.Bind<float>("Breathing", "PeriodSeconds", 3.2f, "One full breath cycle in seconds. 2-4 s reads as breathing."); CfgMin = ((BasePlugin)this).Config.Bind<float>("Breathing", "MinFactor", 0.3f, "Emissive multiplier at the dimmest point."); CfgMax = ((BasePlugin)this).Config.Bind<float>("Breathing", "MaxFactor", 0.98f, "Emissive multiplier at the brightest point."); CfgCurve = ((BasePlugin)this).Config.Bind<float>("Breathing", "CurvePower", 1.6f, "1 = pure sine. Higher = longer dwell at the dim end."); CfgEnabled = ((BasePlugin)this).Config.Bind<bool>("Switches", "Enabled", true, "Master switch (also the 总开关 toggle on the in-game page)."); CfgMode = ((BasePlugin)this).Config.Bind<string>("Switches", "Effect", "Solid", "Which effect drives the emissive. One of:\n Solid / Breathing / Heartbeat / Alarm / Flicker / Charge / Hue\nAlso selectable on the in-game 效果 page, where the seven switches\nare mutually exclusive."); CfgEquipmentOnly = ((BasePlugin)this).Config.Bind<bool>("Advanced", "EquipmentOnly", true, "true = ONLY weapons/tools are affected (recommended).\nfalse = every emissive object in the level, including terminal\n screens and door panels."); CfgExcludeNames = ((BasePlugin)this).Config.Bind<string>("Advanced", "ExcludeNames", "", "Space separated. Renderers whose GameObject OR material name\ncontains any of these are left alone.\nEMPTY BY DEFAULT on purpose: the EquipmentOnly check already\nkeeps terminal screens out (they do not hang off a player),\nand a word like 'screen' in here also catches the screens\non the weapons themselves."); CfgShaderFilter = ((BasePlugin)this).Config.Bind<string>("Advanced", "ShaderFilter", "Gear", "Only renderers whose shader name CONTAINS this are considered."); CfgRequireEmissiveMap = ((BasePlugin)this).Config.Bind<bool>("Advanced", "RequireEmissiveMap", true, "Skip materials with no _EmissiveMap assigned."); CfgVisibleOnly = ((BasePlugin)this).Config.Bind<bool>("Performance", "VisibleOnly", false, "Only write to renderers that are visible this frame."); CfgRetrySeconds = ((BasePlugin)this).Config.Bind<float>("Performance", "RetrySeconds", 12f, "While no gear has been found yet, how often to look again.\nScanning is expensive, so it stops once something is found."); CfgScanMode = ((BasePlugin)this).Config.Bind<string>("Performance", "ScanMode", "Test", "Off = no full scan ever. The held-item path still\n collects the wielded weapon, so the effect keeps\n showing; only the safety-net scan is gone.\nTest = scan on demand, plus 60 s / 300 s safety timers.\n Fastest response, at the cost of a ~200 ms hitch\n every few minutes.\nConfirmed = one scan, then a 30 minute safety net only.\n Set by the manual confirm switch."); Log.LogInfo((object)"EmissiveFX v4.0.1 loaded - effects + scan policy. (menu-stutter fix)"); try { PatchAll(); Log.LogInfo((object)"harmony patches applied"); } catch (Exception ex) { Log.LogError((object)("failed to apply harmony patches: " + ex)); } ((BasePlugin)this).AddComponent<BreathBehaviour>(); try { TrajectoryCfg.Bind(((BasePlugin)this).Config); ((BasePlugin)this).AddComponent<TrajectoryBehaviour>(); Log.LogInfo((object)"trajectory (tracer) ready - default OFF"); } catch (Exception ex2) { Log.LogError((object)("failed to init trajectory: " + ex2)); } } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] private static void PatchAll() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) new Harmony("gtfoskin.emissivefx").PatchAll(typeof(SettingsPage)); } } public class BreathBehaviour : MonoBehaviour { private class Target { public Renderer rend; public Color baseColor; public SlotKind slot; public float phase; public float sparkTimer; public float spark; public float along; public bool alongDone; } private readonly List<Target> _scanCache = new List<Target>(); private readonly List<Target> _heldTargets = new List<Target>(); private readonly HashSet<long> _merged = new HashSet<long>(); private readonly Dictionary<long, Target> _known = new Dictionary<long, Target>(); private readonly List<Target> _targets = new List<Target>(); private float _gearTimer; private int _lastGearPtr; private string _lastGearSig = string.Empty; private PlayerInventoryLocal _cachedInv; private Transform _wieldedTf; private int _cachedItemPtr; private float _nextInvRetry; private int _invQueryCount; private int _invDropped; private float _invStaleTimer; private float _gearLogTimer; private float _rescanFallbackTimer; private bool _needScan = true; private float _lastScanTime; private readonly MaterialPropertyBlock _mpb = new MaterialPropertyBlock(); private Dam_SyncedDamageBase _playerDmg; private float _healthRel = 1f; private int _healthStage = 4; private float _healthTimer; private PlayerStamina _playerStamina; private float _tiredness; private float _staminaRel = 1f; private float _heartPhase; private static readonly float[] HealthHz = new float[5] { 2f, 1.55f, 1.15f, 0.8f, 0.5f }; private static readonly float[] HealthPeak = new float[5] { 1.55f, 1.35f, 1.18f, 1.03f, 0.95f }; private static readonly HashSet<string> _logged = new HashSet<string>(); private float _nextRetry; private bool _foundAny; private int _lastPulsed; private int _lastVisible; private float _reclassTimer; private string _lastTally = string.Empty; private float _frameGain = 1f; private Color _frameFixed = Color.white; private bool _frameUseFixed; private float _flicker = 1f; private float _sweepPos; private string _diagSamples = ""; private int _diagCount; private float _diagTimer; private float _diagDeadline = 180f; private static float _alongSeq; private static string[] _excl = new string[0]; private static string _exclRaw; private static readonly HashSet<string> _seenExcluded = new HashSet<string>(); private static readonly HashSet<string> _seenMatched = new HashSet<string>(); private static readonly HashSet<string> _seenScenery = new HashSet<string>(); private int _owners; public BreathBehaviour(IntPtr ptr) : base(ptr) { }//IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Expected O, but got Unknown //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) private static void LogOnce(string where, Exception e) { try { string item = where + "|" + e.GetType().Name; if (_logged.Add(item)) { Plugin.Log.LogWarning((object)("[once] " + where + ": " + e.Message)); } } catch { } } private void Awake() { _nextRetry = Time.time + 4f; _reclassTimer = Time.time + 2f; } private void Reclassify() { int num = 0; int num2 = 0; int num3 = 0; int num4 = 0; int num5 = 0; for (int i = 0; i < _targets.Count; i++) { Target target = _targets[i]; if (!((Object)(object)target.rend == (Object)null)) { target.slot = Classify(target.rend); switch (target.slot) { case SlotKind.Primary: num++; break; case SlotKind.Special: num2++; break; case SlotKind.Tool: num3++; break; case SlotKind.Melee: num4++; break; default: num5++; break; } } } string text = $"primary={num} special={num2} tool={num3} melee={num4} other={num5}"; if (text != _lastTally) { _lastTally = text; Plugin.Log.LogInfo((object)("slots: " + text)); } } private void Update() { try { SettingsPage.Tick(); if (Time.time >= _gearTimer) { _gearTimer = Time.time + 0.2f; RefreshGear(); } bool flag = _targets.Count == 0 && Time.time - _lastScanTime > 60f; bool flag2 = Time.time - _lastScanTime > 300f; bool flag3 = Plugin.CfgScanMode.Value != null && Plugin.CfgScanMode.Value.Equals("Confirmed", StringComparison.OrdinalIgnoreCase); int num; if (Plugin.CfgScanMode.Value != null) { num = (Plugin.CfgScanMode.Value.Equals("Off", StringComparison.OrdinalIgnoreCase) ? 1 : 0); if (num != 0) { if (string.IsNullOrEmpty(Plugin.FrozenMode)) { Plugin.FrozenMode = Plugin.CfgMode.Value; Plugin.Log.LogInfo((object)("[scan] effect frozen at '" + Plugin.FrozenMode + "'")); } goto IL_0113; } } else { num = 0; } if (!string.IsNullOrEmpty(Plugin.FrozenMode)) { Plugin.FrozenMode = null; Plugin.Log.LogInfo((object)"[scan] effect unfrozen"); } goto IL_0113; IL_0113: bool flag4; if (num == 0) { flag4 = ((!flag3) ? (Plugin.NeedScan || _needScan || flag || flag2) : (_lastScanTime <= 0f || Plugin.NeedScan || Time.time - _lastScanTime > 1800f)); } else { flag4 = false; _needScan = false; } if (flag4) { Plugin.NeedScan = false; _needScan = false; _lastScanTime = Time.time; Scan(); if (Plugin.ManualScanPending) { Plugin.ManualScanPending = false; try { SettingsPage.RefreshRows(); } catch { } } } else if (_targets.Count == 0) { MergeTargets(); } if (Plugin.CfgEnabled.Value && _targets.Count != 0) { ComputeFrame(); bool value = Plugin.CfgVisibleOnly.Value; int pulsed = 0; int visible = 0; try { Pulse(_targets, value, ref pulsed, ref visible); } catch (Exception e) { LogOnce("pulse", e); } _lastPulsed = pulsed; _lastVisible = visible; } } catch (Exception ex) { Plugin.Log.LogError((object)("update failed: " + ex)); } } private void Pulse(List<Target> list, bool visibleOnly, ref int pulsed, ref int visible) { //IL_0667: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_061d: Unknown result type (might be due to invalid IL or missing references) //IL_0627: Unknown result type (might be due to invalid IL or missing references) //IL_0631: Unknown result type (might be due to invalid IL or missing references) //IL_044a: Unknown result type (might be due to invalid IL or missing references) //IL_045e: Unknown result type (might be due to invalid IL or missing references) //IL_046b: Unknown result type (might be due to invalid IL or missing references) //IL_0470: Unknown result type (might be due to invalid IL or missing references) //IL_03d1: Unknown result type (might be due to invalid IL or missing references) //IL_03d6: Unknown result type (might be due to invalid IL or missing references) //IL_04ba: Unknown result type (might be due to invalid IL or missing references) //IL_04ce: Unknown result type (might be due to invalid IL or missing references) //IL_04d8: Unknown result type (might be due to invalid IL or missing references) //IL_04dd: Unknown result type (might be due to invalid IL or missing references) //IL_052f: Unknown result type (might be due to invalid IL or missing references) //IL_0543: Unknown result type (might be due to invalid IL or missing references) //IL_054a: Unknown result type (might be due to invalid IL or missing references) //IL_054f: Unknown result type (might be due to invalid IL or missing references) Color val2 = default(Color); for (int i = 0; i < list.Count; i++) { try { Target target = list[i]; Renderer rend = target.rend; if (!((Object)(object)rend == (Object)null)) { if (!visibleOnly) { goto IL_0041; } bool flag; try { flag = rend.isVisible; } catch { flag = true; } if (flag) { goto IL_0041; } } goto end_IL_0008; IL_0041: visible++; string text = Plugin.ActiveMode(); float time = Time.time; float num = Mathf.Max(0.2f, Plugin.CfgPeriod.Value); float value = Plugin.CfgMin.Value; float value2 = Plugin.CfgMax.Value; float num2 = _frameGain; Color val = (_frameUseFixed ? _frameFixed : target.baseColor); if (text.Equals("Twinkle", StringComparison.OrdinalIgnoreCase)) { float num3 = (time / num + target.phase) % 1f; float num4 = 0.5f - 0.5f * Mathf.Cos(MathF.PI * 2f * num3); num4 = Mathf.Pow(num4, Mathf.Max(0.05f, Plugin.CfgCurve.Value)); num2 = Mathf.Lerp(value, value2, num4); } else if (text.Equals("Sparks", StringComparison.OrdinalIgnoreCase)) { target.sparkTimer -= Time.deltaTime; if (target.sparkTimer <= 0f) { target.sparkTimer = Random.Range(0.5f, 3.5f); target.spark = 1f; } target.spark *= Mathf.Exp((0f - Time.deltaTime) * 9f); num2 = Mathf.Lerp(value, value2, Mathf.Clamp01(target.spark)); } else if (text.Equals("Sweep", StringComparison.OrdinalIgnoreCase)) { if (!target.alongDone) { target.along = 0.5f; target.alongDone = true; } float num5 = Mathf.Abs(Mathf.Repeat(target.along - _sweepPos + 0.5f, 1f) - 0.5f); float num6 = Mathf.Clamp01(1f - num5 / 0.16f); num2 = Mathf.Lerp(value, value2, num6 * num6); } else if (text.Equals("LowHealth", StringComparison.OrdinalIgnoreCase)) { float num7 = HealthHz[_healthStage]; float num8 = HealthPeak[_healthStage]; float x = time * num7 % 1f; float num9 = Thump(0.26f, x); num2 = Mathf.Lerp(value, value2 * num8, Mathf.Clamp01(num9)); } else if (text.Equals("Chase", StringComparison.OrdinalIgnoreCase)) { if (!target.alongDone) { target.along = target.phase; target.alongDone = true; } int num10 = Mathf.FloorToInt(time * 0.9f % 1f * 8f); float num11 = ((Mathf.FloorToInt(target.along * 8f * 0.999f) == num10) ? 1f : 0.35f); num2 = Mathf.Lerp(value + 0.2f, value2 * 1.15f, num11); } else if (text.Equals("Gradient", StringComparison.OrdinalIgnoreCase)) { if (!target.alongDone) { target.along = target.phase; target.alongDone = true; } float num12 = 0.5f + 0.5f * Mathf.Sin(time * 0.35f); float num13 = Mathf.Lerp(target.along, 1f - target.along, num12); num2 = Mathf.Lerp(value + 0.3f, value2 * 1.12f, num13 * num13); } else if (text.Equals("Rainbow", StringComparison.OrdinalIgnoreCase)) { if (!target.alongDone) { target.along = target.phase; target.alongDone = true; } val = Color.HSVToRGB(Mathf.Repeat(target.along * 0.8f + time * 0.14f, 1f), 1f, 1f); num2 = Mathf.Lerp(value + 0.45f, value2 * 1.15f, 0.45f + 0.25f * Mathf.Sin(time * 1.1f) + 0.3f * target.along); } else if (text.Equals("Heat", StringComparison.OrdinalIgnoreCase)) { float num14 = 0.5f - 0.5f * Mathf.Cos(MathF.PI * 2f * (time % num) / num); val = Color.Lerp(target.baseColor, new Color(1f, 0.72f, 0.32f), num14 * 0.85f); num2 = Mathf.Lerp(value, value2 * 1.15f, num14); } else if (text.Equals("ColdFire", StringComparison.OrdinalIgnoreCase)) { float num15 = 0.5f - 0.5f * Mathf.Cos(MathF.PI * 2f * (time % num) / num); val = Color.Lerp(target.baseColor, new Color(0.34f, 0.84f, 1f), 0.85f); num2 = Mathf.Lerp(value, value2 * 1.02f, num15); } else if (text.Equals("Ember", StringComparison.OrdinalIgnoreCase)) { float num16 = Mathf.PerlinNoise(time * 0.55f, target.phase * 7.3f); val = Color.Lerp(new Color(0.45f, 0.06f, 0.02f), new Color(1f, 0.42f, 0.1f), num16); num2 = Mathf.Lerp(value * 0.7f, value2 * 0.88f, num16); } else if (text.Equals("NoiseDrift", StringComparison.OrdinalIgnoreCase)) { float num17 = Mathf.PerlinNoise(time * 0.33f, target.phase * 13.7f); num2 = Mathf.Lerp(value, value2, num17); } else if (text.Equals("AntiPhase", StringComparison.OrdinalIgnoreCase)) { float num18 = time % num / num; float num19 = 0.5f - 0.5f * Mathf.Cos(MathF.PI * 2f * num18); num19 = Mathf.Pow(num19, Mathf.Max(0.05f, Plugin.CfgCurve.Value)); if (target.phase > 0.5f) { num19 = 1f - num19; } num2 = Mathf.Lerp(value, value2, num19); } ((Color)(ref val2))..ctor(val.r * num2, val.g * num2, val.b * num2, target.baseColor.a); try { rend.GetPropertyBlock(_mpb); } catch { } _mpb.SetColor("_EmissiveColor", val2); try { rend.SetPropertyBlock(_mpb); } catch { } pulsed++; end_IL_0008:; } catch { } } } private void LateUpdate() { try { SettingsPage.Tick(); } catch { } } private bool AllDead() { if (_targets.Count == 0) { return false; } for (int i = 0; i < _targets.Count; i++) { if ((Object)(object)_targets[i].rend != (Object)null) { return false; } } return true; } private static float NextAlong() { _alongSeq += 0.618034f; if (_alongSeq >= 1f) { _alongSeq -= 1f; } return _alongSeq; } private static float Thump(float width, float x) { if (x < 0f) { return 0f; } float num = x / width; return Mathf.Exp((0f - num) * num); } private static float Hash01(float n) { return Mathf.Abs(Mathf.Sin(n * 12.9898f) * 43758.547f) % 1f; } private void ComputeFrame() { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_02f3: Unknown result type (might be due to invalid IL or missing references) //IL_02f8: Unknown result type (might be due to invalid IL or missing references) string text = Plugin.ActiveMode(); float num = Mathf.Max(0.2f, Plugin.CfgPeriod.Value); float value = Plugin.CfgMin.Value; float value2 = Plugin.CfgMax.Value; float time = Time.time; _frameUseFixed = false; _frameFixed = Color.white; if (text.Equals("Solid", StringComparison.OrdinalIgnoreCase)) { _frameGain = value2; } else if (text.Equals("Heartbeat", StringComparison.OrdinalIgnoreCase)) { float num2 = Mathf.Lerp(55f, 185f, _tiredness); if (_healthRel < 0.5f) { num2 += (0.5f - _healthRel) * 60f; } num2 = Mathf.Clamp(num2, 40f, 210f); float num3 = 60f / num2; _heartPhase += Time.deltaTime / num3; if (_heartPhase >= 1f) { _heartPhase -= 1f; } if (_heartPhase < 0f) { _heartPhase = 0f; } float width = Mathf.Lerp(0.07f, 0.042f, _tiredness) / num3; float width2 = Mathf.Lerp(0.085f, 0.05f, _tiredness) / num3; float num4 = Mathf.Lerp(0.28f, 0.15f, _tiredness) / num3; float heartPhase = _heartPhase; float num5 = Thump(width, heartPhase) + 0.62f * Thump(width2, heartPhase - num4); _frameGain = Mathf.Lerp(value, value2, Mathf.Clamp01(num5)); } else if (text.Equals("Alarm", StringComparison.OrdinalIgnoreCase)) { float num6 = num * 0.35f; float num7 = time % num6 / num6; float num8 = ((num7 < 0.3f) ? Mathf.Clamp01(num7 / 0.05f) : Mathf.Clamp01(1f - (num7 - 0.3f) / 0.25f)); _frameGain = Mathf.Lerp(value, value2, num8); } else if (text.Equals("Flicker", StringComparison.OrdinalIgnoreCase)) { float num9 = ((Hash01(Mathf.Floor(time / 0.09f) % 1000f) < 0.3f) ? 0.15f : 1f); _flicker = Mathf.Lerp(_flicker, num9, 1f - Mathf.Exp((0f - Time.deltaTime) * 22f)); _frameGain = Mathf.Lerp(value, value2, Mathf.Clamp01(_flicker)); } else if (text.Equals("Charge", StringComparison.OrdinalIgnoreCase)) { float num10 = num * 0.8f; float num11 = time % num10 / num10; _frameGain = Mathf.Lerp(value, value2, num11); } else if (text.Equals("Hue", StringComparison.OrdinalIgnoreCase)) { float num12 = time * 0.12f % 1f; _frameUseFixed = true; _frameFixed = Color.HSVToRGB(num12, 0.75f, 1f); _frameGain = Mathf.Lerp(value, value2, 0.5f + 0.5f * Mathf.Sin(time)); } else { float num13 = time % num / num; float num14 = 0.5f - 0.5f * Mathf.Cos(MathF.PI * 2f * num13); num14 = Mathf.Pow(num14, Mathf.Max(0.05f, Plugin.CfgCurve.Value)); _frameGain = Mathf.Lerp(value, value2, num14); } _sweepPos = time * 0.45f % 1f; if (Time.time >= _healthTimer) { _healthTimer = Time.time + 0.5f; SampleHealth(); } } private void SampleHealth() { try { if ((Object)(object)_playerDmg == (Object)null) { if ((Object)(object)_cachedInv == (Object)null) { return; } Component componentInParent = ((Component)_cachedInv).gameObject.GetComponentInParent(Il2CppType.Of<Dam_SyncedDamageBase>()); if ((Object)(object)componentInParent != (Object)null) { _playerDmg = ((Il2CppObjectBase)componentInParent).TryCast<Dam_SyncedDamageBase>(); } } if ((Object)(object)_playerStamina == (Object)null && (Object)(object)_cachedInv != (Object)null) { try { Component componentInParent2 = ((Component)_cachedInv).gameObject.GetComponentInParent(Il2CppType.Of<PlayerStamina>()); if ((Object)(object)componentInParent2 != (Object)null) { _playerStamina = ((Il2CppObjectBase)componentInParent2).TryCast<PlayerStamina>(); } } catch { } } if ((Object)(object)_playerStamina != (Object)null) { try { _tiredness = Mathf.Clamp01(_playerStamina.TirednessRelative); _staminaRel = Mathf.Clamp01(_playerStamina.StaminaRelative); } catch { _playerStamina = null; } } if ((Object)(object)_playerDmg != (Object)null) { _healthRel = Mathf.Clamp01(_playerDmg.GetHealthRel()); int num = Mathf.Clamp(Mathf.FloorToInt(_healthRel * 100f / 20f), 0, 4); if (num != _healthStage) { _healthStage = num; Plugin.Log.LogInfo((object)$"low health stage -> {num} ({num * 20} HP band); {HealthHz[num]} Hz, peak {HealthPeak[num]}x"); } } } catch { _playerDmg = null; } } private void ComputeAlong() { //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Unknown result type (might be due to invalid IL or missing references) int count = _heldTargets.Count; if (count < 2) { for (int i = 0; i < count; i++) { _heldTargets[i].along = 0.5f; _heldTargets[i].alongDone = true; } Plugin.Log.LogInfo((object)$"along: only {count} gear target(s) - no axis to measure, using 0.5"); return; } _ = Vector3.zero; Transform val = null; try { val = _wieldedTf; } catch { } if ((Object)(object)val == (Object)null) { return; } Vector3[] array = (Vector3[])(object)new Vector3[count]; Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(float.MaxValue, float.MaxValue, float.MaxValue); Vector3 val3 = default(Vector3); ((Vector3)(ref val3))..ctor(float.MinValue, float.MinValue, float.MinValue); int num = 0; for (int j = 0; j < count; j++) { Renderer rend = _heldTargets[j].rend; if ((Object)(object)rend == (Object)null) { array[j] = Vector3.zero; continue; } try { Vector3 val4 = Vector3.zero; try { Bounds bounds = rend.bounds; val4 = ((Bounds)(ref bounds)).center; } catch { } if (val4 == Vector3.zero) { val4 = ((Component)rend).transform.position; } Vector3 val5 = (array[j] = val.InverseTransformPoint(val4)); val2 = Vector3.Min(val2, val5); val3 = Vector3.Max(val3, val5); num++; } catch { array[j] = Vector3.zero; } } if (num >= 2) { Vector3 val6 = val3 - val2; int num2 = 1; if (val6.x >= val6.y && val6.x >= val6.z) { num2 = 0; } else if (val6.z >= val6.x && val6.z >= val6.y) { num2 = 2; } float num3 = num2 switch { 1 => val2.y, 0 => val2.x, _ => val2.z, }; float num4 = num2 switch { 1 => val6.y, 0 => val6.x, _ => val6.z, }; if (num4 < 0.0001f) { num4 = 0.0001f; } for (int k = 0; k < count; k++) { float num5 = num2 switch { 1 => array[k].y, 0 => array[k].x, _ => array[k].z, }; _heldTargets[k].along = Mathf.Clamp01((num5 - num3) / num4); _heldTargets[k].alongDone = true; } string text = ""; for (int l = 0; l < count && l < 6; l++) { text += $" {_heldTargets[l].along:F2}"; } Plugin.Log.LogInfo((object)string.Format("along axis = {0} (extent {1:F4}) for {2} target(s); first values:{3}", num2 switch { 1 => "Y", 0 => "X", _ => "Z", }, num4, count, (text.Length > 0) ? text : " none")); } } private void PreparePerTargetState() { try { ComputeAlong(); } catch (Exception ex) { Plugin.Log.LogWarning((object)("PreparePerTargetState: " + ex.Message)); } } private static SlotKind Classify(Renderer r) { //IL_00a6: Unknown result type (might be due to invalid IL or missing references) try { Component componentInParent = ((Component)r).gameObject.GetComponentInParent(Il2CppType.Of<ItemEquippable>()); ItemEquippable val = (((Object)(object)componentInParent != (Object)null) ? ((Il2CppObjectBase)componentInParent).TryCast<ItemEquippable>() : null); if ((Object)(object)val == (Object)null) { return SlotKind.Other; } Component componentInParent2 = ((Component)val).gameObject.GetComponentInParent(Il2CppType.Of<PlayerInventoryBase>()); PlayerInventoryBase val2 = (((Object)(object)componentInParent2 != (Object)null) ? ((Il2CppObjectBase)componentInParent2).TryCast<PlayerInventoryBase>() : null); if ((Object)(object)val2 == (Object)null) { return SlotKind.Other; } if ((Object)(object)((Il2CppObjectBase)val2).TryCast<PlayerInventoryLocal>() == (Object)null) { return SlotKind.Other; } ItemEquippable wieldedItem = val2.WieldedItem; if ((Object)(object)wieldedItem == (Object)null || ((Il2CppObjectBase)wieldedItem).Pointer != ((Il2CppObjectBase)val).Pointer) { return SlotKind.Other; } return FromSlot(val2.WieldedSlot); } catch { return SlotKind.Other; } } private static SlotKind FromSlot(InventorySlot s) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Expected I4, but got Unknown return (int)s switch { 1 => SlotKind.Primary, 2 => SlotKind.Special, 3 => SlotKind.Tool, 10 => SlotKind.Melee, _ => SlotKind.Other, }; } private static string ClassifyVerbose(Renderer r) { //IL_0130: 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_011c: Expected I4, but got Unknown try { Component componentInParent = ((Component)r).gameObject.GetComponentInParent(Il2CppType.Of<ItemEquippable>()); ItemEquippable val = (((Object)(object)componentInParent != (Object)null) ? ((Il2CppObjectBase)componentInParent).TryCast<ItemEquippable>() : null); if ((Object)(object)val == (Object)null) { return "slot=Other (no ItemEquippable ancestor)"; } string text = "<unnamed>"; try { text = ((Object)((Component)val).gameObject).name; } catch { } Component componentInParent2 = ((Component)val).gameObject.GetComponentInParent(Il2CppType.Of<PlayerInventoryBase>()); PlayerInventoryBase val2 = (((Object)(object)componentInParent2 != (Object)null) ? ((Il2CppObjectBase)componentInParent2).TryCast<PlayerInventoryBase>() : null); if ((Object)(object)val2 == (Object)null) { return "slot=Other (item='" + text + "' has no PlayerInventoryBase ancestor)"; } bool flag = false; try { flag = (Object)(object)((Il2CppObjectBase)val2).TryCast<PlayerInventoryLocal>() != (Object)null; } catch { } string text2 = "?"; try { ItemEquippable wieldedItem = val2.WieldedItem; text2 = ((!((Object)(object)wieldedItem == (Object)null)) ? ((((Il2CppObjectBase)wieldedItem).Pointer == ((Il2CppObjectBase)val).Pointer) ? "THIS" : "other") : "none"); } catch (Exception ex) { text2 = "err:" + ex.GetType().Name; } int num = -1; try { num = (int)val2.WieldedSlot; } catch { } return $"slot={FromSlot(val2.WieldedSlot)} item='{text}' isLocalPlayer={flag} wielded={text2} rawWieldedSlot={num}"; } catch (Exception ex2) { return "slot=Other (classify threw " + ex2.GetType().Name + ")"; } } private void MergeTargets() { _targets.Clear(); _merged.Clear(); for (int i = 0; i < _scanCache.Count; i++) { AddMerged(_scanCache[i]); } for (int j = 0; j < _heldTargets.Count; j++) { AddMerged(_heldTargets[j]); } } private void AddMerged(Target t) { if (t == null) { return; } Renderer rend = t.rend; if ((Object)(object)rend == (Object)null) { return; } try { if (!_merged.Add(((Il2CppObjectBase)rend).Pointer.ToInt64())) { return; } } catch { return; } _targets.Add(t); } private void RefreshGear() { try { if ((Object)(object)_cachedInv == (Object)null) { if (Time.time < _nextInvRetry) { _wieldedTf = null; return; } _nextInvRetry = Time.time + 3f; _cachedInv = FindLocalInventory(); _invQueryCount++; if ((Object)(object)_cachedInv == (Object)null) { _wieldedTf = null; return; } _needScan = true; } ItemEquippable wieldedItem = ((PlayerInventoryBase)_cachedInv).WieldedItem; _wieldedTf = (((Object)(object)wieldedItem != (Object)null) ? ((Component)wieldedItem).transform : null); try { LogGearIfChanged(_heldTargets.Count, _scanCache.Count, _invQueryCount, ((Object)(object)wieldedItem == (Object)null) ? 1 : 0); } catch { } if ((Object)(object)wieldedItem == (Object)null) { if (_heldTargets.Count > 0) { ReleaseHeld(); MergeTargets(); } return; } int num = 0; try { num = ((Il2CppObjectBase)wieldedItem).Pointer.ToInt32(); } catch { } if (num == _cachedItemPtr && _heldTargets.Count > 0) { MergeTargets(); return; } _cachedItemPtr = num; ReleaseHeld(); try { Il2CppReferenceArray<Component> componentsInChildren = ((Component)wieldedItem).gameObject.GetComponentsInChildren(Il2CppType.Of<Renderer>(), true); if (componentsInChildren != null) { for (int i = 0; i < ((Il2CppArrayBase<Component>)(object)componentsInChildren).Length; i++) { Component val = ((Il2CppArrayBase<Component>)(object)componentsInChildren)[i]; if ((Object)(object)val == (Object)null) { continue; } Renderer val2 = ((Il2CppObjectBase)val).TryCast<Renderer>(); if (!((Object)(object)val2 == (Object)null)) { Target target = TryMakeTarget(val2, SlotKind.Other, classifySlot: false, ownerIsPlayer: true); if (target != null) { _heldTargets.Add(target); } } } } } catch { } PreparePerTargetState(); MergeTargets(); } catch { _cachedInv = null; _wieldedTf = null; } } private static PlayerInventoryLocal FindLocalInventory() { PlayerInventoryLocal val = QueryInvs(Il2CppType.Of<PlayerInventoryLocal>()); if ((Object)(object)val != (Object)null) { return val; } try { Il2CppReferenceArray<Object> val2 = Resources.FindObjectsOfTypeAll(Il2CppType.Of<PlayerInventoryBase>()); Plugin.Log.LogWarning((object)$"no PlayerInventoryLocal found (FindObjectsOfType=empty, FindObjectsOfTypeAll(PlayerInventoryBase) returned {((Il2CppArrayBase<Object>)(object)val2)?.Length ?? (-1)})"); } catch (Exception ex) { Plugin.Log.LogWarning((object)("inventory probe failed: " + ex.Message)); } return null; } private static PlayerInventoryLocal QueryInvs(Type t) { try { Il2CppReferenceArray<Object> val = Object.FindObjectsOfType(t); if (val != null) { for (int i = 0; i < ((Il2CppArrayBase<Object>)(object)val).Length; i++) { Object val2 = ((Il2CppArrayBase<Object>)(object)val)[i]; if (!(val2 == (Object)null)) { PlayerInventoryLocal val3 = ((Il2CppObjectBase)val2).TryCast<PlayerInventoryLocal>(); if ((Object)(object)val3 != (Object)null) { return val3; } } } } } catch (Exception ex) { Plugin.Log.LogWarning((object)("FindObjectsOfType(PlayerInventoryLocal): " + ex.Message)); } try { Il2CppReferenceArray<Object> val4 = Resources.FindObjectsOfTypeAll(t); if (val4 != null) { for (int j = 0; j < ((Il2CppArrayBase<Object>)(object)val4).Length; j++) { Object val5 = ((Il2CppArrayBase<Object>)(object)val4)[j]; if (!(val5 == (Object)null)) { PlayerInventoryLocal val6 = ((Il2CppObjectBase)val5).TryCast<PlayerInventoryLocal>(); if ((Object)(object)val6 != (Object)null) { return val6; } } } } } catch (Exception ex2) { Plugin.Log.LogWarning((object)("FindObjectsOfTypeAll(PlayerInventoryLocal): " + ex2.Message)); } return null; } private void ReleaseHeld() { //IL_0043: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < _heldTargets.Count; i++) { Renderer rend = _heldTargets[i].rend; if (!((Object)(object)rend == (Object)null)) { try { rend.GetPropertyBlock(_mpb); _mpb.SetColor("_EmissiveColor", _heldTargets[i].baseColor); rend.SetPropertyBlock(_mpb); } catch { } } } _heldTargets.Clear(); } private void LogGearIfChanged(int matched, int seen, int invs, int wieldedNull) { string text = matched + "/" + seen + "/" + _lastGearPtr + "/" + invs + "/" + wieldedNull; if (!(text == _lastGearSig)) { _lastGearSig = text; StringBuilder stringBuilder = new StringBuilder(); for (int i = 0; i < _heldTargets.Count; i++) { stringBuilder.Append(_heldTargets[i].slot).Append(' '); } Plugin.Log.LogInfo((object)$"gear: {matched} held of {seen} cached; slots=[{stringBuilder.ToString().Trim()}]; inventoryFound={invs} wieldedNull={wieldedNull} finds={_invQueryCount} targets={_targets.Count}"); } } private static void RefreshExclusions() { string text = Plugin.CfgExcludeNames.Value ?? ""; if (text == _exclRaw) { return; } _exclRaw = text; List<string> list = new List<string>(); string[] array = text.Split(new char[3] { ' ', ',', ';' }, StringSplitOptions.RemoveEmptyEntries); foreach (string text2 in array) { if (text2.Length > 0) { list.Add(text2); } } _excl = list.ToArray(); } private static bool IsEquipment(Renderer r) { try { GameObject gameObject = ((Component)r).gameObject; if ((Object)(object)gameObject.GetComponentInParent(Il2CppType.Of<ItemEquippable>()) != (Object)null) { return true; } if ((Object)(object)gameObject.GetComponentInParent(Il2CppType.Of<PlayerAgent>()) != (Object)null) { return true; } return false; } catch { return false; } } private static bool IsExcluded(Renderer r, Material m) { if (_excl.Length == 0) { return false; } for (int i = 0; i < _excl.Length; i++) { string value = _excl[i]; string text = null; try { if ((Object)(object)m != (Object)null) { text = ((Object)m).name; } } catch { } if (text != null && text.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0) { return true; } Transform val = null; try { val = ((Component)r).transform; } catch { } for (int j = 0; j < 5; j++) { if (!((Object)(object)val != (Object)null)) { break; } string text2 = null; try { text2 = ((Object)((Component)val).gameObject).name; } catch { } if (text2 != null && text2.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0) { return true; } try { val = val.parent; } catch { val = null; } } } return false; } private static string Describe(Renderer r) { try { Transform val = null; try { val = ((Component)r).transform; } catch { } string text = (((Object)(object)val != (Object)null) ? ((Object)((Component)val).gameObject).name : "?"); try { val = val.parent; } catch { val = null; } for (int i = 0; i < 3; i++) { if (!((Object)(object)val != (Object)null)) { break; } text = ((Object)((Component)val).gameObject).name + "/" + text; try { val = val.parent; } catch { val = null; } } return text; } catch { return "?"; } } private static void NoteScenery(Renderer r, Material m) { try { } catch { } } private static void NoteExcluded(Renderer r, Material m) { try { } catch { } } private static void NoteMatched(Renderer r, Material m) { try { } catch { } } private Target TryMakeTarget(Renderer r, SlotKind slot, bool classifySlot, bool ownerIsPlayer) { //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) long key = 0L; bool flag = false; try { key = ((Il2CppObjectBase)r).Pointer.ToInt64(); flag = true; } catch { } if (flag && _known.TryGetValue(key, out var value)) { if (value != null && (Object)(object)value.rend != (Object)null) { return value; } _known.Remove(key); } RefreshExclusions(); Material val = null; try { val = r.sharedMaterial; } catch { return null; } if ((Object)(object)val == (Object)null) { return null; } string text = Plugin.CfgShaderFilter.Value ?? ""; string text2 = ""; try { if ((Object)(object)val.shader != (Object)null) { text2 = ((Object)val.shader).name; } } catch { } if (text.Length > 0 && text2.IndexOf(text, StringComparison.OrdinalIgnoreCase) < 0) { return null; } bool flag2 = false; try { flag2 = val.HasProperty("_EmissiveColor"); } catch { } if (!flag2) { return null; } if (Plugin.CfgRequireEmissiveMap.Value) { bool flag3 = false; try { flag3 = (Object)(object)val.GetTexture("_EmissiveMap") != (Object)null; } catch { } if (!flag3) { return null; } } if (!ownerIsPlayer && Plugin.CfgEquipmentOnly.Value && !IsEquipment(r)) { NoteScenery(r, val); return null; } if (IsExcluded(r, val)) { NoteExcluded(r, val); return null; } if (classifySlot) { try { slot = Classify(r); } catch { } } Color color; try { color = val.GetColor("_EmissiveColor"); } catch { return null; } NoteMatched(r, val); Target target = new Target(); target.rend = r; target.baseColor = color; target.slot = slot; target.phase = Random.value; target.sparkTimer = Random.Range(0.2f, 2f); target.along = NextAlong(); target.alongDone = true; if (flag) { _known[key] = target; if (_known.Count > 4000) { _known.Clear(); } } return target; } private void Scan() { _scanCache.Clear(); _owners = 0; int seen = 0; try { float realtimeSinceStartup = Time.realtimeSinceStartup; AddFromQuery(Il2CppType.Of<ItemEquippable>(), ref seen); AddFromQuery(Il2CppType.Of<PlayerAgent>(), ref seen); MergeTargets(); float num = (Time.realtimeSinceStartup - realtimeSinceStartup) * 1000f; Plugin.Log.LogInfo((object)$"scan: {_owners} owner(s), {seen} renderer(s), {_scanCache.Count} in scene, {_heldTargets.Count} held, {_targets.Count} merged, took {num:F0} ms"); } catch (Exception ex) { Plugin.Log.LogError((object)("scan failed: " + ex)); } } private void AddFromQuery(Type type, ref int seen) { try { Il2CppReferenceArray<Object> val = Resources.FindObjectsOfTypeAll(type); if (val == null) { return; } for (int i = 0; i < ((Il2CppArrayBase<Object>)(object)val).Length; i++) { Object val2 = ((Il2CppArrayBase<Object>)(object)val)[i]; if (val2 == (Object)null) { continue; } Component val3 = null; try { val3 = ((Il2CppObjectBase)val2).TryCast<Component>(); } catch { } if ((Object)(object)val3 == (Object)null) { continue; } GameObject val4 = null; try { val4 = val3.gameObject; } catch { } if ((Object)(object)val4 == (Object)null) { continue; } _owners++; try { Component componentInParent = val4.GetComponentInParent(Il2CppType.Of<PlayerInventoryBase>()); if ((Object)(object)componentInParent != (Object)null) { PlayerInventoryBase val5 = ((Il2CppObjectBase)componentInParent).TryCast<PlayerInventoryBase>(); PlayerInventoryLocal val6 = (((Object)(object)val5 != (Object)null) ? ((Il2CppObjectBase)val5).TryCast<PlayerInventoryLocal>() : null); if ((Object)(object)val6 != (Object)null) { bool flag = false; try { flag = (Object)(object)((PlayerInventoryBase)val6).WieldedItem != (Object)null; } catch { } bool flag2 = (Object)(object)_cachedInv == (Object)null; if (!flag2 && flag) { try { flag2 = ((Il2CppObjectBase)_cachedInv).Pointer != ((Il2CppObjectBase)val6).Pointer; } catch { flag2 = false; } } if (flag2) { _cachedInv = val6; _cachedItemPtr = 0; Plugin.Log.LogInfo((object)("[scan] local inventory captured from '" + ((Object)val4).name + "' wielded=" + (flag ? "yes" : "no"))); } } } } catch { } try { Il2CppReferenceArray<Component> componentsInChildren = val4.GetComponentsInChildren(Il2CppType.Of<Renderer>(), true); if (componentsInChildren == null) { continue; } for (int j = 0; j < ((Il2CppArrayBase<Component>)(object)componentsInChildren).Length; j++) { Component val7 = ((Il2CppArrayBase<Component>)(object)componentsInChildren)[j]; if ((Object)(object)val7 == (Object)null) { continue; } Renderer val8 = ((Il2CppObjectBase)val7).TryCast<Renderer>(); if (!((Object)(object)val8 == (Object)null)) { seen++; Target target = TryMakeTarget(val8, SlotKind.Other, classifySlot: false, ownerIsPlayer: true); if (target != null) { _scanCache.Add(target); } } } } catch { } } } catch (Exception e) { LogOnce("scan query", e); } } private void ClearOverrides() { //IL_0043: 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) try { for (int i = 0; i < _targets.Count; i++) { Renderer rend = _targets[i].rend; if (!((Object)(object)rend == (Object)null)) { try { rend.GetPropertyBlock(_mpb); _mpb.SetColor("_EmissiveColor", _targets[i].baseColor); rend.SetPropertyBlock(_mpb); } catch { } } } for (int j = 0; j < _heldTargets.Count; j++) { Renderer rend2 = _heldTargets[j].rend; if (!((Object)(object)rend2 == (Object)null)) { try { rend2.GetPropertyBlock(_mpb); _mpb.SetColor("_EmissiveColor", _heldTargets[j].baseColor); rend2.SetPropertyBlock(_mpb); } catch { } } } } catch (Exception ex) { Plugin.Log.LogError((object)("clear failed: " + ex)); } } } public static class SettingsPage { private class BoolRow { public TextMeshPro label; public Func<bool> getter; } private static readonly Color Accent = new Color(0.42f, 0.86f, 0.75f, 1f); private const string PageLabel = "效果"; private static CM_PageSettings _page; private static CM_ScrollWindow _window; private static readonly List<BoolRow> _rows = new List<BoolRow>(); private static CM_Item _button; private static TextMeshPro _buttonTmp; public static CM_SettingsInputField ColorInputField; public static string ColorInputLastAccepted = ""; private static GameObject _colorPopupRoot; internal static CM_ScrollWindow _pageWindow; private static readonly List<GameObject> _colorPopupItems = new List<GameObject>(); public static bool HexEditing; private static string _hexBuffer = ""; private static float _lastHexStop; private static readonly List<TextMeshPro> _hexDisplayTmps = new List<TextMeshPro>(); private static readonly KeyCode[] _hexKeyMap; private static readonly string[] _hexKeyChar; private static GameObject _ddEntryPrefab; private static CM_SettingsStringArrayDropdownButton _ddWrapper; private static TextMeshPro _ddValueText; private static CM_ScrollWindow _colorSubWin; private static readonly List<TextMeshPro> _colorSubRowTmps; private static readonly List<RectTransform> _colorSubRowRTs; private static bool _level3Open; private static float _lastSubClose; public static bool IsColorPanelOpen => _level3Open; [HarmonyPatch(typeof(CM_PageSettings), "Setup")] [HarmonyPostfix] [HarmonyWrapSafe] [HarmonyPriority(600)] public static void Postfix_Setup(CM_PageSettings __instance) { try { if (Plugin.Log != null) { Build(__instance); } } catch (Exception ex) { if (Plugin.Log != null) { Plugin.Log.LogError((object)("[settings] build failed: " + ex)); } } } private static void Build(CM_PageSettings page) { //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)page == (Object)null) { return; } if ((Object)(object)_window != (Object)null) { _page = page; return; } _page = page; _rows.Clear(); CM_Item val = null; try { val = page.CreateSingleButton(page.m_subMenuButtonPrefab, 0u); if ((Object)(object)val != (Object)null) { StyleButton(val, "效果"); } } catch (Exception ex) { Plugin.Log.LogError((object)("[settings] CreateSingleButton failed: " + ex)); } if ((Object)(object)val == (Object)null) { Plugin.Log.LogWarning((object)"[settings] no sidebar button - tab will not appear"); return; } CM_ScrollWindow window = null; try { RectTransformComp val2 = ((GuiLayer)((CM_PageBase)page).m_guiLayer).AddRectComp(page.m_scrollwindowPrefab, (GuiAnchor)1, new Vector2(420f, -200f), (Transform)(object)((CM_PageBase)page).m_movingContentHolder); window = ((Il2CppObjectBase)val2).TryCast<CM_ScrollWindow>(); } catch (Exception ex2) { Plugin.Log.LogError((object)("[settings] AddRectComp failed: " + ex2)); } if ((Object)(object)window == (Object)null) { Plugin.Log.LogWarning((object)"[settings] no content window - tab will not appear"); return; } try { window.Setup(((Component)page).transform); ((RectTransformComp)window).SetSize(new Vector2(1020f, 900f)); ((RectTransformComp)window).SetVisible(false); page.m_allSettingsWindows.Add(window); try { Il2CppReferenceArray<CM_ScrollWindowHeader> headers = window.m_headers; if (headers != null && ((Il2CppArrayBase<CM_ScrollWindowHeader>)(object)headers).Length > 0) { CM_ScrollWindowHeader val3 = ((Il2CppArrayBase<CM_ScrollWindowHeader>)(object)headers)[0]; if ((Object)(object)val3 != (Object)null) { TextMeshPro componentInChildren = ((Component)val3).GetComponentInChildren<TextMeshPro>(); if ((Object)(object)componentInChildren != (Object)null) { ((TMP_Text)componentInChildren).SetText("效果", true); } } } } catch (Exception ex3) { Plugin.Log.LogWarning((object)("[settings] header text: " + ex3.Message)); } Populate(page, window); _window = window; Action<int> onClick = delegate { try { CloseColorPopup(); page.ResetAllInputFields(); page.ResetAllValueHolders(); page.m_currentSubMenuId = (eSettingsSubMenuId)0; SwapTo(page, window); } catch (Exception ex5) { Plugin.Log.LogError((object)("[settings] switch failed: " + ex5)); } }; WireClick(val, onClick); Plugin.Log.LogInfo((object)"[settings] 呼吸 page added"); } catch (Exception ex4) { Plugin.Log.LogError((object)("[settings] window setup failed: " + ex4)); } } private static void Populate(CM_PageSettings page, CM_ScrollWindow window) { try { _rows.Clear(); } catch { } ColorInputField = null; _ddEntryPrefab = null; _ddWrapper = null; _ddValueText = null; try { if ((Object)(object)_colorSubWin != (Object)null) { Object.Destroy((Object)(object)((Component)_colorSubWin).gameObject); } } catch { } _colorSubWin = null; _colorSubRowTmps.Clear(); _level3Open = false; _colorPopupItems.Clear(); List<iScrollWindowContent> val = new List<iScrollWindowContent>(); AddHeader(page, window, val, "弹轨(独立)"); AddToggle(page, window, val, "弹轨特效", "开火时从枪口到命中点画一条细的发光能量束,约 1.5 秒淡出。\n颜色用下面两行选;时长 / 宽度在配置文件的 [Trajectory] 段改。", () => TrajectoryCfg.Enabled.Value, delegate(bool v) { TrajectoryCfg.Enabled.Value = v; }); AddColorDropdownV3(page, window, val, "弹轨颜色 >", "点开在右侧浮出 14 个预设色,点一下即选中,下一枪生效;再点一次收起。\n★ 想用任意颜色:用下面的「弹轨颜色代码」。"); AddColorInput(page, window, val, "弹轨颜色代码", "点一下进入输入状态,直接键入十六进制(0-9 / A-F)。\n★ Enter 确认,Esc 取消,Backspace 删格;输满 6 位实时预览颜色。"); AddHeader(page, window, val, "总开关"); AddToggle(page, window, val, "总开关", "", () => Plugin.CfgEnabled.Value, delegate(bool v) { Plugin.CfgEnabled.Value = v; }); AddHeader(page, window, val, "扫描"); AddToggle(page, window, val, "关闭扫描", "完全关闭扫描,彻底避免扫描带来的卡顿。\n效果仍会显示,但不再自动更新。", () => IsScanMode("Off"), delegate(bool v) { SetScanMode(v ? "Off" : "Test"); }); AddToggle(page, window, val, "效果尝试扫描", "持续扫描,响应最快。\n★ 会占用帧率,可能有卡顿风险。", () => IsScanMode("Test"), delegate(bool v) { if (!IsScanMode("Off")) { SetScanMode(v ? "Test" : "Confirmed"); } }); AddToggle(page, window, val, "手动确认扫描", "选好效果后点一下,执行一次完整扫描并固定下来。\n★ 此后不再自动扫描;扫描完成后开关自动弹回。", () => Plugin.ManualScanPending, delegate(bool v) { if (v && !IsScanMode("Off")) { Plugin.CfgScanMode.Value = "Confirmed"; Plugin.ManualScanPending = true; Plugin.NeedScan = true; } }); AddHeader(page, window, val, "基础"); AddEffect(page, window, val, "常亮", "Solid"); AddEffect(page, window, val, "呼吸", "Breathing"); AddEffect(page, window, val, "警报", "Alarm"); AddEffect(page, window, val, "故障闪烁", "Flicker"); AddEffect(page, window, val, "充能", "Charge"); AddEffect(page, window, val, "色相流动", "Hue"); AddHeader(page, window, val, "逐部件"); AddEffect(page, window, val, "星空闪烁", "Twinkle"); AddEffect(page, window, val, "随机火花", "Sparks"); AddEffect(page, window, val, "噪声流动", "NoiseDrift"); AddEffect(page, window, val, "反相呼吸", "AntiPhase"); AddHeader(page, window, val, "位置"); AddEffect(page, window, val, "流光扫描", "Sweep"); AddEffect(page, window, val, "逐段轮转", "Chase"); AddEffect(page, window, val, "前后渐变", "Gradient"); AddEffect(page, window, val, "彩虹分布", "Rainbow"); AddHeader(page, window, val, "颜色"); AddEffect(page, window, val, "炽热", "Heat"); AddEffect(page, window, val, "冷焰", "ColdFire"); AddEffect(page, window, val, "余烬", "Ember"); AddHeader(page, window, val, "状态"); AddEffect(page, window, val, "心跳", "Heartbeat"); AddEffect(page, window, val, "低血量警示", "LowHealth"); try { window.SetContentItems(val, 5f); } catch (Exception ex) { Plugin.Log.LogError((object)("[settings] SetContentItems failed: " + ex)); } } private static CM_SettingsItem CreateItem(CM_PageSettings page, CM_ScrollWindow window, List<iScrollWindowContent> items, string label) { if ((Object)(object)page.m_settingsItemPrefab == (Object)null) { return null; } GameObject val = Object.Instantiate<GameObject>(page.m_settingsItemPrefab, ((Component)window).transform); if ((Object)(object)val == (Object)null) { return null; } CM_SettingsItem component = val.GetComponent<CM_SettingsItem>(); if ((Object)(object)component == (Object)null) { return null; } try { ((CM_Item)component).TextMeshRoot = ((Component)page).transform; } catch { } try { Transform val2 = val.transform.Find("Title/TitleText"); TextMeshPro val3 = (((Object)(object)val2 != (Object)null) ? ((Component)val2).GetComponent<TextMeshPro>() : null); if ((Object)(object)val3 != (Object)null) { ((TMP_Text)val3).SetText(label, true); } else { ((CM_Item)component).SetText(label); } } catch { try { ((CM_Item)component).SetText(label); } catch { } } try { ((RectTransformComp)component).ForcePopupLayer(true, (GameObject)null); } catch { } try { iScrollWindowContent val4 = ((Il2CppObjectBase)component).TryCast<iScrollWindowContent>(); if (val4 != null) { items.Add(val4); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[settings] item cast failed: " + ex.Message)); } return component; } public static void Tick() { //IL_0064: Unknown result type (might be due to invalid IL or missing references) try { if (!((Object)(object)_buttonTmp == (Object)null) && !((Object)(object)_button == (Object)null)) { string text = null; try { text = ((TMP_Text)_buttonTmp).text; } catch { } if (text != "效果") { ((TMP_Text)_buttonTmp).SetText("效果", true); ((Graphic)_buttonTmp).color = new Color(1f, 1f, 1f, 1f); } } } catch { } } private static void StyleButton(CM_Item item, string label) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) TextMeshPro val = null; int num = -1; try { val = ((Component)item).GetComponentInChildren<TextMeshPro>(true); if ((Object)(object)val != (Object)null) { ((TMP_Text)val).SetText(label, true); ((Graphic)val).color = new Color(1f, 1f, 1f, 1f); _button = item; _buttonTmp = val; } else { item.SetText(label); } } catch (Exception ex) { if (Plugin.Log != null) { Plugin.Log.LogWarning((object)("[settings] button text failed: " + ex.Message)); } } try { Color val2 = default(Color); ((Color)(ref val2))..ctor(1f, 1f, 1f, 1f); item.m_spriteColorOrg = val2; item.m_spriteColorOut = new Color(1f, 1f, 1f, item.m_spriteAlphaOut); item.m_spriteColorOver = new Color(1f, 1f, 1f, item.m_spriteAlphaOver); Il2CppReferenceArray<TextMeshPro> texts = item.m_texts; num = ((Il2CppArrayBase<TextMeshPro>)(object)texts)?.Length ?? (-1); if (texts != null) { for (int i = 0; i < ((Il2CppArrayBase<TextMeshPro>)(object)texts).Length; i++) { ((Il2CppArrayBase<Color>)(object)item.m_textColorOrg)[i] = val2; ((Il2CppArrayBase<Color>)(object)item.m_textColorOut)[i] = new Color(1f, 1f, 1f, item.m_textAlphaOut); ((Il2CppArrayBase<Color>)(object)item.m_textColorOver)[i] = new Color(1f, 1f, 1f, item.m_textAlphaOver); } } item.OnHoverOut(); } catch (Exception ex2) { if (Plugin.Log != null) { Plugin.Log.LogWarning((object)("[settings] button colour failed: " + ex2.Message)); } } if (Plugin.Log == null) { return; } string text = "?"; bool flag = false; string text2 = "?"; if ((Object)(object)val != (Object)null) { try { text = ((Object)((Component)val).gameObject).name; } catch { } try { flag = ((Component)val).gameObject.activeInHierarchy; } catch { } try { text2 = ((TMP_Text)val).text; } catch { } } Plugin.Log.LogInfo((object)$"[settings] button styled: tmp={(Object)(object)val != (Object)null} name='{text}' active={flag} textAfter='{text2}' m_texts={num} alphaOut={item.m_textAlphaOut}"); } private static void AddHeader(CM_PageSettings page, CM_ScrollWindow window, List<iScrollWindowContent> items, string label) { //IL_0041: 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_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) try { CM_SettingsItem val = CreateItem(page, window, items, label); if ((Object)(object)val == (Object)null) { return; } try { ((Renderer)val.m_background).enabled = false; } catch { } RectTransform component = ((Component)val).gameObject.GetComponent<RectTransform>(); if ((Object)(object)component != (Object)null) { component.sizeDelta = new Vector2(component.sizeDelta.x, component.sizeDelta.y * 1.5f); } try { Transform val2 = ((Component)val).transform.Find("Title/TitleText"); TextMeshPro val3 = (((Object)(object)val2 != (Object)null) ? ((Component)val2).GetComponent<TextMeshPro>() : null); if ((Object)(object)val3 != (Object)null) { ((Graphic)val3).color = Accent; ((TMP_Text)val3).alignment = (TextAlignmentOptions)513; ((TMP_Text)val3).fontSizeMax = ((TMP_Text)val3).fontSizeMax * 1.5f; } } catch { } try { BoxCollider2D component2 = ((Component)val).gameObject.GetComponent<BoxCollider2D>(); if ((Object)(object)component2 != (Object)null) { ((Behaviour)component2).enabled = false; } } catch { } } catch (Exception ex) { Plugin.Log.LogError((object)("[settings] AddHeader failed: " + ex)); } } private static bool IsScanMode(string id) { try { return string.Equals(Plugin.CfgScanMode.Value, id, StringComparison.OrdinalIgnoreCase); } catch { return false; } } private static void SetScanMode(string id) { try { Plugin.CfgScanMode.Value = id; Plugin.NeedScan = true; Plugin.Log.LogInfo((object)("[settings] scan mode -> " + id)); } catch (Exception ex) { Plugin.Log.LogError((object)("[settings] SetScanMode: " + ex)); } } private static void AddEffect(CM_PageSettings page, CM_ScrollWindow window, List<iScrollWindowContent> items, string label, string modeId) { AddToggle(page, window, items, label, "", () => string.Equals(Plugin.CfgMode.Value, modeId, StringComparison.OrdinalIgnoreCase), delegate { Plugin.CfgMode.Value = modeId; RefreshRows(); }); } public static void RefreshRows() { for (int i = 0; i < _rows.Count; i++) { Refresh(_rows[i]); } } private static string[] TrajColorNames() { try { return TrajectoryBehaviour.PresetNames; } catch { return new string[0]; } } private static string[] TrajColorHexes() { try { return TrajectoryBehaviour.PresetHexes; } catch { return new string[0]; } } private static int TrajColorIndex() { try { string[] array = TrajColorHexes(); string text = (TrajectoryCfg.ColorHex.Value ?? "").Trim().ToUpperInvariant(); for (int i = 0; i < array.Length; i++) { if (array[i].ToUpperInvariant() == text) { return i; } } } catch { } return 0; } private static void AddColorDropdown(CM_PageSettings page, CM_ScrollWindow window, List<iScrollWindowContent> items, string label, string tooltip) { //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Expected O, but got Unknown try { CM_SettingsItem val = CreateItem(page, window, items, label); if ((Object)(object)val == (Object)null) { Plugin.Log.LogError((object)"[settings] dd: CreateItem null"); return; } GameObject val2 = null; try { val2 = Object.Instantiate<GameObject>(val.m_stringArrayDropdownInputPrefab, val.m_inputAlign, false); } catch (Exception ex) { Plugin.Log.LogError((object)("[settings] dd instantiate: " + ex.Message)); } if ((Object)(object)val2 != (Object)null) { DumpPrefabComponents("stringArrayDropdown", val2); try { Plugin.Log.LogInfo((object)("[settings] dd prefab root = " + ((Object)val2).name)); } catch { } try { Component componentInChildren = val2.GetComponentInChildren(Il2CppType.Of<CM_DropdownButton_StringArray>()); CM_DropdownButton_StringArray val3 = (((Object)(object)componentInChildren != (Object)null) ? ((Il2CppObjectBase)componentInChildren).TryCast<CM_DropdownButton_StringArray>() : null); if ((Object)(object)val3 == (Object)null) { Plugin.Log.LogError((object)"[settings] dd: component not found on prefab"); } else { string[] array = TrajColorNames(); string[] hexes = TrajColorHexes(); val3.SetStrings(Il2CppStringArray.op_Implicit(array)); val3.SetStartValue((uint)TrajColorIndex()); val3.OnSelectionChanged = Action<int>.op_Implicit((Action<int>)delegate(int idx) { try { if (idx >= 0 && idx < hexes.Length) { TrajectoryCfg.ColorHex.Value = hexes[idx]; Plugin.Log.LogInfo((object)("[settings] traj color -> " + hexes[idx])); } } catch { } }); Plugin.Log.LogInfo((object)("[settings] color dropdown added (" + array.Length + " colors)")); } } catch (Exception ex2) { Plugin.Log.LogError((object)("[settings] dd setup: " + ex2.Message)); } } if (!string.IsNullOrEmpty(tooltip)) { try { ((CM_Item)val).TooltipInfo = new TooltipInfo { PositionType = (TooltipPositionType)1, TooltipHeader = label, TooltipText = tooltip, UseTooptip = true }; } catch { } } try { GameObject val4 = Object.Instantiate<GameObject>(val.m_colorInputPrefab, val.m_inputAlign, false); if ((Object)(object)val4 != (Object)null) { DumpPrefabComponents("colorInput", val4); Object.Destroy((Object)(object)val4); } } catch (Exception ex3) { Plugin.Log.LogWarning((object)("[dd] colorInput instantiate: " + ex3.Message)); } try { GameObject val5 = Object.Instantiate<GameObject>(val.m_enumDropdownInputPrefab, val.m_inputAlign, false); if ((Object)(object)val5 != (Object)null) { DumpPrefabComponents("enumDropdown", val5); Object.Destroy((Object)(object)val5); } } catch (Exception ex4) { Plugin.Log.LogWarning((object)("[dd] enumDropdown instantiate: " + ex4.Message)); } try { GameObject val6 = Object.Instantiate<GameObject>(val.m_textInputPrefab, val.m_inputAlign, false); if ((Object)(object)val6 != (Object)null) { DumpPrefabComponents("textInput", val6); Object.Destroy((Object)(object)val6); } } catch (Exception ex5) { Plugin.Log.LogWarning((object)("[dd] textInput instantiate: " + ex5.Message)); } } catch (Exception ex6) { Plugin.Log.LogError((object)("[settings] AddColorDropdown: " + ex6)); } } private static void AddColorDropdownV2(CM_PageSettings page, CM_ScrollWindow window, List<iScrollWindowContent> items, string label, string tooltip) { //IL_0dd9: Unknown result type (might be due to invalid IL or missing references) //IL_0dde: Unknown result type (might be due to invalid IL or missing references) //IL_05bc: Unknown result type (might be due to invalid IL or missing references) //IL_05c3: Expected O, but got Unknown //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_1311: Unknown result type (might be due to invalid IL or missing references) //IL_1316: Unknown result type (might be due to invalid IL or missing references) //IL_1332: Unknown result type (might be due to invalid IL or missing references) //IL_1337: Unknown result type (might be due to invalid IL or missing references) //IL_1353: Unknown result type (might be due to invalid IL or missing references) //IL_1358: Unknown result type (might be due to invalid IL or missing references) //IL_147a: Unknown result type (might be due to invalid IL or missing references) //IL_147f: Unknown result type (might be due to invalid IL or missing references) //IL_1486: Unknown result type (might be due to invalid IL or missing references) //IL_148d: Unknown result type (might be due to invalid IL or missing references) //IL_1495: Unknown result type (might be due to invalid IL or missing references) //IL_14a1: Expected O, but got Unknown //IL_11e3: Unknown result type (might be due to invalid IL or missing references) //IL_11e8: Unknown result type (might be due to invalid IL or missing references) //IL_11fe: Unknown result type (might be due to invalid IL or missing references) //IL_1203: Unknown result type (might be due to invalid IL or missing references) try { CM_SettingsItem val = CreateItem(page, window, items, label); if ((Object)(object)val == (Object)null) { Plugin.Log.LogError((object)"[dd2] CreateItem null"); return; } GameObject val2 = null; try { val2 = Object.Instantiate<GameObject>(val.m_stringArrayDropdownInputPrefab, val.m_inputAlign, false); } catch (Exception ex) { Plugin.Log.LogError((object)("[dd2] instantiate: " + ex.Message)); } if ((Object)(object)val2 == (Object)null) { return; } _pageWindow = window; try { CM_Item val3 = val2.AddComponent<CM_Item>(); if ((Object)(object)val3 != (Object)null) { try { RectTransform rectTrans = ((RectTransformComp)val3).RectTrans; rectTrans.anchoredPosition3D = new Vector3(-300f, 25f, 100.1f); rectTrans.sizeDelta = new Vector2(600f, 50f); Plugin.Log.LogInfo((object)"[dd2] aligned to toggle rect (z=100.1)"); } catch (Exception ex2) { Plugin.Log.LogWarning((object)("[dd2] pos: " + ex2.Message)); } try { BoxCollider2D component = val2.GetComponent<BoxCollider2D>(); if ((Object)(object)component != (Object)null) { component.size = new Vector2(550f, 50f); ((Collider2D)component).offset = new Vector2(250f, -25f); } } catch { } try { Collider2D componentInChildren = ((Component)val3).GetComponentInChildren<Collider2D>(); if ((Object)(object)componentInChildren != (Object)null) { ((Behaviour)componentInChildren).enabled = false; } } catch { } Plugin.Log.LogInfo((object)"[dd2] CM_Item added + positioned"); } else { Plugin.Log.LogError((object)"[dd2] AddComponent<CM_Item> returned null"); } } catch (Exception ex3) { Plugin.Log.LogError((object)("[dd2] CM_Item: " + ex3.Message)); } DumpRT("dropdown", val2.transform); CM_SettingsStringArrayDropdownButton wrapper = null; try { Component componentInChildren2 = val2.GetComponentInChildren(Il2CppType.Of<CM_SettingsStringArrayDropdownButton>()); wrapper = (((Object)(object)componentInChildren2 != (Object)null) ? ((Il2CppObjectBase)componentInChildren2).TryCast<CM_SettingsStringArrayDropdownButton>() : null); } catch (Exception ex4) { Plugin.Log.LogWarning((object)("[dd2] wrapper: " + ex4.Message)); } Plugin.Log.LogInfo((object)("[dd2] wrapper found = " + ((Object)(object)wrapper != (Object)null))); CM_DropdownButton_StringArray dd = null; try { Component val4 = val2.AddComponent(Il2CppType.Of<CM_DropdownButton_StringArray>()); dd = (((Object)(object)val4 != (Object)null) ? ((Il2CppObjectBase)val4).TryCast<CM_DropdownButton_StringArray>() : null); } catch (Exception ex5) { Plugin.Log.LogError((object)("[dd2] AddComponent: " + ex5.Message)); } if ((Object)(object)dd == (Object)null) { Plugin.Log.LogError((object)"[dd2] dropdown component null"); return; } if ((Object)(object)wrapper != (Object)null) { try { dd.m_popupItemPrefab = wrapper.m_popupItemPrefab; } catch (Exception ex6) { Plugin.Log.LogWarning((object)("[dd2] popupItemPrefab: " + ex6.Message)); } try { dd.m_popupWindowAlign = wrapper.m_popupWindowAlign; } catch (Exception ex7) { Plugin.Log.LogWarning((object)("[dd2] popupWindowAlign: " + ex7.Message)); } try { dd.m_basePage = (CM_PageBase)(object)wrapper.m_basePage; } catch { } try { dd.m_popupWindow = wrapper.m_popupWindow; } catch { } try { dd.m_currentValue = wrapper.m_currentValue; Plugin.Log.LogInfo((object)("[dd2] m_currentValue copied = " + ((Object)(object)dd.m_currentValue != (Object)null))); } catch (Exception ex8) { Plugin.Log.LogWarning((object)("[dd2] currentValue: " + ex8.Message)); } } if ((Object)(object)dd.m_currentValue == (Object)null) { try { Component componentInChildren3 = val2.GetComponentInChildren(Il2CppType.Of<TextMeshPro>()); TextMeshPro val5 = (((Object)(object)componentInChildren3 != (Object)null) ? ((Il2CppObjectBase)componentInChildren3).TryCast<TextMeshPro>() : null); if ((Object)(object)val5 != (Object)null) { dd.m_currentValue = val5; Plugin.Log.LogInfo((object)"[dd2] m_currentValue from children = True"); } else { Plugin.Log.LogError((object)"[dd2] no TextMeshPro found for m_currentValue"); } } catch (Exception ex9) { Plugin.Log.LogWarning((object)("[dd2] find TMP: " + ex9.Message)); } } try { dd.Setup((CM_PageBase)(object)page, window, 0u); Plugin.Log.LogInfo((object)"[dd2] Setup ok"); } catch (Exception ex10) { Plugin.Log.LogError((object)("[dd2] Setup: " + ex10.Message)); } string[] names = TrajectoryBehaviour.PresetNames; string[] hexes = TrajectoryBehaviour.PresetHexes; try { string text = "basePage=" + ((Object)(object)dd.m_basePage != (Object)null) + " popupWindow=" + ((Object)(object)dd.m_popupWindow != (Object)null) + " popupItemPrefab=" + ((Object)(object)dd.m_popupItemPrefab != (Object)null) + " popupWindowAlign=" + ((Object)(object)dd.m_popupWindowAlign != (Object)null) + " strings=" + (dd.m_strings != null) + " currentValue=" + ((Object)(object)dd.m_currentValue != (Object)null); Plugin.Log.LogInfo((object)("[dd2] state: " + text)); } catch (Exception ex11) { Plugin.Log.LogWarning((object)("[dd2] state: " + ex11.Message)); } try { Il2CppStringArray val6 = new Il2CppStringArray((long)names.Length); for (int i = 0; i < names.Length; i++) { ((Il2CppArrayBase<string>)(object)val6)[i] = names[i]; } dd.SetStrings(val6); Plugin.Log.LogInfo((object)("[dd2] SetStrings ok (" + names.Length + ")")); } catch (Exception ex12) { Plugin.Log.LogError((object)("[dd2] SetStrings: " + ex12.Message)); } try { int startValue = 0; string text2 = (TrajectoryCfg.ColorHex.Value ?? "").Trim().ToUpperInvariant(); for (int j = 0; j < hexes.Length; j++) { if (hexes[j].ToUpperInvariant() == text2) { startValue = j; break; } } dd.SetStartValue((uint)startValue); Plugin.Log.LogInfo((object)("[dd2] SetStartValue ok (" + startValue + ")")); } catch (Exception ex13) { Plugin.Log.LogError((object)("[dd2] SetStartValue: " + ex13.Message)); } try { dd.UpdateText(); Plugin.Log.LogInfo((object)"[dd2] UpdateText ok"); } catch (Exception ex14) { Plugin.Log.LogWarning((object)("[dd2] UpdateText: " + ex14.Message)); } try { int num = 0; string text3 = (TrajectoryCfg.ColorHex.Value ?? "").Trim().ToUpperInvariant(); for (int k = 0; k < hexes.Length; k++) { if (hexes[k].ToUpperInvariant() == text3) { num = k; break; } } ((TMP_Text)dd.m_currentValue).text = names[num] + " " + hexes[num]; ((Behaviour)dd.m_currentValue).enabled = true; Plugin.Log.LogInfo((object)("[dd2] text forced -> " + names[num] + " " + hexes[num])); } catch (Exception ex15) { Plugin.Log.LogWarning((object)("[dd2] force text: " + ex15.Message)); } try { dd.OnSelectionChanged = Action<int>.op_Implicit((Action<int>)delegate(int num12) { try { if (num12 >= 0 && num12 < hexes.Length) { TrajectoryCfg.ColorHex.Value = hexes[num12]; Plugin.Log.LogInfo((object)("[dd2] selected -> " + hexes[num12])); } } catch { } }); Plugin.Log.LogInfo((object)"[dd2] OnSelectionChanged ok"); } catch (Exception ex16) { Plugin.Log.LogError((object)("[dd2] OnSelectionChanged: " + ex16.Message)); } try { _ = new bool[1]; WireClick((CM_Item)(object)val, delegate { if (_colorPopupItems.Count > 0) { CloseColorPopup(); Plugin.Log.LogInfo((object)"[cp] closed by click"); } else { ShowColorPopup(wrapper, dd.m_currentValue, names, hexes); } }); Plugin.Log.LogInfo((object)"[dd2] WireClick ok (custom popup)"); try { Il2CppReferenceArray<Object> val7 = Resources.FindObjectsOfTypeAll(Il2CppType.Of<CM_SettingsStringArrayDropdownButton>()); int num2 = 0; try { num2 = ((Il2CppArrayBase<Object>)(object)val7)?.Length ?? 0; } catch { } Plugin.Log.LogInfo((object)("[vpop] scan: found " + num2 + " wrappers")); for (int num3 = 0; num3 < num2 && num3 < 8; num3++) { try { Object val8 = ((Il2CppArrayBase<Object>)(object)val7)[num3]; if (val8 == (Object)null) { continue; } CM_SettingsStringArrayDropdownButton val9 = ((Il2CppObjectBase)val8).TryCast<CM_SettingsStringArrayDropdownButton>(); if ((Object)(object)val9 == (Object)null) { continue; } string text4 = "?"; try { text4 = ((Object)((Component)val9).gameObject).name; } catch { } bool flag = false; bool flag2 = false; try { flag = val9.m_isSetup; } catch { } try { flag2 = (Object)(object)val9.m_popupWindow != (Object)null; } catch { } Plugin.Log.LogInfo((object)("[vpop] w[" + num3 + "] go='" + text4 + "' isSetup=" + flag + " popupWindow=" + flag2)); if (!flag2) { continue; } CM_ScrollWindow popupWindow = val9.m_popupWindow; Transform transform = ((Component)popupWindow).transform; string text5 = "?"; string text6 = "?"; try { text5 = ((Object)((Component)popupWindow).gameObject).name; } catch { } try { text6 = (((Object)(object)transform.parent != (Object)null) ? ((Object)transform.parent).name : "(root)"); } catch { } int num4 = 0; try { num4 = transform.childCount; } catch { } bool flag3 = false; try { flag3 = (Object)(object)popupWindow.m_contentContainer != (Object)null; } catch { } bool flag4 = false; try { flag4 = popupWindow.m_isSetup; } catch { } Plugin.Log.LogInfo((object)("[vpop] win='" + text5 + "' parent='" + text6 + " children=" + num4 + " contentContainer=" + flag3 + " isSetup=" + flag4)); for (int num5 = 0; num5 < num4 && num5 < 6; num5++) { try { Transform child = transform.GetChild(num5); if ((Object)(object)child != (Object)null) { Plugin.Log.LogInfo((object)("[vpop] child[" + num5 + "] '" + ((Object)((Component)child).gameObject).name + "'")); } } catch { } } } catch { } } } catch (Exception ex17) { Plugin.Log.LogWarning((object)("[vpop] " + ex17.Message)); } try { ShowColorPopup(wrapper, dd.m_currentValue, names, hexes); Plugin.Log.LogInfo((object)("[cp] SELFTEST built items=" + _colorPopupItems.Count)); CloseColorPopup(); Plugin.Log.LogInfo((object)"[cp] SELFTEST closed ok"); return; } catch (Exception ex18) { Plugin.Log.LogError((object)("[cp] SELFTEST: " + ex18)); return; } } catch (Exception ex19) { Plugin.Log.LogError((object)("[dd2] WireClick custom: " + ex19.Message)); } try { bool[] popupState = new bool[1]; WireClick((CM_Item)(object)val, delegate { if (popupState[0]) { try { dd.SetPopupVisible(false); Plugin.Log.LogInfo((object)"[dd2] click -> popup closed"); } catch (Exception ex29) { Plugin.Log.LogWarning((object)("[dd2] close: " + ex29.Message)); } popupState[0] = false; } else { bool flag5 = false; try { dd.CreateAndShowEnumPopup(); Plugin.Log.LogInfo((object)"[dd2] click -> CreateAndShowEnumPopup ok (list shown)"); flag5 = true; } catch (Exception ex30) { Plugin.Log.LogWarning((object)("[dd2] CreateAndShowEnumPopup: " + ex30.Message)); } if (!flag5) { try { dd.SetPopupVisible(true); Plugin.Log.LogInfo((object)"[dd2] click -> SetPopupVisible(true) ok (fallback)"); flag5 = true; } catch (Exception ex31) { Plugin.Log.LogWarning((object)("[dd2] SetPopupVisible: " + ex31.Message)); } } if (!flag5) { try { ((CM_Item)dd).OnBtnPress((iCellMenuInputHandler)null); Plugin.Log.LogInfo((object)"[dd2] click -> OnBtnPress(null) ok (last resort)"); return; } catch (Exception ex32) { Plugin.Log.LogError((object)("[dd2] OnBtnPress: " + ex32.Message)); return; } } popupState[0] = true; } }); Plugin.Log.LogInfo((object)"[dd2] WireClick ok"); try { Action<int> prev = dd.OnSelectionChanged; dd.OnSelectionChanged = Action<int>.op_Implicit((Action<int>)delegate(int num12) { try { if (prev != null) { prev.Invoke(num12); } } catch { } try { if (num12 >= 0 && num12 < hexes.Length) { TrajectoryCfg.ColorHex.Value = hexes[num12]; } ((TMP_Text)dd.m_currentValue).text = names[num12] + " " + hexes[num12]; } catch { } try { dd.SetPopupVisible(false); } catch { } popupState[0] = false; Plugin.Log.LogInfo((object)("[dd2] selected -> " + ((num12 >= 0 && num12 < hexes.Length) ? hexes[num12] : "?") + " (popup closed)")); }); Plugin.Log.LogInfo((object)"[dd2] OnSelectionChanged wrapped (auto-close)"); } catch (Exception ex20) { Plugin.Log.LogError((object)("[dd2] wrap selection: " + ex20.Message)); } } catch (Exception ex21) { Plugin.Log.LogError((object)("[dd2] WireClick: " + ex21.Message)); } try { Il2CppReferenceArray<Object> val10 = Resources.FindObjectsOfTypeAll(Il2CppType.Of<CM_SettingsStringArrayDropdownButton>()); if (val10 != null) { int num6 = 0; try { num6 = ((Il2CppArrayBase<Object>)(object)val10).Length; } catch { } Plugin.Log.LogInfo((object)("[cmp] 场景里下拉按钮数量 = " + num6)); for (int num7 = 0; num7 < num6 && num7 < 12; num7++) { try { Object val11 = ((Il2CppArrayBase<Object>)(object)val10)[num7]; if (val11 == (Object)null) { continue; } CM_SettingsStringArrayDropdownButton val12 = ((Il2CppObjectBase)val11).TryCast<CM_SettingsStringArrayDropdownButton>(); if ((Object)(object)val12 == (Object)null) { continue; } string text7 = "?"; string text8 = "?"; try { text7 = ((Object)((Component)val12).gameObject).name; } catch { } try { text8 = (((Object)(object)((Component)val12).transform.parent != (Object)null) ? ((Object)((Component)val12).transform.parent).name : "(no parent)"); } catch { } string text9 = "isSetup=" + val12.m_isSetup + " settingId=" + ((object)val12.m_settingId/*cast due to .constrained prefix*/).ToString() + " popupWindow=" + ((Object)(object)val12.m_popupWindow != (Object)null) + " popupAlign=" + ((Object)(object)val12.m_popupWindowAlign != (Object)null) + " basePage=" + ((Object)(object)val12.m_basePage != (Object)null) + " receiver=" + (val12.m_receiver != null) + " curValue=" + ((Object)(object)val12.m_currentValue != (Object)null); Plugin.Log.LogInfo((object)("[cmp] dd[" + num7 + "] go='" + text7 + "' parent='" + text8 + "' " + text9)); if (!val12.m_isSetup || !((Object)(object)val12.m_popupWindow != (Object)null)) { continue; } try { CM_ScrollWindow popupWindow2 = val12.m_popupWindow; Transform transform2 = ((Component)popupWindow2).transform; Plugin.Log.LogInfo((object)("[vpop] === 原版弹窗窗 === go='" + ((Object)((Component)popupWindow2).gameObject).name + "' active=" + ((Component)popupWindow2).gameObject.activeSelf + " parent='" + (((Object)(object)transform2.parent != (Object)null) ? ((Object)transform2.parent).name : "?") + "'")); try { Il2CppReferenceArray<iScrollWindowContent> contentItems = popupWindow2.ContentItems; int num8 = 0; try { num8 = ((Il2CppArrayBase<iScrollWindowContent>)(object)contentItems)?.Length ?? 0; } catch { } Plugin.Log.LogInfo((object)("[vpop] ContentItems=" + num8)); } catch (Exception ex22) { Plugin.Log.LogWarning((object)("[vpop] ContentItems: " + ex22.Message)); } try { Plugin.Log.LogInfo((object)("[vpop] m_contentContainer=" + ((Object)(object)popupWindow2.m_contentContainer != (Object)null) + " isSetup=" + popupWindow2.m_isSetup)); } catch { } try { int childCount = transform2.childCount; Plugin.Log.LogInfo((object)("[vpop] childCount=" + childCount)); for (int num9 = 0; num9 < childCount && num9 < 6; num9++) { try { Transform child2 = transform2.GetChild(num9); if ((Object)(object)child2 != (Object)null) { Plugin.Log.LogInfo((object)("[vpop] child[" + num9 + "] '" + ((Object)((Component)child2).gameObject).name + "'")); } } catch { } } } catch { } } catch (Exception ex23) { Plugin.Log.LogWarning((object)("[vpop] " + ex23.Message)); } } catch { } } } } catch (Exception ex24) { Plugin.Log.LogWarning((object)("[cmp] scan: " + ex24.Message)); } if ((Object)(object)wrapper != (Object)null) { try { GameObject popupItemPrefab = wrapper.m_popupItemPrefab; if ((Object)(object)popupItemPrefab != (Object)null) { Plugin.Log.LogInfo((object)("[pop] popupItemPrefab name='" + ((Object)popupItemPrefab).name + "'")); Transform transform3 = popupItemPrefab.transform; int num10 = 0; try { num10 = transform3.childCount; } catch { } for (int num11 = 0; num11 < num10 && num11 < 8; num11++) { try { Transform child3 = transform3.GetChild(num11); if (!((Object)(object)child3 == (Object)null)) { string text10 = ""; RectTransform val13 = ((Il2CppObjectBase)child3).TryCast<RectTransform>(); if ((Object)(object)val13 != (Object)null) { text10 = " size=" + ((object)val13.sizeDelta/*cast due to .constrained prefix*/).ToString() + " pos=" + ((object)val13.anchoredPosition/*cast due to .constrained prefix*/).ToString(); } Plugin.Log.LogInfo((object)("[pop] child[" + num11 + "] '" + ((Object)((Component)child3).gameObject).name + "'" + text10)); } } catch { } } } else { Plugin.Log.LogWarning((object)"[pop] popupItemPrefab is null"); } } catch (Exception ex25) { Plugin.Log.LogWarning((object)("[pop] item prefab: " + ex25.Message)); } try { Transform popupWindowAlign = wrapper.m_popupWindowAlign; if ((Object)(object)popupWindowAlign != (Object)null) { RectTransform val14 = ((Il2CppObjectBase)popupWindowAlign).TryCast<RectTransform>(); string text11 = "name='" + ((Object)((Component)popupWindowAlign).gameObject).name + "'"; if ((Object)(object)val14 != (Object)null) { text11 = text11 + " size=" + ((object)val14.sizeDelta/*cast due to .constrained prefix*/).ToString() + " anchoredPos=" + ((object)val14.anchoredPosition/*cast due to .constrained prefix*/).ToString() + " worldPos=" + ((object)((Transform)val14).position/*cast due to .constrained prefix*/).ToString(); } text11 = text11 + " parent='" + (((Object)(object)popupWindowAlign.parent != (Object)null) ? ((Object)popupWindowAlign.parent).name : "?") + "'"; Plugin.Log.LogInfo((object)("[pop] popupWindowAlign " + text11)); } else { Plugin.Log.LogWarning((object)"[pop] popupWindowAlign is null"); } } catch (Exception ex26) { Plugin.Log.LogWarning((object)("[pop] align: " + ex26.Message)); } } try { ShowColorPopup(wrapper, dd.m_currentValue, TrajectoryBehaviour.PresetNames, TrajectoryBehaviour.PresetHexes); Plugin.Log.LogInfo((object)("[cp] SELFTEST built items=" + _colorPopupItems.Count)); CloseColorPopup(); Plugin.Log.LogInfo((object)"[cp] SELFTEST closed ok"); } catch (Exception ex27) { Plugin.Log.LogError((object)("[cp] SELFTEST: " + ex27)); } if (string.IsNullOrEmpty(tooltip)) { return; } try { ((CM_Item)val).TooltipInfo = new TooltipInfo { PositionType = (TooltipPositionType)1, TooltipHeader = label, TooltipText = tooltip, UseTooptip = true }; } catch { } } catch (Exception ex28) { Plugin.Log.LogError((object)("[dd2] AddColorDropdownV2: " + ex28)); } } private static void AddColorInput(CM_PageSettings page, CM_ScrollWindow window, List<iScrollWindowContent> items, string label, string tooltip) { //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0217: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Unknown result type (might be due to invalid IL or missing references) //IL_022a: Unknown result type (might be due to invalid IL or missing references) //IL_0232: Unknown result type (might be due to invalid IL or missing references) //IL_023e: Expected O, but got Unknown //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) try { CM_SettingsItem val = CreateItem(page, window, items, label); if ((Object)(object)val == (Object)null) { Plugin.Log.LogError((object)"[settings] ci: CreateItem null"); return; } try { GameObject val2 = Object.Instantiate<GameObject>(val.m_toggleInputPrefab, val.m_inputAlign, false); if ((Object)(object)val2 != (Object)null) { try { CM_Item val3 = val2.GetComponent<CM_Item>(); if ((Object)(object)val3 == (Object)null) { val3 = val2.AddComponent<CM_Item>(); } if ((Object)(object)val3 != (Object)null) { try { ((RectTransformComp)val3).RectTrans.anchoredPosition3D = new Vector3(-325f, 0f, 0f); } catch { } } } catch { } try { Collider2D componentInChildren = val2.GetComponentInChildren<Collider2D>(); if ((Object)(object)componentInChildren != (Object)null) { ((Behaviour)componentInChildren).enabled = false; } } catch { } _hexDisplayTmps.Clear(); try { Il2CppReferenceArray<Component> componentsInChildren = val2.GetComponentsInChildren(Il2CppType.Of<TextMeshPro>(), true); if (componentsInChildren != null) { int num = 0; try { num = ((Il2CppA