using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using GoodItemScan.Patches;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using MonoMod.RuntimeDetour;
using TMPro;
using TestAccountCore.KotlinSharp.Extensions;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: IgnoresAccessChecksTo("AmazingAssets.TerrainToMesh")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("ClientNetworkTransform")]
[assembly: IgnoresAccessChecksTo("com.olegknyazev.softmask")]
[assembly: IgnoresAccessChecksTo("DissonanceVoip")]
[assembly: IgnoresAccessChecksTo("EasyTextEffects")]
[assembly: IgnoresAccessChecksTo("Facepunch Transport for Netcode for GameObjects")]
[assembly: IgnoresAccessChecksTo("Facepunch.Steamworks.Win64")]
[assembly: IgnoresAccessChecksTo("Unity.AI.Navigation")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging.DocCodeExamples")]
[assembly: IgnoresAccessChecksTo("Unity.Burst")]
[assembly: IgnoresAccessChecksTo("Unity.Burst.Unsafe")]
[assembly: IgnoresAccessChecksTo("Unity.Collections")]
[assembly: IgnoresAccessChecksTo("Unity.Collections.LowLevel.ILSupport")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem.ForUI")]
[assembly: IgnoresAccessChecksTo("Unity.Jobs")]
[assembly: IgnoresAccessChecksTo("Unity.Mathematics")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.Common")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.MetricTypes")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStats")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Component")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Configuration")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Implementation")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsReporting")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkProfiler.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkSolutionInterface")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Components")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.Networking.Transport")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Csg")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.KdTree")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Poly2Tri")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Stl")]
[assembly: IgnoresAccessChecksTo("Unity.Profiling.Core")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.ShaderLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Config.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Authentication")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Analytics")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Components")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Configuration")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Device")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Networking")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Registration")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Scheduler")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Telemetry")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Threading")]
[assembly: IgnoresAccessChecksTo("Unity.Services.QoS")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Relay")]
[assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")]
[assembly: IgnoresAccessChecksTo("Unity.Timeline")]
[assembly: IgnoresAccessChecksTo("Unity.VisualEffectGraph.Runtime")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ARModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.NVIDIAModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UI")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("TestAccount666.GoodItemScan")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Yet another scan mod")]
[assembly: AssemblyFileVersion("2.1.0.0")]
[assembly: AssemblyInformationalVersion("2.1.0+8076ce9cb49c1dad7b646590dd31d4876b89c368")]
[assembly: AssemblyProduct("GoodItemScan")]
[assembly: AssemblyTitle("TestAccount666.GoodItemScan")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.1.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}
public NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.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 GoodItemScan
{
public enum AnimationType
{
VANILLA,
GOOD,
FADE,
DOUBLE_RING
}
[Tooltip("This class is for mods like LGU that want to modify the scanner")]
public static class CheatsAPI
{
public static int additionalDistance;
public static int additionalEnemyDistance;
public static int noLineOfSightDistance;
}
public class Color
{
public readonly float red;
public readonly float green;
public readonly float blue;
public Color UnityColor => new Color(red, green, blue);
public Color(float red, float green, float blue)
{
this.red = red;
this.green = green;
this.blue = blue;
base..ctor();
}
public static Color FromHex(string hex)
{
if (hex == null)
{
throw new ArgumentNullException("hex");
}
hex = ((!hex.StartsWith("#")) ? hex : hex.TrimStart('#'));
if (hex.Length != 6)
{
throw new ArgumentException("Hex string must be 6 characters long", "hex");
}
byte b = byte.Parse(hex.Substring(0, 2), NumberStyles.HexNumber);
byte b2 = byte.Parse(hex.Substring(2, 2), NumberStyles.HexNumber);
byte b3 = byte.Parse(hex.Substring(4, 2), NumberStyles.HexNumber);
return new Color((float)(int)b / 255f, (float)(int)b2 / 255f, (float)(int)b3 / 255f);
}
private string RGBFloatToHex()
{
int num = (int)Math.Round(Math.Clamp(red, 0f, 1f) * 255f);
int num2 = (int)Math.Round(Math.Clamp(green, 0f, 1f) * 255f);
int num3 = (int)Math.Round(Math.Clamp(blue, 0f, 1f) * 255f);
return $"#{num:X2}{num2:X2}{num3:X2}";
}
public override string ToString()
{
return RGBFloatToHex();
}
}
public class ComponentCache
{
private readonly Dictionary<GameObject, (GrabbableObject? Grabbable, EnemyAI? Enemy, TerminalAccessibleObject? Terminal)> _cache = new Dictionary<GameObject, (GrabbableObject, EnemyAI, TerminalAccessibleObject)>();
public void Clear()
{
_cache.Clear();
}
public (GrabbableObject? Grabbable, EnemyAI? Enemy, TerminalAccessibleObject? Terminal) GetComponents(GameObject parent)
{
GameObject parent2 = parent;
if (!ConfigManager.useDictionaryCache.Value)
{
return GetUncachedComponents(parent2);
}
if (_cache.TryGetValue(parent2, out (GrabbableObject, EnemyAI, TerminalAccessibleObject) value))
{
return value;
}
return KotlinStyleExtensions.Also<(GrabbableObject, EnemyAI, TerminalAccessibleObject)>(GetUncachedComponents(parent2), (Action<(GrabbableObject, EnemyAI, TerminalAccessibleObject)>)delegate((GrabbableObject Grabbable, EnemyAI Enemy, TerminalAccessibleObject Terminal) tuple)
{
_cache[parent2] = tuple;
});
}
private static (GrabbableObject? Grabbable, EnemyAI? Enemy, TerminalAccessibleObject? Terminal) GetUncachedComponents(GameObject parent)
{
GrabbableObject item = default(GrabbableObject);
parent.TryGetComponent<GrabbableObject>(ref item);
EnemyAI item2 = default(EnemyAI);
parent.TryGetComponent<EnemyAI>(ref item2);
TerminalAccessibleObject item3 = default(TerminalAccessibleObject);
parent.TryGetComponent<TerminalAccessibleObject>(ref item3);
return (item, item2, item3);
}
}
public static class ConfigManager
{
public static ConfigEntry<bool> holdToScan = null;
public static ConfigEntry<bool> preferClosestNodes = null;
public static ConfigEntry<bool> alwaysRescan = null;
public static ConfigEntry<int> scanNodesHardLimit = null;
public static ConfigEntry<float> scanNodeDelay = null;
public static ConfigEntry<bool> useDictionaryCache = null;
public static ConfigEntry<bool> alwaysCheckForLineOfSight = null;
public static ConfigEntry<int> scanNodesGroupSize = null;
public static ConfigEntry<bool> updateScanNodeText = null;
public static ConfigEntry<bool> calculateDistance = null;
public static ConfigEntry<bool> sendDebugMessages = null;
public static ConfigEntry<bool> showOpenedBlastDoorScanNode = null;
public static ConfigEntry<bool> addBoxCollidersToInvalidScanNodes = null;
public static ConfigEntry<bool> hideEmptyScanNodeSubText = null;
public static ConfigEntry<int> totalAddWaitMultiplier = null;
public static ConfigEntry<float> updateTimer = null;
public static ConfigEntry<bool> fixLandmineScanNode = null;
public static readonly Dictionary<NodeType, ConfigEntry<AnimationType>> APPEAR_ANIMATION_TYPES = new Dictionary<NodeType, ConfigEntry<AnimationType>>();
public static readonly Dictionary<NodeType, ConfigEntry<float>> APPEAR_ANIMATION_SPEEDS = new Dictionary<NodeType, ConfigEntry<float>>();
public static readonly Dictionary<NodeType, ConfigEntry<AnimationType>> DISAPPEAR_ANIMATION_TYPES = new Dictionary<NodeType, ConfigEntry<AnimationType>>();
public static readonly Dictionary<NodeType, ConfigEntry<float>> DISAPPEAR_ANIMATION_SPEEDS = new Dictionary<NodeType, ConfigEntry<float>>();
public static readonly Dictionary<NodeType, Color> TEXT_COLORS = new Dictionary<NodeType, Color>();
public static readonly Dictionary<NodeType, Color> TEXT_BACKGROUND_COLORS = new Dictionary<NodeType, Color>();
public static readonly Dictionary<NodeType, Color> CIRCLE_COLORS = new Dictionary<NodeType, Color>();
public static ConfigEntry<int> scanNodeScreenTime = null;
internal static void Initialize(ConfigFile configFile)
{
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
//IL_0064: Expected O, but got Unknown
//IL_0092: Unknown result type (might be due to invalid IL or missing references)
//IL_009c: Expected O, but got Unknown
//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
//IL_0103: Expected O, but got Unknown
//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
//IL_01d3: Expected O, but got Unknown
//IL_0201: Unknown result type (might be due to invalid IL or missing references)
//IL_020b: Expected O, but got Unknown
//IL_04af: Unknown result type (might be due to invalid IL or missing references)
//IL_04b9: Expected O, but got Unknown
//IL_02eb: Unknown result type (might be due to invalid IL or missing references)
//IL_02f5: Expected O, but got Unknown
//IL_0362: Unknown result type (might be due to invalid IL or missing references)
//IL_036c: Expected O, but got Unknown
preferClosestNodes = configFile.Bind<bool>("General", "Prefer Closest Nodes", true, "If true, will prefer scanning the closest nodes first. This might cause performance issues.");
alwaysRescan = configFile.Bind<bool>("General", "Always Rescan", true, "If true, will always start a fresh scan. This removes all previously scanned nodes from the UI.");
scanNodesHardLimit = configFile.Bind<int>("General", "Scan Nodes Hard Limit", 60, new ConfigDescription("Defines the maximum amount of scan nodes on screen. If you feel like your screen is cluttered, try lowering this value.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(30, 666), Array.Empty<object>()));
scanNodeDelay = configFile.Bind<float>("General", "Scan Node Delay", 0.1f, new ConfigDescription("Defines the delay between each scan node being added to the UI. This will look stupid if set too high. This value is divided by 100.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
useDictionaryCache = configFile.Bind<bool>("General", "Use Dictionary Cache", true, "May increase performance, at the cost of ram usage. If true, will use a dictionary for caching. If false, will not cache at all.");
alwaysCheckForLineOfSight = configFile.Bind<bool>("General", "Always Check For Line Of Sight", false, "If true, will check for line of sight every frame. Enabling this could cause performance issues. Vanilla value is true.");
scanNodesGroupSize = configFile.Bind<int>("General", "Scan Node Group Size", 32, new ConfigDescription("Will use \"Scan Node Hard Limit\" divided by \"this value\" to determine how many canvases will be created. This should be between a quarter and half of \"Scan Node Hard Limit\". This is also used to determine how many nodes will be scanned/updated per frame.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 666), Array.Empty<object>()));
updateScanNodeText = configFile.Bind<bool>("General", "Update Scan Node Text", true, "If true, will update the scan node text. This is useful, if you, for example, have a mod that updates the value of an item.");
calculateDistance = configFile.Bind<bool>("General", "Calculate Distance", false, "If true, will perform additional distance calculations. If false, use viewport as distance. Set to `true`, if you don't mind slightly worse performance and want accurate distance calculations.");
sendDebugMessages = configFile.Bind<bool>("Debug", "Send Debug Messages", false, "If set to true, will spam your log with debug messages.");
showOpenedBlastDoorScanNode = configFile.Bind<bool>("Special Cases", "Show opened blast door scan node", true, "If set to true, will allow you to scan nodes of opened blast doors (Vanilla value: false) Enabling this could improve performance.");
addBoxCollidersToInvalidScanNodes = configFile.Bind<bool>("Special Cases", "Add BoxColliders To Invalid Scan Nodes", false, "If true, will add BoxColliers to ScanNodes that do not have one. It is not recommended to enable this. This feature was also never tested, so it might not even work.");
hideEmptyScanNodeSubText = configFile.Bind<bool>("Special Cases", "Hide Empty Scan Node Sub Text", true, "I true, will hide the rectangle beneath the item name, if there's no text to be displayed.");
totalAddWaitMultiplier = configFile.Bind<int>("Special Cases", "Total Add Wait Multiplier", 100, new ConfigDescription("This multiplier is used to define the wait time between adding more to the total displayed value. The lower this number, the faster the animation is updated. The lower this number, the less will be added per updated. For a vanilla-ish feeling, set this to 48.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100), Array.Empty<object>()));
updateTimer = configFile.Bind<float>("Special Cases", "Scan Node Update Timer", 0.6f, new ConfigDescription("This value is used to have a cooldown between scan node updates (Like position updates). The lower this number, the more often it will get updated.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 12f), Array.Empty<object>()));
fixLandmineScanNode = configFile.Bind<bool>("Special Cases", "Fix Landmine ScanNode", true, "Fixes Landmines being scannable after exploding.");
holdToScan = configFile.Bind<bool>("General", "Hold To Scan", false, "If true, holding the scan button will continuously scan.");
NodeType[] enumValues = GetEnumValues<NodeType>();
foreach (NodeType type in enumValues)
{
if (type == NodeType.UNKNOWN)
{
continue;
}
string text = type.ToFriendlyName();
APPEAR_ANIMATION_TYPES[type] = configFile.Bind<AnimationType>("Visuals", text + " Appear Animation Type", AnimationType.GOOD, "The appear animation type to use for this node type.");
APPEAR_ANIMATION_SPEEDS[type] = configFile.Bind<float>("Visuals", text + " Appear Animation Speed", 0.6f, new ConfigDescription("The appear animation speed to use for this node type.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 2f), Array.Empty<object>()));
DISAPPEAR_ANIMATION_TYPES[type] = configFile.Bind<AnimationType>("Visuals", text + " Disappear Animation Type", AnimationType.GOOD, "The disappear animation type to use for this node type.");
DISAPPEAR_ANIMATION_SPEEDS[type] = configFile.Bind<float>("Visuals", text + " Disappear Animation Speed", 0.6f, new ConfigDescription("The disappear animation speed to use for this node type.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 2f), Array.Empty<object>()));
ConfigEntry<string> val = KotlinStyleExtensions.Also<ConfigEntry<string>>(configFile.Bind<string>("Visuals", text + " Text Color", type.DefaultTextColor().ToString(), "The color to use for this node type's text."), (Action<ConfigEntry<string>>)delegate(ConfigEntry<string> c)
{
c.SettingChanged += delegate
{
TEXT_COLORS[type] = Color.FromHex(c.Value);
};
});
TEXT_COLORS[type] = Color.FromHex(val.Value);
ConfigEntry<string> val2 = KotlinStyleExtensions.Also<ConfigEntry<string>>(configFile.Bind<string>("Visuals", text + " Text Background Color", type.DefaultTextBackgroundColor().ToString(), "The color to use for this node type's text background."), (Action<ConfigEntry<string>>)delegate(ConfigEntry<string> c)
{
c.SettingChanged += delegate
{
TEXT_BACKGROUND_COLORS[type] = Color.FromHex(c.Value);
};
});
TEXT_BACKGROUND_COLORS[type] = Color.FromHex(val2.Value);
ConfigEntry<string> val3 = KotlinStyleExtensions.Also<ConfigEntry<string>>(configFile.Bind<string>("Visuals", text + " Circle Color", type.DefaultCircleColor().ToString(), "The color to use for this node type's circles."), (Action<ConfigEntry<string>>)delegate(ConfigEntry<string> c)
{
c.SettingChanged += delegate
{
CIRCLE_COLORS[type] = Color.FromHex(c.Value);
};
});
CIRCLE_COLORS[type] = Color.FromHex(val3.Value);
}
scanNodeScreenTime = configFile.Bind<int>("Visuals", "Scan Node Screen Time", 0, new ConfigDescription("The amount of seconds the scan node will be displayed on screen. This is used to determine how long the scan node will be displayed on screen. 0 = infinite", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 60), Array.Empty<object>()));
}
private static T[] GetEnumValues<T>()
{
return (T[])Enum.GetValues(typeof(T));
}
}
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency("TestAccount666.TestAccountCore", "1.18.0")]
[BepInPlugin("TestAccount666.GoodItemScan", "GoodItemScan", "2.1.0")]
public class GoodItemScan : BaseUnityPlugin
{
public static readonly List<Hook> Hooks = new List<Hook>();
public static RectTransform originalRectTransform = null;
public static ScanObjectInfo scanObject = null;
public static Scanner? scanner;
internal static AssetBundle assetBundle;
public static GoodItemScan Instance { get; private set; } = null;
internal static ManualLogSource Logger { get; private set; } = null;
internal static Harmony? Harmony { get; set; }
private void Awake()
{
Logger = ((BaseUnityPlugin)this).Logger;
Instance = this;
assetBundle = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "GoodItemScan.AssetBundle"));
ConfigManager.Initialize(((BaseUnityPlugin)this).Config);
ConfigManager.scanNodesHardLimit.SettingChanged += delegate
{
SetIncreasedMaximumScanNodes(HUDManager.Instance);
};
Patch();
HUDManagerPatch.InitMonoMod();
UnpatchHdLethalCompany();
Logger.LogInfo((object)"TestAccount666.GoodItemScan v2.1.0 has loaded!");
}
private static void UnpatchHdLethalCompany()
{
MethodInfo methodInfo = AccessTools.DeclaredMethod(typeof(HUDManager), "UpdateScanNodes", (Type[])null, (Type[])null);
Patches patchInfo = Harmony.GetPatchInfo((MethodBase)methodInfo);
if (patchInfo == null)
{
return;
}
Patch[] array = patchInfo.Postfixes.ToArray();
foreach (Patch val in array)
{
if (val != null && val.owner.ToLower().Contains("hdlethalcompany"))
{
Harmony? harmony = Harmony;
if (harmony != null)
{
harmony.Unpatch((MethodBase)methodInfo, (HarmonyPatchType)2, val.owner);
}
Logger.LogInfo((object)"Found HDLethalCompany patch!");
Logger.LogInfo((object)$"Unpatched {methodInfo} method!");
}
}
}
internal static void Patch()
{
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Expected O, but got Unknown
if (Harmony == null)
{
Harmony = new Harmony("TestAccount666.GoodItemScan");
}
LogDebug("Patching...");
Harmony.PatchAll();
LogDebug("Finished patching!");
}
internal static void Unpatch()
{
LogDebug("Unpatching...");
Harmony? harmony = Harmony;
if (harmony != null)
{
harmony.UnpatchSelf();
}
foreach (Hook hook in Hooks)
{
hook.Undo();
}
LogDebug("Finished unpatching!");
}
internal static void SetIncreasedMaximumScanNodes(HUDManager? hudManager)
{
if (!((Object)(object)hudManager == (Object)null))
{
RectTransform[] scanElements = hudManager.scanElements;
foreach (RectTransform val in scanElements)
{
hudManager.scanNodes.Remove(val);
((Component)val).gameObject.SetActive(false);
}
hudManager.scanNodesHit = Array.Empty<RaycastHit>();
hudManager.scanElements = Array.Empty<RectTransform>();
scanner?.FillInScanNodes(GetOriginal());
}
}
internal static ScanObjectInfo GetOriginal()
{
if (Object.op_Implicit((Object)(object)scanObject))
{
return scanObject;
}
return KotlinStyleExtensions.Also<ScanObjectInfo>((from asset in assetBundle.LoadAllAssets()
where asset is GameObject
let gameObject1 = (GameObject)(object)((asset is GameObject) ? asset : null)
let scanObjectInfo = gameObject1.GetComponent<ScanObjectInfo>()
where Object.op_Implicit((Object)(object)scanObjectInfo)
select scanObjectInfo).First(), (Action<ScanObjectInfo>)delegate(ScanObjectInfo obj)
{
scanObject = obj;
});
}
internal static void LogDebug(object data)
{
if (ConfigManager.sendDebugMessages.Value)
{
Logger.LogInfo(data);
}
}
}
public class ScannedNode
{
private ScanNodeProperties? _scanNodeProperties;
internal long _scanTimeStamp = -1L;
public Vector3 viewPoint;
public Vector3 lastKnownPosition = Vector3.zero;
public GameObject scanNodeParent = null;
public readonly int canvasIndex;
public readonly ScanObjectInfo scanObject;
public ScanNodeProperties ScanNodeProperties
{
get
{
return _scanNodeProperties ?? null;
}
set
{
_scanNodeProperties = value;
if ((Object)(object)value != (Object)null && Object.op_Implicit((Object)(object)value))
{
scanNodeParent = ((Component)((Component)value).transform.parent).gameObject;
}
}
}
public long ScanTimeStamp => _scanTimeStamp;
public NodeType NodeType => ScanNodeProperties.nodeType.ToNodeType();
public RectTransform RectTransform => scanObject.mainRectTransform;
public TextMeshProUGUI Header => scanObject.header;
public TextMeshProUGUI Footer => scanObject.footer;
public GameObject SubTextBox => ((Component)scanObject.footerBackground).gameObject;
public bool HasScanNode => (Object)(object)_scanNodeProperties != (Object)null && Object.op_Implicit((Object)(object)_scanNodeProperties);
public ScannedNode(ScanObjectInfo scanObject, int canvasIndex)
{
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
this.canvasIndex = canvasIndex;
this.scanObject = scanObject;
base..ctor();
}
}
public enum NodeType
{
UNKNOWN = -1,
TOOL,
ENEMY,
SCRAP
}
public static class NodeTypeExtensions
{
public static string ToFriendlyName(this NodeType nodeType)
{
string text = nodeType.ToString();
string text2 = text.Substring(0, 1).ToUpper();
string text3 = text;
return text2 + text3.Substring(1, text3.Length - 1);
}
public static Color DefaultTextColor(this NodeType nodeType)
{
if (1 == 0)
{
}
Color result = nodeType switch
{
NodeType.TOOL => new Color(0f, 0f, 0f),
NodeType.ENEMY => new Color(0f, 0f, 0f),
NodeType.SCRAP => new Color(0f, 0f, 0f),
_ => new Color(0f, 0f, 0f),
};
if (1 == 0)
{
}
return result;
}
public static Color DefaultTextBackgroundColor(this NodeType nodeType)
{
if (1 == 0)
{
}
Color result = nodeType switch
{
NodeType.TOOL => new Color(0.043137256f, 22f / 85f, 0.69803923f),
NodeType.ENEMY => new Color(64f / 85f, 2f / 85f, 0f),
NodeType.SCRAP => new Color(0.14509805f, 0.5019608f, 0f),
_ => new Color(0f, 0f, 0f),
};
if (1 == 0)
{
}
return result;
}
public static Color DefaultCircleColor(this NodeType nodeType)
{
if (1 == 0)
{
}
Color result = nodeType switch
{
NodeType.TOOL => new Color(0.043137256f, 0f, 0.69803923f),
NodeType.ENEMY => new Color(1f, 2f / 51f, 0f),
NodeType.SCRAP => new Color(0.21960784f, 57f / 85f, 0f),
_ => new Color(0f, 0f, 0f),
};
if (1 == 0)
{
}
return result;
}
public static Color TextColor(this NodeType nodeType)
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
return ConfigManager.TEXT_COLORS[nodeType].UnityColor;
}
public static Color TextBackgroundColor(this NodeType nodeType)
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
return ConfigManager.TEXT_BACKGROUND_COLORS[nodeType].UnityColor;
}
public static Color CircleColor(this NodeType nodeType)
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
return ConfigManager.CIRCLE_COLORS[nodeType].UnityColor;
}
public static NodeType ToNodeType(this int value)
{
try
{
return (NodeType)value;
}
catch
{
return NodeType.UNKNOWN;
}
}
}
public class Scanner
{
[CompilerGenerated]
private sealed class <>c__DisplayClass23_0
{
public Vector3 playerPos;
internal float <ScanNodesRoutine>b__0(ScanNodeProperties node)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
return Vector3.Distance(playerPos, ((Component)node).transform.position);
}
}
[CompilerGenerated]
private sealed class <>c__DisplayClass24_0
{
public Vector3 viewPoint;
public Scanner <>4__this;
public HUDManager hudManager;
internal void <AddScanNodeToUI>b__0(ScannedNode scannedNode)
{
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
scannedNode._scanTimeStamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
scannedNode.viewPoint = viewPoint;
<>4__this.RefreshPositionCache();
<>4__this.UpdateScanNodePosition(scannedNode);
<>4__this.ActivateScanElement(hudManager, scannedNode);
}
}
[CompilerGenerated]
private sealed class <>c__DisplayClass30_0
{
public ScannedNode scannedNode;
internal void <DisableScanNodeWithAnimation>b__0(Animator a)
{
a.SetFloat(_ANIMATION_SPEED_ANIMATOR_HASH, ConfigManager.DISAPPEAR_ANIMATION_SPEEDS[scannedNode.NodeType].Value);
a.SetInteger(_DISAPPEAR_ANIMATION_TYPE_ANIMATOR_HASH, (int)ConfigManager.DISAPPEAR_ANIMATION_TYPES[scannedNode.NodeType].Value);
a.SetBool(_VISIBLE_ANIMATOR_HASH, false);
}
internal bool <DisableScanNodeWithAnimation>b__1()
{
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
int result;
if (scannedNode.HasScanNode)
{
AnimatorStateInfo currentAnimatorStateInfo = scannedNode.scanObject.animator.GetCurrentAnimatorStateInfo(0);
result = (((AnimatorStateInfo)(ref currentAnimatorStateInfo)).IsName("Idle") ? 1 : 0);
}
else
{
result = 1;
}
return (byte)result != 0;
}
}
[CompilerGenerated]
private sealed class <AddScanNodeToUI>d__24 : IEnumerator<object>, IEnumerator, IDisposable
{
private int <>1__state;
private object <>2__current;
public ScanNodeProperties node;
public Vector3 viewPoint;
public int currentScanNodeCount;
public Scanner <>4__this;
private <>c__DisplayClass24_0 <>8__1;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <AddScanNodeToUI>d__24(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>8__1 = null;
<>1__state = -2;
}
private bool MoveNext()
{
//IL_003c: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
//IL_0071: Unknown result type (might be due to invalid IL or missing references)
//IL_007b: Expected O, but got Unknown
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
<>8__1 = new <>c__DisplayClass24_0();
<>8__1.viewPoint = viewPoint;
<>8__1.<>4__this = <>4__this;
<>2__current = (object)new WaitForSeconds(ConfigManager.scanNodeDelay.Value / 100f * (float)currentScanNodeCount);
<>1__state = 1;
return true;
case 1:
<>1__state = -1;
<>2__current = null;
<>1__state = 2;
return true;
case 2:
{
<>1__state = -1;
<>8__1.hudManager = HUDManager.Instance;
if ((Object)(object)<>8__1.hudManager == (Object)null || (Object)(object)node == (Object)null || !Object.op_Implicit((Object)(object)node))
{
return false;
}
GoodItemScan.LogDebug($"Scanning node '{currentScanNodeCount}'! ({node.headerText};{node.subText})");
ScannedNode? scannedNode2 = <>4__this.AssignNodeToUIElement(node);
if (scannedNode2 != null)
{
KotlinStyleExtensions.Also<ScannedNode>(scannedNode2, (Action<ScannedNode>)delegate(ScannedNode scannedNode)
{
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
scannedNode._scanTimeStamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
scannedNode.viewPoint = <>8__1.viewPoint;
<>8__1.<>4__this.RefreshPositionCache();
<>8__1.<>4__this.UpdateScanNodePosition(scannedNode);
<>8__1.<>4__this.ActivateScanElement(<>8__1.hudManager, scannedNode);
});
}
return false;
}
}
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
[CompilerGenerated]
private sealed class <DisableScanNodeWithAnimation>d__30 : IEnumerator<object>, IEnumerator, IDisposable
{
private int <>1__state;
private object <>2__current;
public ScannedNode scannedNode;
public Scanner <>4__this;
private <>c__DisplayClass30_0 <>8__1;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <DisableScanNodeWithAnimation>d__30(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>8__1 = null;
<>1__state = -2;
}
private bool MoveNext()
{
//IL_0091: Unknown result type (might be due to invalid IL or missing references)
//IL_009b: Expected O, but got Unknown
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
<>8__1 = new <>c__DisplayClass30_0();
<>8__1.scannedNode = scannedNode;
if (<>8__1.scannedNode == null)
{
return false;
}
KotlinStyleExtensions.Also<Animator>(<>8__1.scannedNode.scanObject.animator, (Action<Animator>)delegate(Animator a)
{
a.SetFloat(_ANIMATION_SPEED_ANIMATOR_HASH, ConfigManager.DISAPPEAR_ANIMATION_SPEEDS[<>8__1.scannedNode.NodeType].Value);
a.SetInteger(_DISAPPEAR_ANIMATION_TYPE_ANIMATOR_HASH, (int)ConfigManager.DISAPPEAR_ANIMATION_TYPES[<>8__1.scannedNode.NodeType].Value);
a.SetBool(_VISIBLE_ANIMATOR_HASH, false);
});
<>2__current = (object)new WaitUntil((Func<bool>)delegate
{
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
int result;
if (<>8__1.scannedNode.HasScanNode)
{
AnimatorStateInfo currentAnimatorStateInfo = <>8__1.scannedNode.scanObject.animator.GetCurrentAnimatorStateInfo(0);
result = (((AnimatorStateInfo)(ref currentAnimatorStateInfo)).IsName("Idle") ? 1 : 0);
}
else
{
result = 1;
}
return (byte)result != 0;
});
<>1__state = 1;
return true;
case 1:
<>1__state = -1;
if (!<>8__1.scannedNode.HasScanNode)
{
return false;
}
<>4__this.HandleMissingNode(<>8__1.scannedNode);
return false;
}
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
[CompilerGenerated]
private sealed class <ScanNodesRoutine>d__23 : IEnumerator<object>, IEnumerator, IDisposable
{
private int <>1__state;
private object <>2__current;
public PlayerControllerB localPlayer;
public ScanNodeProperties[] scanNodes;
public Scanner <>4__this;
private int <currentScanNodeCount>5__1;
private int <processedNodesThisFrame>5__2;
private int <maxPerFrame>5__3;
private int <hardLimit>5__4;
private <>c__DisplayClass23_0 <>8__5;
private ScanNodeProperties[] <>s__6;
private int <>s__7;
private ScanNodeProperties <node>5__8;
private Vector3 <viewPoint>5__9;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <ScanNodesRoutine>d__23(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>8__5 = null;
<>s__6 = null;
<node>5__8 = null;
<>1__state = -2;
}
private bool MoveNext()
{
//IL_0070: Unknown result type (might be due to invalid IL or missing references)
//IL_0075: 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_018f: Unknown result type (might be due to invalid IL or missing references)
//IL_0194: Unknown result type (might be due to invalid IL or missing references)
//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
//IL_0218: Unknown result type (might be due to invalid IL or missing references)
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
<>2__current = null;
<>1__state = 1;
return true;
case 1:
<>1__state = -1;
if (ConfigManager.preferClosestNodes.Value)
{
<>8__5 = new <>c__DisplayClass23_0();
<>8__5.playerPos = ((Component)localPlayer).transform.position;
scanNodes = scanNodes.OrderBy((ScanNodeProperties node) => Vector3.Distance(<>8__5.playerPos, ((Component)node).transform.position)).ToArray();
<>8__5 = null;
}
<currentScanNodeCount>5__1 = 0;
<processedNodesThisFrame>5__2 = 0;
<maxPerFrame>5__3 = ConfigManager.scanNodesGroupSize.Value;
<hardLimit>5__4 = ConfigManager.scanNodesHardLimit.Value;
<>s__6 = scanNodes;
<>s__7 = 0;
goto IL_0244;
case 2:
{
<>1__state = -1;
<processedNodesThisFrame>5__2 = 0;
goto IL_0161;
}
IL_0236:
<>s__7++;
goto IL_0244;
IL_0244:
if (<>s__7 < <>s__6.Length)
{
<node>5__8 = <>s__6[<>s__7];
if ((Object)(object)<node>5__8 == (Object)null || !Object.op_Implicit((Object)(object)<node>5__8))
{
goto IL_0236;
}
if (<processedNodesThisFrame>5__2 >= <maxPerFrame>5__3)
{
<>2__current = null;
<>1__state = 2;
return true;
}
goto IL_0161;
}
<>s__6 = null;
return false;
IL_0161:
<processedNodesThisFrame>5__2++;
<viewPoint>5__9 = localPlayer.gameplayCamera.WorldToViewportPoint(((Component)<node>5__8).transform.position);
if (ScanValidator.IsNodeVisible(<node>5__8, <viewPoint>5__9, forceCheckLos: true, <>4__this._componentCache))
{
<currentScanNodeCount>5__1++;
if (<currentScanNodeCount>5__1 > <hardLimit>5__4)
{
GoodItemScan.LogDebug($"Hard Limit of {<hardLimit>5__4} reached!");
return false;
}
((MonoBehaviour)localPlayer).StartCoroutine(<>4__this.AddScanNodeToUI(<node>5__8, <viewPoint>5__9, <currentScanNodeCount>5__1));
<node>5__8 = null;
}
goto IL_0236;
}
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
[CompilerGenerated]
private sealed class <UpdateScanNodesRoutine>d__28 : IEnumerator<object>, IEnumerator, IDisposable
{
private int <>1__state;
private object <>2__current;
public Scanner <>4__this;
private IEnumerator<HashSet<ScannedNode>> <>s__1;
private HashSet<ScannedNode> <set>5__2;
private HashSet<ScannedNode>.Enumerator <>s__3;
private ScannedNode <scannedNode>5__4;
private ScanNodeProperties <node>5__5;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <UpdateScanNodesRoutine>d__28(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
int num = <>1__state;
if (num == -3 || num == 1)
{
try
{
}
finally
{
<>m__Finally1();
}
}
<>s__1 = null;
<set>5__2 = null;
<>s__3 = default(HashSet<ScannedNode>.Enumerator);
<scannedNode>5__4 = null;
<node>5__5 = null;
<>1__state = -2;
}
private bool MoveNext()
{
//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
try
{
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
<>s__1 = <>4__this._ui.canvasesToUpdate.Where((HashSet<ScannedNode> set) => set.Count > 0).GetEnumerator();
<>1__state = -3;
break;
case 1:
<>1__state = -3;
<set>5__2 = null;
break;
}
if (<>s__1.MoveNext())
{
<set>5__2 = <>s__1.Current;
<>s__3 = <set>5__2.GetEnumerator();
try
{
while (<>s__3.MoveNext())
{
<scannedNode>5__4 = <>s__3.Current;
if (!ScanValidator.IsNodeVisible(<scannedNode>5__4.ScanNodeProperties, <scannedNode>5__4.viewPoint, forceCheckLos: false, <>4__this._componentCache))
{
<>4__this.HandleMissingNode(<scannedNode>5__4);
}
else
{
if (!ConfigManager.updateScanNodeText.Value)
{
continue;
}
<node>5__5 = <scannedNode>5__4.ScanNodeProperties;
if (!((Object)(object)<node>5__5 == (Object)null) && Object.op_Implicit((Object)(object)<node>5__5))
{
((TMP_Text)<scannedNode>5__4.Header).text = <node>5__5.headerText;
((TMP_Text)<scannedNode>5__4.Footer).text = <node>5__5.subText;
if (ConfigManager.hideEmptyScanNodeSubText.Value)
{
<scannedNode>5__4.SubTextBox.SetActive(!string.IsNullOrWhiteSpace(<node>5__5.subText));
<node>5__5 = null;
<scannedNode>5__4 = null;
}
}
}
}
}
finally
{
((IDisposable)<>s__3).Dispose();
}
<>s__3 = default(HashSet<ScannedNode>.Enumerator);
<set>5__2.Clear();
<>2__current = null;
<>1__state = 1;
return true;
}
<>m__Finally1();
<>s__1 = null;
<>4__this._nodeVisibilityCheckCoroutine = null;
return false;
}
catch
{
//try-fault
((IDisposable)this).Dispose();
throw;
}
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
private void <>m__Finally1()
{
<>1__state = -1;
if (<>s__1 != null)
{
<>s__1.Dispose();
}
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
public static readonly int DISPLAY_ANIMATOR_HASH = Animator.StringToHash("display");
private static readonly int _SCAN_ANIMATOR_HASH = Animator.StringToHash("scan");
private static readonly int _ANIMATION_SPEED_ANIMATOR_HASH = Animator.StringToHash("AnimationSpeed");
private static readonly int _APPEAR_ANIMATION_TYPE_ANIMATOR_HASH = Animator.StringToHash("AppearAnimationType");
private static readonly int _DISAPPEAR_ANIMATION_TYPE_ANIMATOR_HASH = Animator.StringToHash("DisappearAnimationType");
private static readonly int _VISIBLE_ANIMATOR_HASH = Animator.StringToHash("Visible");
private Coroutine? _scanCoroutine;
private Coroutine? _nodeVisibilityCheckCoroutine;
private readonly List<ScannedNode> _scannedNodesToRemove = new List<ScannedNode>();
public readonly HashSet<ScannedNode> activeNodes = new HashSet<ScannedNode>();
private readonly ComponentCache _componentCache = new ComponentCache();
private readonly ScrapTracker _scrapTracker = new ScrapTracker();
private readonly ScannerUI _ui = new ScannerUI();
private float _updateTimer = 0.05f;
private Rect _cachedScreenRect;
private Camera? _cachedCamera;
private RectTransform _screenRectTransform = null;
private RectTransform ScreenRectTransform
{
get
{
if (Object.op_Implicit((Object)(object)_screenRectTransform))
{
return _screenRectTransform;
}
HUDManager instance = HUDManager.Instance;
if ((Object)(object)instance == (Object)null || !Object.op_Implicit((Object)(object)instance))
{
return null;
}
GameObject gameObject = ((Component)instance.playerScreenShakeAnimator).gameObject;
return _screenRectTransform = gameObject.GetComponent<RectTransform>();
}
}
public void FillInScanNodes(ScanObjectInfo scanObject)
{
if (!Object.op_Implicit((Object)(object)scanObject))
{
scanObject = GoodItemScan.GetOriginal();
}
if (!Object.op_Implicit((Object)(object)scanObject))
{
GoodItemScan.Logger.LogError((object)"ScanObjectInfo is null!");
}
DisableAllScanElements();
_componentCache.Clear();
_ui.Initialize(scanObject);
_nodeVisibilityCheckCoroutine = null;
}
public void Scan()
{
//IL_008b: Unknown result type (might be due to invalid IL or missing references)
PlayerControllerB localPlayerController = StartOfRound.Instance.localPlayerController;
if (!((Object)(object)localPlayerController == (Object)null) && Object.op_Implicit((Object)(object)localPlayerController))
{
HUDManager instance = HUDManager.Instance;
if (!((Object)(object)instance == (Object)null) && Object.op_Implicit((Object)(object)instance) && instance.CanPlayerScan() && !((double)instance.playerPingingScan > -1.0))
{
ResetScanState(instance);
Transform transform = ((Component)localPlayerController.gameplayCamera).transform;
((Component)instance.scanEffectAnimator).transform.position = transform.position;
instance.scanEffectAnimator.SetTrigger(_SCAN_ANIMATOR_HASH);
instance.UIAudio.PlayOneShot(instance.scanSFX);
GoodItemScan.LogDebug("Scan Initiated!");
ScanNodeProperties[] array = Object.FindObjectsByType<ScanNodeProperties>((FindObjectsInactive)0, (FindObjectsSortMode)0);
GoodItemScan.LogDebug($"Got '{array.Length}' nodes!");
_scanCoroutine = ((MonoBehaviour)instance).StartCoroutine(ScanNodesRoutine(localPlayerController, array));
}
}
}
private void ResetScanState(HUDManager hudManager)
{
if (_scanCoroutine != null)
{
((MonoBehaviour)hudManager).StopCoroutine(_scanCoroutine);
}
if (ConfigManager.alwaysRescan.Value)
{
DisableAllScanElements();
_scrapTracker.Reset();
}
hudManager.playerPingingScan = 0.3f;
}
public void DisableAllScanElements()
{
KotlinStyleExtensions.ForEach<ScannedNode>((IEnumerable<ScannedNode>)activeNodes.ToHashSet(), (Action<ScannedNode>)DisableScanNode);
_scannedNodesToRemove.Clear();
_ui.ClearUpdateSets();
HUDManager instance = HUDManager.Instance;
if (_nodeVisibilityCheckCoroutine != null && (Object)(object)instance != (Object)null)
{
((MonoBehaviour)instance).StopCoroutine(_nodeVisibilityCheckCoroutine);
}
_nodeVisibilityCheckCoroutine = null;
}
[IteratorStateMachine(typeof(<ScanNodesRoutine>d__23))]
private IEnumerator ScanNodesRoutine(PlayerControllerB localPlayer, ScanNodeProperties[] scanNodes)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <ScanNodesRoutine>d__23(0)
{
<>4__this = this,
localPlayer = localPlayer,
scanNodes = scanNodes
};
}
[IteratorStateMachine(typeof(<AddScanNodeToUI>d__24))]
private IEnumerator AddScanNodeToUI(ScanNodeProperties node, Vector3 viewPoint, int currentScanNodeCount)
{
//IL_0015: 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)
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <AddScanNodeToUI>d__24(0)
{
<>4__this = this,
node = node,
viewPoint = viewPoint,
currentScanNodeCount = currentScanNodeCount
};
}
public ScannedNode? AssignNodeToUIElement(ScanNodeProperties node)
{
ScanNodeProperties node2 = node;
if ((Object)(object)HUDManager.Instance == (Object)null)
{
return null;
}
if (activeNodes.Any((ScannedNode active) => (Object)(object)active.ScanNodeProperties == (Object)(object)node2))
{
return null;
}
ScannedNode? scannedNode2 = _ui.DequeueNode();
return (scannedNode2 != null) ? KotlinStyleExtensions.Also<ScannedNode>(scannedNode2, (Action<ScannedNode>)delegate(ScannedNode scannedNode)
{
scannedNode.ScanNodeProperties = node2;
activeNodes.Add(scannedNode);
}) : null;
}
public void UpdateScanNodes()
{
HUDManager instance = HUDManager.Instance;
if ((Object)(object)instance == (Object)null)
{
return;
}
HandlePendingRemovals();
_scrapTracker.UpdateDisplay(instance, activeNodes.Count > 0);
if (activeNodes.Count <= 0)
{
return;
}
_updateTimer -= Time.deltaTime;
if (_updateTimer > 0f)
{
return;
}
_updateTimer = ConfigManager.updateTimer.Value / 100f;
if (_nodeVisibilityCheckCoroutine != null)
{
return;
}
foreach (ScannedNode activeNode in activeNodes)
{
if (!activeNode.HasScanNode)
{
HandleMissingNode(activeNode);
continue;
}
long num = (long)ConfigManager.scanNodeScreenTime.Value * 1000L;
if (num > 0 && (activeNode.NodeType != NodeType.SCRAP || _scrapTracker._scannedValue <= _scrapTracker._scannedValueDisplayed))
{
long num2 = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() - activeNode._scanTimeStamp;
if (num2 >= num)
{
((MonoBehaviour)HUDManager.Instance).StartCoroutine(DisableScanNodeWithAnimation(activeNode));
continue;
}
}
_ui.canvasesToUpdate[activeNode.canvasIndex].Add(activeNode);
}
if (_ui.TotalNodesToUpdate > 0)
{
_nodeVisibilityCheckCoroutine = ((MonoBehaviour)instance).StartCoroutine(UpdateScanNodesRoutine());
}
}
private void HandlePendingRemovals()
{
if (_scannedNodesToRemove.Count > 0)
{
_scannedNodesToRemove.ForEach(DisableScanNode);
_scannedNodesToRemove.Clear();
}
}
[IteratorStateMachine(typeof(<UpdateScanNodesRoutine>d__28))]
private IEnumerator UpdateScanNodesRoutine()
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <UpdateScanNodesRoutine>d__28(0)
{
<>4__this = this
};
}
private void RefreshPositionCache()
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
_cachedScreenRect = ScreenRectTransform.rect;
StartOfRound instance = StartOfRound.Instance;
if ((Object)(object)instance == (Object)null || !Object.op_Implicit((Object)(object)instance))
{
_cachedCamera = null;
return;
}
PlayerControllerB localPlayerController = instance.localPlayerController;
if ((Object)(object)localPlayerController == (Object)null || !Object.op_Implicit((Object)(object)localPlayerController))
{
_cachedCamera = null;
}
else
{
_cachedCamera = localPlayerController.gameplayCamera;
}
}
[IteratorStateMachine(typeof(<DisableScanNodeWithAnimation>d__30))]
private IEnumerator DisableScanNodeWithAnimation(ScannedNode scannedNode)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <DisableScanNodeWithAnimation>d__30(0)
{
<>4__this = this,
scannedNode = scannedNode
};
}
private void HandleMissingNode(ScannedNode scannedNode)
{
if (scannedNode != null)
{
ScanNodeProperties scanNodeProperties = scannedNode.ScanNodeProperties;
if ((Object)(object)scanNodeProperties != (Object)null && Object.op_Implicit((Object)(object)scanNodeProperties))
{
_scrapTracker.RemoveScrap(scanNodeProperties);
}
_scannedNodesToRemove.Add(scannedNode);
}
}
private void UpdateScanNodePosition(ScannedNode scannedNode)
{
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_0060: Unknown result type (might be due to invalid IL or missing references)
//IL_0071: Unknown result type (might be due to invalid IL or missing references)
//IL_0076: Unknown result type (might be due to invalid IL or missing references)
//IL_0098: Unknown result type (might be due to invalid IL or missing references)
//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
//IL_00be: Unknown result type (might be due to invalid IL or missing references)
//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
//IL_00da: Unknown result type (might be due to invalid IL or missing references)
ScannedNode scannedNode2 = scannedNode;
if ((Object)(object)_cachedCamera == (Object)null)
{
return;
}
ScanNodeProperties scanNodeProperties = scannedNode2.ScanNodeProperties;
if (!((Object)(object)scanNodeProperties == (Object)null) && Object.op_Implicit((Object)(object)scanNodeProperties))
{
Vector3 val = KotlinStyleExtensions.Also<Vector3>(_cachedCamera.WorldToViewportPoint(((Component)scanNodeProperties).transform.position), (Action<Vector3>)delegate(Vector3 p)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
scannedNode2.viewPoint = p;
});
scannedNode2.RectTransform.anchoredPosition = Vector2.op_Implicit(KotlinStyleExtensions.Also<Vector3>(new Vector3(((Rect)(ref _cachedScreenRect)).xMin + ((Rect)(ref _cachedScreenRect)).width * val.x, ((Rect)(ref _cachedScreenRect)).yMin + ((Rect)(ref _cachedScreenRect)).height * val.y, val.z), (Action<Vector3>)delegate(Vector3 p)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
scannedNode2.lastKnownPosition = p;
}));
}
}
public void ActivateScanElement(HUDManager hudManager, ScannedNode scannedNode)
{
//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
ScanNodeProperties node = scannedNode.ScanNodeProperties;
if ((Object)(object)node == (Object)null || !Object.op_Implicit((Object)(object)node))
{
return;
}
NodeType nodeType = KotlinStyleExtensions.Also<NodeType>(scannedNode.NodeType, (Action<NodeType>)delegate(NodeType t)
{
if (t == NodeType.SCRAP)
{
_scrapTracker.AddScrap(node);
}
});
ScanObjectInfo scanObject = scannedNode.scanObject;
((Component)scanObject.mainRectTransform).gameObject.SetActive(true);
scanObject.animator.SetFloat(_ANIMATION_SPEED_ANIMATOR_HASH, ConfigManager.APPEAR_ANIMATION_SPEEDS[nodeType].Value);
scanObject.animator.SetInteger(_APPEAR_ANIMATION_TYPE_ANIMATOR_HASH, (int)ConfigManager.APPEAR_ANIMATION_TYPES[nodeType].Value);
scanObject.animator.SetBool(_VISIBLE_ANIMATOR_HASH, true);
scanObject.SetTextColor(nodeType.TextColor());
scanObject.SetTextBackgroundColor(nodeType.TextBackgroundColor());
scanObject.SetCircleColor(nodeType.CircleColor());
((TMP_Text)scannedNode.Header).text = node.headerText;
((TMP_Text)scannedNode.Footer).text = node.subText;
if (node.creatureScanID != -1)
{
hudManager.AttemptScanNewCreature(node.creatureScanID);
}
if (ConfigManager.hideEmptyScanNodeSubText.Value)
{
scannedNode.SubTextBox.SetActive(!string.IsNullOrWhiteSpace(node.subText));
}
}
private void DisableScanNode(ScannedNode scannedNode)
{
if (Object.op_Implicit((Object)(object)scannedNode.RectTransform))
{
((Component)scannedNode.RectTransform).gameObject.SetActive(false);
}
KotlinStyleExtensions.Also<ScannedNode>(scannedNode, (Action<ScannedNode>)delegate(ScannedNode s)
{
s.ScanNodeProperties = null;
activeNodes.Remove(s);
_ui.EnqueueNode(s);
});
}
internal void LateUpdate()
{
KotlinStyleExtensions.ForEach<ScannedNode>((IEnumerable<ScannedNode>)activeNodes, (Action<ScannedNode>)UpdateScanNodePosition);
}
}
public class ScannerUI
{
internal readonly List<GameObject> _canvases = new List<GameObject>();
internal readonly List<RectTransform> _canvasRectTransforms = new List<RectTransform>();
private readonly List<Queue<ScannedNode>> _freeNodes = new List<Queue<ScannedNode>>();
public readonly List<HashSet<ScannedNode>> canvasesToUpdate = new List<HashSet<ScannedNode>>();
public int CanvasCount => _canvases.Count;
public int TotalNodesToUpdate => canvasesToUpdate.Sum((HashSet<ScannedNode> set) => set.Count);
public void Clear()
{
_canvases.ForEach((Action<GameObject>)Object.Destroy);
_canvases.Clear();
_canvasRectTransforms.Clear();
_freeNodes.Clear();
canvasesToUpdate.Clear();
}
public void Initialize(ScanObjectInfo scanObject)
{
//IL_0114: Unknown result type (might be due to invalid IL or missing references)
//IL_013f: Expected O, but got Unknown
Clear();
int value = ConfigManager.scanNodesHardLimit.Value;
int value2 = ConfigManager.scanNodesGroupSize.Value;
int num = Mathf.CeilToInt((float)value / (float)value2);
GoodItemScan.LogDebug($"Built {num} canvases!");
if (num > 6)
{
GoodItemScan.Logger.LogWarning((object)($"Your max size ({value}) is considerably higher than your maxPerFrame ({value2}) setting! " + "This will cause the scanner to appear laggy! Try maxSize / maxPerFrame to be lower than 6!"));
}
for (int i = 0; i < num; i++)
{
canvasesToUpdate.Add(new HashSet<ScannedNode>());
}
GameObject val = GameObject.Find("Systems/UI/Canvas");
Canvas parentCanvas = val.GetComponent<Canvas>();
Transform objectScanner = val.transform.Find("ObjectScanner");
for (int j = 0; j < num; j++)
{
GameObject val2 = KotlinStyleExtensions.Also<GameObject>(new GameObject($"ScanCanvas_{j}", new Type[2]
{
typeof(RectTransform),
typeof(Canvas)
}), (Action<GameObject>)delegate(GameObject obj)
{
obj.transform.SetParent(objectScanner, false);
obj.layer = 5;
RectTransform item = KotlinStyleExtensions.Also<RectTransform>(obj.GetComponent<RectTransform>(), (Action<RectTransform>)delegate(RectTransform rt)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
rt.anchorMin = Vector2.zero;
rt.anchorMax = Vector2.one;
rt.offsetMin = Vector2.zero;
rt.offsetMax = Vector2.zero;
});
_canvasRectTransforms.Add(item);
});
_canvases.Add(val2);
_freeNodes.Add(new Queue<ScannedNode>());
KotlinStyleExtensions.Also<Canvas>(val2.GetComponent<Canvas>(), (Action<Canvas>)delegate(Canvas canvasComp)
{
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)parentCanvas == (Object)null) && Object.op_Implicit((Object)(object)parentCanvas))
{
canvasComp.renderMode = parentCanvas.renderMode;
canvasComp.worldCamera = parentCanvas.worldCamera;
canvasComp.planeDistance = parentCanvas.planeDistance;
canvasComp.sortingLayerName = parentCanvas.sortingLayerName;
canvasComp.sortingOrder = parentCanvas.sortingOrder;
}
});
int canvasSize = Mathf.Min(value2, value - j * value2);
PopulateCanvas(scanObject, canvasSize, j, val2);
}
SetupHUDLayout();
}
private void PopulateCanvas(ScanObjectInfo scanObject, int canvasSize, int index, GameObject canvasObj)
{
ScanObjectInfo scanObject2 = scanObject;
Transform canvasTransform = canvasObj.transform;
UsefulExtensions.Times(canvasSize, (Action)delegate
{
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
ScanObjectInfo scanObject3 = KotlinStyleExtensions.Let<GameObject, ScanObjectInfo>(KotlinStyleExtensions.Also<GameObject>(Object.Instantiate<GameObject>(((Component)scanObject2).gameObject, canvasTransform.position, canvasTransform.rotation, canvasTransform), (Action<GameObject>)delegate(GameObject obj)
{
obj.gameObject.SetActive(false);
}), (Func<GameObject, ScanObjectInfo>)((GameObject obj) => obj.GetComponent<ScanObjectInfo>()));
_freeNodes[index].Enqueue(new ScannedNode(scanObject3, index));
});
}
private static void SetupHUDLayout()
{
GameObject val = GameObject.Find("Systems/UI/Canvas");
if ((Object)(object)val == (Object)null || !Object.op_Implicit((Object)(object)val))
{
return;
}
Transform val2 = val.transform.Find("ObjectScanner");
if (!((Object)(object)val2 == (Object)null) && Object.op_Implicit((Object)(object)val2))
{
val2.SetSiblingIndex(3);
Transform val3 = val2.Find("GlobalScanInfo");
if ((Object)(object)val3 != (Object)null && Object.op_Implicit((Object)(object)val3))
{
val3.SetAsLastSibling();
}
}
}
public ScannedNode? DequeueNode()
{
foreach (Queue<ScannedNode> freeNode in _freeNodes)
{
if (!freeNode.TryDequeue(out var result))
{
continue;
}
return result;
}
return null;
}
public void EnqueueNode(ScannedNode node)
{
if (node.canvasIndex < _freeNodes.Count)
{
_freeNodes[node.canvasIndex].Enqueue(node);
}
}
public void ClearUpdateSets()
{
canvasesToUpdate.ForEach(delegate(HashSet<ScannedNode> set)
{
set.Clear();
});
}
}
public class ScanObjectInfo : MonoBehaviour
{
public Image[] circles;
public TextMeshProUGUI header;
public RectTransform headerBackground;
public Image headerImage;
public TextMeshProUGUI footer;
public RectTransform footerBackground;
public Image footerImage;
public RectTransform mainRectTransform;
public Animator animator;
public void SetTextColor(Color color)
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
((Graphic)header).color = color;
((Graphic)footer).color = color;
}
public void SetTextBackgroundColor(Color color)
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
((Graphic)headerImage).color = color;
((Graphic)footerImage).color = color;
}
public void SetCircleColor(Color color)
{
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
Image[] array = circles;
foreach (Image val in array)
{
((Graphic)val).color = color;
}
}
}
public static class ScanValidator
{
private static readonly Vector3[] _CORNERS_BUFFER = (Vector3[])(object)new Vector3[8];
public static bool IsNodeVisible(ScanNodeProperties node, Vector3 viewPoint, bool forceCheckLos, ComponentCache componentCache)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
//IL_0056: Unknown result type (might be due to invalid IL or missing references)
//IL_0057: Unknown result type (might be due to invalid IL or missing references)
//IL_005e: 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_00de: Unknown result type (might be due to invalid IL or missing references)
if (!IsNodeOnScreen(viewPoint))
{
return false;
}
if ((Object)(object)node == (Object)null || !Object.op_Implicit((Object)(object)node))
{
return false;
}
PlayerControllerB localPlayerController = StartOfRound.Instance.localPlayerController;
Vector3 position = ((Component)localPlayerController.gameplayCamera).transform.position;
float num = CalculateDistance(viewPoint, ((Component)node).transform.position, position);
int num2 = node.maxRange + ((node.nodeType.ToNodeType() == NodeType.ENEMY) ? CheatsAPI.additionalEnemyDistance : CheatsAPI.additionalDistance);
if (num2 < node.maxRange)
{
num2 = int.MaxValue;
}
if (num > (float)num2 || num < (float)node.minRange)
{
return false;
}
if ((forceCheckLos || ConfigManager.alwaysCheckForLineOfSight.Value) && num > (float)CheatsAPI.noLineOfSightDistance && !HasLineOfSight(node, position))
{
return false;
}
return IsScanNodeValid(node, componentCache);
}
public static bool IsNodeOnScreen(Vector3 viewPoint)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
float x = viewPoint.x;
int result;
if (x >= 0f && x <= 1f)
{
x = viewPoint.y;
if (x >= 0f && x <= 1f)
{
result = ((viewPoint.z > 0f) ? 1 : 0);
goto IL_003f;
}
}
result = 0;
goto IL_003f;
IL_003f:
return (byte)result != 0;
}
public static float CalculateDistance(Vector3 viewPoint, Vector3 objectPosition, Vector3 cameraPosition)
{
//IL_0015: 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_000d: Unknown result type (might be due to invalid IL or missing references)
return ConfigManager.calculateDistance.Value ? Vector3.Distance(objectPosition, cameraPosition) : viewPoint.z;
}
public static bool HasLineOfSight(ScanNodeProperties node, Vector3 cameraPosition)
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_004f: Unknown result type (might be due to invalid IL or missing references)
//IL_0054: 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_005e: 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_0070: Unknown result type (might be due to invalid IL or missing references)
//IL_0077: Unknown result type (might be due to invalid IL or missing references)
//IL_007d: Unknown result type (might be due to invalid IL or missing references)
//IL_0082: 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)
//IL_0094: Unknown result type (might be due to invalid IL or missing references)
//IL_009a: Unknown result type (might be due to invalid IL or missing references)
//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
//IL_00be: Unknown result type (might be due to invalid IL or missing references)
//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
//IL_00da: Unknown result type (might be due to invalid IL or missing references)
//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
//IL_0105: Unknown result type (might be due to invalid IL or missing references)
//IL_010b: Unknown result type (might be due to invalid IL or missing references)
//IL_0110: Unknown result type (might be due to invalid IL or missing references)
//IL_011b: Unknown result type (might be due to invalid IL or missing references)
//IL_0121: 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_012e: Unknown result type (might be due to invalid IL or missing references)
//IL_0133: 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_013f: Unknown result type (might be due to invalid IL or missing references)
if (!node.requiresLineOfSight)
{
return true;
}
if (!TryGetOrAddBoxCollider(node, out BoxCollider boxCollider))
{
return false;
}
Bounds bounds = ((Collider)boxCollider).bounds;
Vector3 min = ((Bounds)(ref bounds)).min;
Vector3 max = ((Bounds)(ref bounds)).max;
_CORNERS_BUFFER[0] = max;
_CORNERS_BUFFER[1] = new Vector3(max.x, max.y, min.z);
_CORNERS_BUFFER[2] = new Vector3(max.x, min.y, max.z);
_CORNERS_BUFFER[3] = new Vector3(max.x, min.y, min.z);
_CORNERS_BUFFER[4] = new Vector3(min.x, max.y, max.z);
_CORNERS_BUFFER[5] = new Vector3(min.x, max.y, min.z);
_CORNERS_BUFFER[6] = new Vector3(min.x, min.y, max.z);
_CORNERS_BUFFER[7] = min;
return _CORNERS_BUFFER.Any((Vector3 corner) => !Physics.Linecast(cameraPosition, corner, 256, (QueryTriggerInteraction)1));
}
private static bool TryGetOrAddBoxCollider(ScanNodeProperties node, out BoxCollider boxCollider)
{
if (((Component)node).TryGetComponent<BoxCollider>(ref boxCollider))
{
return true;
}
GoodItemScan.Logger.LogError((object)(node.headerText + " has no BoxCollider!"));
if (!ConfigManager.addBoxCollidersToInvalidScanNodes.Value)
{
return false;
}
GoodItemScan.Logger.LogError((object)"Adding a BoxCollider!");
boxCollider = ((Component)node).gameObject.AddComponent<BoxCollider>();
return true;
}
public static bool IsScanNodeValid(ScanNodeProperties node, ComponentCache componentCache)
{
GameObject gameObject = ((Component)((Component)node).transform.parent).gameObject;
if ((Object)(object)gameObject == (Object)null || !Object.op_Implicit((Object)(object)gameObject))
{
return false;
}
(GrabbableObject, EnemyAI, TerminalAccessibleObject) components = componentCache.GetComponents(gameObject);
return IsScanNodeValid(components.Item1, components.Item2, components.Item3);
}
public static bool IsScanNodeValid(GrabbableObject? grabbable, EnemyAI? enemy, TerminalAccessibleObject? terminal)
{
if ((Object)(object)grabbable != (Object)null && Object.op_Implicit((Object)(object)grabbable) && (grabbable.isHeld || grabbable.isHeldByEnemy || grabbable.deactivated))
{
return false;
}
if ((Object)(object)enemy != (Object)null && Object.op_Implicit((Object)(object)enemy) && enemy.isEnemyDead)
{
return false;
}
if (ConfigManager.showOpenedBlastDoorScanNode.Value)
{
return true;
}
if ((Object)(object)terminal == (Object)null || !Object.op_Implicit((Object)(object)terminal) || !terminal.isBigDoor)
{
return true;
}
return terminal != null && !terminal.isDoorOpen && terminal.isPoweredOn;
}
}
public class ScrapTracker
{
private int _scannedAmount;
internal int _scannedValue;
internal int _scannedValueDisplayed;
private float _addToDisplayTotalInterval = 0.35f;
public bool HasScrap => _scannedAmount > 0;
public void Reset()
{
_scannedAmount = 0;
_scannedValue = 0;
_scannedValueDisplayed = 0;
_addToDisplayTotalInterval = 0.35f;
}
public void AddScrap(ScanNodeProperties node)
{
if (node != null && node.nodeType == 2 && node.scrapValue > 0)
{
_scannedAmount++;
_scannedValue += node.scrapValue;
}
}
public void RemoveScrap(ScanNodeProperties node)
{
if (node != null && node.nodeType == 2 && node.scrapValue > 0)
{
_scannedAmount--;
_scannedValue = Mathf.Clamp(_scannedValue - node.scrapValue, 0, 10000);
}
}
public void UpdateDisplay(HUDManager hudManager, bool hasActiveNodes)
{
if (!hasActiveNodes || _scannedAmount <= 0)
{
((TMP_Text)hudManager.totalValueText).text = "$0";
_scannedAmount = 0;
_scannedValue = 0;
_scannedValueDisplayed = 0;
_addToDisplayTotalInterval = 0.35f;
hudManager.scanInfoAnimator.SetBool(Scanner.DISPLAY_ANIMATOR_HASH, false);
return;
}
hudManager.scanInfoAnimator.SetBool(Scanner.DISPLAY_ANIMATOR_HASH, _scannedValue != 0);
if (_scannedValueDisplayed >= _scannedValue || _scannedValueDisplayed >= 10000)
{
return;
}
_addToDisplayTotalInterval -= Time.deltaTime;
if (!(_addToDisplayTotalInterval > 0f))
{
_addToDisplayTotalInterval = 0.08525f * ((float)ConfigManager.totalAddWaitMultiplier.Value / 100f);
_scannedValueDisplayed = (int)Mathf.Clamp(Mathf.MoveTowards((float)_scannedValueDisplayed, (float)_scannedValue, (1500f + (float)(_scannedValue * ConfigManager.totalAddWaitMultiplier.Value) / 100f) * Time.deltaTime), 0f, 10000f);
((TMP_Text)hudManager.totalValueText).text = $"${_scannedValueDisplayed}";
if (_scannedValueDisplayed < _scannedValue && _scannedValueDisplayed < 10000)
{
hudManager.UIAudio.PlayOneShot(hudManager.addToScrapTotalSFX);
}
else
{
hudManager.UIAudio.PlayOneShot(hudManager.finishAddingToTotalSFX);
}
}
}
}
public static class MyPluginInfo
{
public const string PLUGIN_GUID = "TestAccount666.GoodItemScan";
public const string PLUGIN_NAME = "GoodItemScan";
public const string PLUGIN_VERSION = "2.1.0";
}
}
namespace GoodItemScan.Patches
{
[HarmonyPatch(typeof(HUDManager))]
public static class HUDManagerPatch
{
[CompilerGenerated]
private sealed class <>c__DisplayClass10_0
{
public HUDManager hudManager;
internal bool <PingScanRoutine>b__0()
{
return hudManager.CanPlayerScan() && (double)hudManager.playerPingingScan <= -1.0;
}
}
[CompilerGenerated]
private sealed class <PingScanRoutine>d__10 : IEnumerator<object>, IEnumerator, IDisposable
{
private int <>1__state;
private object <>2__current;
private <>c__DisplayClass10_0 <>8__1;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <PingScanRoutine>d__10(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>8__1 = null;
<>1__state = -2;
}
private bool MoveNext()
{
//IL_005e: Unknown result type (might be due to invalid IL or missing references)
//IL_0068: Expected O, but got Unknown
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
<>8__1 = new <>c__DisplayClass10_0();
<>8__1.hudManager = HUDManager.Instance;
break;
case 1:
<>1__state = -1;
HUDManager.Instance.PingHUDElement(HUDManager.Instance.Compass, 1f, 0.8f, 0.12f);
GoodItemScan.scanner?.Scan();
<>2__current = null;
<>1__state = 2;
return true;
case 2:
<>1__state = -1;
break;
}
<>2__current = (object)new WaitUntil((Func<bool>)(() => <>8__1.hudManager.CanPlayerScan() && (double)<>8__1.hudManager.playerPingingScan <= -1.0));
<>1__state = 1;
return true;
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
internal static void InitMonoMod()
{
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
//IL_0048: Unknown result type (might be due to invalid IL or missing references)
//IL_0049: Unknown result type (might be due to invalid IL or missing references)
//IL_0053: Expected O, but got Unknown
//IL_008c: Unknown result type (might be due to invalid IL or missing references)
//IL_009b: Unknown result type (might be due to invalid IL or missing references)
//IL_009c: Unknown result type (might be due to invalid IL or missing references)
//IL_00a6: Expected O, but got Unknown
//IL_00df: Unknown result type (might be due to invalid IL or missing references)
//IL_00ee: 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_00f9: Expected O, but got Unknown
//IL_0132: Unknown result type (might be due to invalid IL or missing references)
//IL_0141: Unknown result type (might be due to invalid IL or missing references)
//IL_0142: Unknown result type (might be due to invalid IL or missing references)
//IL_014c: Expected O, but got Unknown
//IL_0185: Unknown result type (might be due to invalid IL or missing references)
//IL_0194: Unknown result type (might be due to invalid IL or missing references)
//IL_0195: Unknown result type (might be due to invalid IL or missing references)
//IL_019f: Expected O, but got Unknown
GoodItemScan.Hooks.Add(new Hook((MethodBase)AccessTools.Method(typeof(HUDManager), "AssignNodeToUIElement", (Type[])null, (Type[])null), (Delegate)new Action<Action<HUDManager, ScanNodeProperties>, HUDManager, ScanNodeProperties>(DontAssignNodeToUIElement), new HookConfig
{
Priority = -99
}));
GoodItemScan.Hooks.Add(new Hook((MethodBase)AccessTools.Method(typeof(HUDManager), "AssignNewNodes", (Type[])null, (Type[])null), (Delegate)new Action<Action<HUDManager, PlayerControllerB>, HUDManager, PlayerControllerB>(DontAssignNewNodes), new HookConfig
{
Priority = -99
}));
GoodItemScan.Hooks.Add(new Hook((MethodBase)AccessTools.Method(typeof(HUDManager), "MeetsScanNodeRequirements", (Type[])null, (Type[])null), (Delegate)new Func<Func<HUDManager, ScanNodeProperties, PlayerControllerB, bool>, HUDManager, ScanNodeProperties, PlayerControllerB, bool>(MeetsScanNodeRequirements), new HookConfig
{
Priority = -99
}));
GoodItemScan.Hooks.Add(new Hook((MethodBase)AccessTools.Method(typeof(HUDManager), "NodeIsNotVisible", (Type[])null, (Type[])null), (Delegate)new Func<Func<HUDManager, ScanNodeProperties, int, bool>, HUDManager, ScanNodeProperties, int, bool>(NodeIsAlwaysVisible), new HookConfig
{
Priority = -99
}));
GoodItemScan.Hooks.Add(new Hook((MethodBase)AccessTools.Method(typeof(HUDManager), "UpdateScanNodes", (Type[])null, (Type[])null), (Delegate)new Action<Action<HUDManager, PlayerControllerB>, HUDManager, PlayerControllerB>(UpdateScanNodes), new HookConfig
{
Priority = -99
}));
}
private static void DontAssignNodeToUIElement(Action<HUDManager, ScanNodeProperties> orig, HUDManager self, ScanNodeProperties node)
{
}
private static void DontAssignNewNodes(Action<HUDManager, PlayerControllerB> orig, HUDManager self, PlayerControllerB playerScript)
{
}
private static bool MeetsScanNodeRequirements(Func<HUDManager, ScanNodeProperties, PlayerControllerB, bool> orig, HUDManager self, ScanNodeProperties node, PlayerControllerB playerScript)
{
return true;
}
private static bool NodeIsAlwaysVisible(Func<HUDManager, ScanNodeProperties, int, bool> orig, HUDManager self, ScanNodeProperties node, int elementIndex)
{
return false;
}
private static void UpdateScanNodes(Action<HUDManager, PlayerControllerB> orig, HUDManager self, PlayerControllerB playerScript)
{
GoodItemScan.scanner?.UpdateScanNodes();
}
[HarmonyPatch("DisableAllScanElements")]
[HarmonyPrefix]
private static bool RedirectDisableAllScanElements()
{
GoodItemScan.scanner?.DisableAllScanElements();
return false;
}
[HarmonyPatch("PingScan_performed")]
[HarmonyPrefix]
private static bool PingScanPerformed(ref CallbackContext context)
{
if (!((CallbackContext)(ref context)).performed)
{
return false;
}
HUDManager instance = HUDManager.Instance;
if ((Object)(object)instance != (Object)null && Object.op_Implicit((Object)(object)instance))
{
instance.PingHUDElement(instance.Compass, 1f, 0.8f, 0.12f);
GoodItemScan.scanner?.Scan();
}
return false;
}
[HarmonyPatch("Start")]
[HarmonyPostfix]
private static void AfterHudManagerAwake(HUDManager __instance)
{
GoodItemScan.scanner = new Scanner();
GoodItemScan.SetIncreasedMaximumScanNodes(__instance);
RegisterHoldScan();
}
private static void RegisterHoldScan()
{
Coroutine pingScanRoutine = null;
InputAction val = InputSystem.actions.FindAction("PingScan", false);
val.started += delegate
{
if (pingScanRoutine != null)
{
((MonoBehaviour)HUDManager.Instance).StopCoroutine(pingScanRoutine);
pingScanRoutine = null;
}
if (ConfigManager.holdToScan.Value)
{
pingScanRoutine = ((MonoBehaviour)HUDManager.Instance).StartCoroutine(PingScanRoutine());
}
};
val.canceled += delegate
{
if (pingScanRoutine != null)
{
((MonoBehaviour)HUDManager.Instance).StopCoroutine(pingScanRoutine);
pingScanRoutine = null;
}
};
}
[IteratorStateMachine(typeof(<PingScanRoutine>d__10))]
private static IEnumerator PingScanRoutine()
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <PingScanRoutine>d__10(0);
}
[HarmonyPatch("OnDisable")]
[HarmonyPostfix]
private static void ResetCheatsAPI()
{
CheatsAPI.additionalEnemyDistance = 0;
CheatsAPI.additionalDistance = 0;
CheatsAPI.noLineOfSightDistance = 0;
}
}
[HarmonyPatch(typeof(Landmine))]
public static class LandminePatch
{
[HarmonyPatch("Detonate")]
[HarmonyPostfix]
public static void DisableLandmineScanNode(Landmine __instance)
{
if (ConfigManager.fixLandmineScanNode.Value)
{
Transform val = ((Component)__instance).transform.parent.Find("ScanNode");
if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)((Component)val).gameObject))
{
Object.Destroy((Object)(object)((Component)val).gameObject);
}
}
}
}
[HarmonyPatch(typeof(PlayerControllerB))]
public static class PlayerPatch
{
[HarmonyPatch("LateUpdate")]
[HarmonyPostfix]
public static void AfterPlayerLateUpdate(PlayerControllerB __instance)
{
PlayerControllerB localPlayerController = StartOfRound.Instance.localPlayerController;
if (!((Object)(object)__instance != (Object)(object)localPlayerController))
{
GoodItemScan.scanner?.LateUpdate();
}
}
}
[HarmonyPatch(typeof(StoryLog))]
public class StoryLogPatch
{
[HarmonyPatch("RemoveLogCollectible")]
[HarmonyPostfix]
public static void DisableScanNode(StoryLog __instance)
{
BoxCollider[] componentsInChildren = ((Component)__instance).GetComponentsInChildren<BoxCollider>();
foreach (BoxCollider val in componentsInChildren)
{
Object.Destroy((Object)(object)((Component)val).gameObject);
}
}
}
}
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
internal sealed class IgnoresAccessChecksToAttribute : Attribute
{
public IgnoresAccessChecksToAttribute(string assemblyName)
{
}
}
}