using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO;
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 Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.SceneManagement;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("my.pahsiv.MyFoothold")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("2.0.0.0")]
[assembly: AssemblyInformationalVersion("2.0.0")]
[assembly: AssemblyProduct("my.pahsiv.MyFoothold")]
[assembly: AssemblyTitle("MyFoothold")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[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]
[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]
[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 BepInEx
{
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
[Conditional("CodeGeneration")]
[Embedded]
internal sealed class BepInAutoPluginAttribute : Attribute
{
public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
{
}
}
}
namespace BepInEx.Preloader.Core.Patching
{
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
[Conditional("CodeGeneration")]
[Embedded]
internal sealed class PatcherAutoPluginAttribute : Attribute
{
public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
{
}
}
}
namespace Microsoft.CodeAnalysis
{
[Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace MyFoothold
{
public static class ColoredLogging
{
private static readonly MethodInfo SetConsoleColorMethod;
private static readonly TextWriter ConsoleStream;
static ColoredLogging()
{
Assembly assembly = typeof(BaseUnityPlugin).Assembly;
Type type = assembly.GetType("BepInEx.ConsoleManager");
if (type != null)
{
SetConsoleColorMethod = type.GetMethod("SetConsoleColor", BindingFlags.Static | BindingFlags.Public);
ConsoleStream = type.GetProperty("ConsoleStream", BindingFlags.Static | BindingFlags.Public)?.GetValue(null) as TextWriter;
}
}
private static void SetColor(ConsoleColor color)
{
SetConsoleColorMethod?.Invoke(null, new object[1] { color });
}
private static void WriteColored(string message, ConsoleColor color, bool newline = true)
{
if (ConsoleStream != null)
{
SetColor(color);
if (newline)
{
ConsoleStream.WriteLine(message);
}
else
{
ConsoleStream.Write(message);
}
SetColor(ConsoleColor.Gray);
}
}
public static void LogColor(this ManualLogSource log, string message, ConsoleColor color = ConsoleColor.Gray)
{
WriteColored(message, color);
}
public static void LogColorW(this ManualLogSource log, string message, ConsoleColor color = ConsoleColor.Yellow)
{
WriteColored(message, color);
}
public static void LogColorE(this ManualLogSource log, string message, ConsoleColor color = ConsoleColor.Red)
{
WriteColored(message, color);
}
public static void LogColorS(this ManualLogSource log, string message, ConsoleColor color = ConsoleColor.Green)
{
WriteColored(message, color);
}
public static void LogColorM(this ManualLogSource log, string message, ConsoleColor color = ConsoleColor.Magenta)
{
WriteColored(message, color);
}
public static void LogColorC(this ManualLogSource log, string message, ConsoleColor color = ConsoleColor.Cyan)
{
WriteColored(message, color);
}
}
public static class ColorHelper
{
public const string White = "FFFFFF";
public const string Black = "000000";
public const string Red = "FF0000";
public const string Green = "00FF00";
public const string Blue = "0000FF";
public const string Yellow = "FFFF00";
public const string Purple = "8765CA";
public const string Gray = "808080";
public const string Orange = "FFA500";
public const string Cyan = "00FFFF";
public const string Magenta = "FF00FF";
public const string Pink = "FFC0CB";
public const string Brown = "A52A2A";
public const string Lime = "00FF00";
public const string Teal = "008080";
public const string Navy = "000080";
public const string Maroon = "800000";
public const string Olive = "808000";
public const string Aqua = "00FFFF";
public const string Silver = "C0C0C0";
public const string Gold = "FFD700";
public const string LightRed = "FF6B6B";
public const string LightGreen = "90EE90";
public const string LightBlue = "ADD8E6";
public const string LightGray = "D3D3D3";
public const string LightPink = "FFB6C1";
public const string DarkRed = "8B0000";
public const string DarkGreen = "006400";
public const string DarkBlue = "00008B";
public const string DarkGray = "A9A9A9";
public const string DarkOrange = "FF8C00";
public const string Pahsiv = "3582E7";
}
[BepInPlugin("my.pahsiv.MyFoothold", "MyFoothold", "2.0.0")]
public class Plugin : BaseUnityPlugin
{
internal struct CachedResult
{
public bool HasHit;
public Vector3 HitPoint;
public float Angle;
public bool IsStandable;
public Vector3 HitNormal;
}
internal struct FixedColumnData
{
public int HitCount;
public CachedResult Hit1;
public CachedResult Hit2;
public CachedResult Hit3;
public CachedResult Hit4;
public CachedResult Hit5;
public CachedResult Hit6;
public CachedResult Hit7;
public CachedResult Hit8;
public CachedResult Hit9;
public CachedResult Hit10;
}
internal enum StandableColor
{
White,
Green
}
internal enum NonStandableColor
{
Red,
Magenta
}
internal enum Mode
{
Toggle,
Trigger,
FadeAway,
Continuous
}
private ConfigEntry<StandableColor> configStandableBallColor;
private ConfigEntry<NonStandableColor> configNonStandableBallColor;
private ConfigEntry<Mode> configMode;
private ConfigEntry<KeyCode> configActivationKey;
private ConfigEntry<int> IndicatorDensityMultiplier;
private Dictionary<int, FixedColumnData> _columnCache = new Dictionary<int, FixedColumnData>();
private GameObject? _particleSystemObject;
private ParticleSystem? _standableParticleSystem;
private ParticleSystem? _nonStandableParticleSystem;
private Material? _proceduralDonutMaterial;
private Material? _proceduralCrossMaterial;
private const float SnapSize = 0.5f;
private const float InvSnapSize = 2f;
private const float xFreq = 0.5f;
private const float zFreq = 0.5f;
private const int xRange = 15;
private const int zRange = 15;
private const float yRange = 10f;
private const float ContinuousScanInterval = 0.5f;
private const float TravelThreshold = 1f;
private bool _isContinuousModeActive;
private Vector3Int _lastContinuousSnappedPos3D;
private Coroutine? _activeScanCoroutine;
private Color _standableColorValue;
private Color _nonStandableColorValue;
private LayerMask _terrainLayerMask;
private RaycastHit[] _raycastHitBuffer = (RaycastHit[])(object)new RaycastHit[10];
private int[] _keyPruneArrayBuffer = new int[1000];
private CachedResult[] _columnWorkerBuffer = new CachedResult[10];
private int _columnWorkerBufferCount;
private Stopwatch _budgetTimer = new Stopwatch();
private Vector3 _raycastOriginBuffer = Vector3.zero;
private Vector3 _centerWorldPosBuffer = Vector3.zero;
private int _xGridKey;
private int _zGridKey;
private int _uniqueIntKey;
private float _xPosCalc;
private float _zPosCalc;
private List<Particle> _standableParticlesList = new List<Particle>(25000);
private List<Particle> _nonStandableParticlesList = new List<Particle>(25000);
private Particle[] _standableDataBuffer = (Particle[])(object)new Particle[25000];
private Particle[] _nonStandableDataBuffer = (Particle[])(object)new Particle[25000];
private Coroutine? _activeStandableFadeCoroutine;
private Coroutine? _activeNonStandableFadeCoroutine;
public const string Id = "my.pahsiv.MyFoothold";
internal static ManualLogSource Log { get; private set; }
public static Plugin? Instance { get; private set; }
public static string Name => "MyFoothold";
public static string Version => "2.0.0";
private void Awake()
{
Log = ((BaseUnityPlugin)this).Logger;
Instance = this;
Log.LogColorM(" Plugin " + Name + " " + Version + " is loading...");
BindConfig();
SceneManager.sceneLoaded += OnSceneLoaded;
configStandableBallColor.SettingChanged += Color_SettingChanged;
configNonStandableBallColor.SettingChanged += Color_SettingChanged;
configMode.SettingChanged += ConfigMode_SettingChanged;
IndicatorDensityMultiplier.SettingChanged += IndicatorDensityMultiplier_SettingChanged;
Log.LogColorC(" Plugin " + Name + " " + Version + " is loaded!");
}
private void IndicatorDensityMultiplier_SettingChanged(object sender, EventArgs e)
{
Log.LogMessage((object)$"[Foothold] Indicator Density changed to: {IndicatorDensityMultiplier.Value}");
}
private void ConfigMode_SettingChanged(object sender, EventArgs e)
{
//IL_00b1: 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_00bb: Unknown result type (might be due to invalid IL or missing references)
Log.LogMessage((object)$"[Foothold] Mode configuration changed to: {configMode.Value}");
if (_activeScanCoroutine != null)
{
((MonoBehaviour)this).StopCoroutine(_activeScanCoroutine);
_activeScanCoroutine = null;
}
if ((Object)(object)_standableParticleSystem != (Object)null)
{
_standableParticleSystem.Clear();
}
if ((Object)(object)_nonStandableParticleSystem != (Object)null)
{
_nonStandableParticleSystem.Clear();
}
_columnCache.Clear();
_isContinuousModeActive = false;
if (configMode.Value == Mode.Continuous && (Object)(object)Camera.main != (Object)null)
{
_isContinuousModeActive = true;
_lastContinuousSnappedPos3D = SnapToGrid(((Component)Camera.main).transform.position);
_activeScanCoroutine = ((MonoBehaviour)this).StartCoroutine(ContinuousScanLoopCoroutine());
}
}
private void Color_SettingChanged(object sender, EventArgs e)
{
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
Log.LogMessage((object)"[Foothold] Color configuration changed mid-game. Refreshing visuals...");
ResolveColorSettings();
if ((Object)(object)Camera.main != (Object)null)
{
((MonoBehaviour)this).StartCoroutine(PerformSlidingWindowScan(((Component)Camera.main).transform.position));
}
}
private void Update()
{
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)_standableParticleSystem == (Object)null) && !((Object)(object)_nonStandableParticleSystem == (Object)null) && !((Object)(object)Camera.main == (Object)null) && Input.GetKeyDown(configActivationKey.Value))
{
if (configMode.Value == Mode.Continuous)
{
ToggleContinuousMode();
}
else if (configMode.Value == Mode.Trigger || configMode.Value == Mode.FadeAway || configMode.Value == Mode.Toggle)
{
ExecuteSingleTriggerScan();
}
}
}
private void ExecuteSingleTriggerScan()
{
//IL_011e: Unknown result type (might be due to invalid IL or missing references)
if (_isContinuousModeActive)
{
return;
}
if (configMode.Value == Mode.Toggle)
{
bool flag = (Object)(object)_standableParticleSystem != (Object)null && _standableParticleSystem.particleCount > 0;
bool flag2 = (Object)(object)_nonStandableParticleSystem != (Object)null && _nonStandableParticleSystem.particleCount > 0;
if (flag || flag2)
{
Log.LogMessage((object)$"[Foothold] ({configMode.Value}) indicators are active. Toggling them OFF.");
if (_activeStandableFadeCoroutine != null)
{
((MonoBehaviour)this).StopCoroutine(_activeStandableFadeCoroutine);
_activeStandableFadeCoroutine = null;
}
if (_activeNonStandableFadeCoroutine != null)
{
((MonoBehaviour)this).StopCoroutine(_activeNonStandableFadeCoroutine);
_activeNonStandableFadeCoroutine = null;
}
if ((Object)(object)_standableParticleSystem != (Object)null)
{
_standableParticleSystem.Clear();
}
if ((Object)(object)_nonStandableParticleSystem != (Object)null)
{
_nonStandableParticleSystem.Clear();
}
return;
}
}
Log.LogMessage((object)$"[Foothold] Single Scan ({configMode.Value}) requested. Toggling indicators ON.");
((MonoBehaviour)this).StartCoroutine(PerformSlidingWindowScan(((Component)Camera.main).transform.position));
}
private void ToggleContinuousMode()
{
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_003c: Unknown result type (might be due to invalid IL or missing references)
_isContinuousModeActive = !_isContinuousModeActive;
if (_isContinuousModeActive)
{
Log.LogMessage((object)"[Foothold] Continuous Mode: ACTIVATED.");
_lastContinuousSnappedPos3D = SnapToGrid(((Component)Camera.main).transform.position);
_activeScanCoroutine = ((MonoBehaviour)this).StartCoroutine(ContinuousScanLoopCoroutine());
return;
}
Log.LogMessage((object)"[Foothold] Continuous Mode: DEACTIVATED.");
if (_activeScanCoroutine != null)
{
((MonoBehaviour)this).StopCoroutine(_activeScanCoroutine);
_activeScanCoroutine = null;
}
if ((Object)(object)_standableParticleSystem != (Object)null)
{
_standableParticleSystem.Clear();
}
if ((Object)(object)_nonStandableParticleSystem != (Object)null)
{
_nonStandableParticleSystem.Clear();
}
_columnCache.Clear();
}
private IEnumerator ContinuousScanLoopCoroutine()
{
Vector3 lastScanActualPosition = ((Component)Camera.main).transform.position;
yield return ((MonoBehaviour)this).StartCoroutine(PerformSlidingWindowScan(lastScanActualPosition));
while (_isContinuousModeActive)
{
yield return (object)new WaitForSeconds(0.5f);
if (!((Object)(object)Camera.main == (Object)null) && _isContinuousModeActive)
{
Vector3 position = ((Component)Camera.main).transform.position;
Vector3 val = position - lastScanActualPosition;
if (!(((Vector3)(ref val)).sqrMagnitude < 1f))
{
lastScanActualPosition = position;
yield return ((MonoBehaviour)this).StartCoroutine(PerformSlidingWindowScan(position));
}
}
}
}
private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
//IL_0055: Unknown result type (might be due to invalid IL or missing references)
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
_columnCache.Clear();
_isContinuousModeActive = false;
if (_activeScanCoroutine != null)
{
((MonoBehaviour)this).StopCoroutine(_activeScanCoroutine);
_activeScanCoroutine = null;
}
if (((Scene)(ref scene)).name.StartsWith("Level_") || ((Scene)(ref scene)).name.StartsWith("Airport"))
{
_terrainLayerMask = HelperFunctions.GetMask((LayerType)1);
ResolveColorSettings();
InitializeParticleSystem();
}
}
private void InitializeParticleSystem()
{
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Expected O, but got Unknown
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
//IL_0034: Expected O, but got Unknown
//IL_006d: Unknown result type (might be due to invalid IL or missing references)
//IL_0077: Expected O, but got Unknown
//IL_013e: Unknown result type (might be due to invalid IL or missing references)
//IL_0144: Expected O, but got Unknown
//IL_017d: Unknown result type (might be due to invalid IL or missing references)
//IL_0187: Expected O, but got Unknown
if ((Object)(object)_particleSystemObject != (Object)null)
{
Object.Destroy((Object)(object)_particleSystemObject);
}
_particleSystemObject = new GameObject("Foothold_ParticleVisualizer");
GameObject val = new GameObject("StandableSystem");
val.transform.SetParent(_particleSystemObject.transform);
_standableParticleSystem = val.AddComponent<ParticleSystem>();
ConfigureBillboardModule(_standableParticleSystem);
_proceduralDonutMaterial = new Material(Shader.Find("Universal Render Pipeline/Particles/Unlit"));
_proceduralDonutMaterial.renderQueue = 3510;
_proceduralDonutMaterial.SetFloat("_Surface", 1f);
_proceduralDonutMaterial.SetFloat("_Blend", 1f);
_proceduralDonutMaterial.SetInt("_SrcBlend", 1);
_proceduralDonutMaterial.SetInt("_DstBlend", 1);
_proceduralDonutMaterial.SetInt("_ZWrite", 0);
_proceduralDonutMaterial.EnableKeyword("_SURFACE_TYPE_TRANSPARENT");
_proceduralDonutMaterial.EnableKeyword("_BLENDMODE_ADD");
_proceduralDonutMaterial.SetTexture("_BaseMap", (Texture)(object)CreateDonutTexture(52));
val.GetComponent<ParticleSystemRenderer>().renderMode = (ParticleSystemRenderMode)0;
((Renderer)val.GetComponent<ParticleSystemRenderer>()).material = _proceduralDonutMaterial;
GameObject val2 = new GameObject("NonStandableSystem");
val2.transform.SetParent(_particleSystemObject.transform);
_nonStandableParticleSystem = val2.AddComponent<ParticleSystem>();
ConfigureBillboardModule(_nonStandableParticleSystem);
_proceduralCrossMaterial = new Material(Shader.Find("Universal Render Pipeline/Particles/Unlit"));
_proceduralCrossMaterial.renderQueue = 3500;
_proceduralCrossMaterial.SetFloat("_Surface", 1f);
_proceduralCrossMaterial.SetFloat("_Blend", 1f);
_proceduralCrossMaterial.SetInt("_SrcBlend", 1);
_proceduralCrossMaterial.SetInt("_DstBlend", 1);
_proceduralCrossMaterial.SetInt("_ZWrite", 0);
_proceduralCrossMaterial.EnableKeyword("_SURFACE_TYPE_TRANSPARENT");
_proceduralCrossMaterial.EnableKeyword("_BLENDMODE_ADD");
_proceduralCrossMaterial.SetTexture("_BaseMap", (Texture)(object)CreateCrossTexture(52));
val2.GetComponent<ParticleSystemRenderer>().renderMode = (ParticleSystemRenderMode)0;
((Renderer)val2.GetComponent<ParticleSystemRenderer>()).material = _proceduralCrossMaterial;
}
private void ConfigureBillboardModule(ParticleSystem ps)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
EmissionModule emission = ps.emission;
((EmissionModule)(ref emission)).enabled = false;
MainModule main = ps.main;
((MainModule)(ref main)).simulationSpace = (ParticleSystemSimulationSpace)1;
((MainModule)(ref main)).loop = false;
((MainModule)(ref main)).playOnAwake = false;
((MainModule)(ref main)).maxParticles = 50000;
ColorOverLifetimeModule colorOverLifetime = ps.colorOverLifetime;
((ColorOverLifetimeModule)(ref colorOverLifetime)).enabled = false;
}
private void CalculateVerticalColumnData(Vector3 raycastOrigin, float raycastDistance)
{
//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_0015: 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_0046: 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_004e: Unknown result type (might be due to invalid IL or missing references)
//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
_columnWorkerBufferCount = 0;
int num = Physics.RaycastNonAlloc(raycastOrigin, Vector3.down, _raycastHitBuffer, raycastDistance, LayerMask.op_Implicit(_terrainLayerMask), (QueryTriggerInteraction)1);
for (int i = 0; i < num; i++)
{
if (_columnWorkerBufferCount >= 10)
{
break;
}
RaycastHit val = _raycastHitBuffer[i];
float num2 = Vector3.Angle(Vector3.up, ((RaycastHit)(ref val)).normal);
if (!(num2 <= 30f))
{
bool isStandable = true;
CollisionModifier component = ((Component)((RaycastHit)(ref val)).collider).GetComponent<CollisionModifier>();
if ((Object)(object)component != (Object)null)
{
isStandable = component.standable;
}
_columnWorkerBuffer[_columnWorkerBufferCount] = new CachedResult
{
HasHit = true,
HitPoint = ((RaycastHit)(ref val)).point,
Angle = num2,
IsStandable = isStandable,
HitNormal = ((RaycastHit)(ref val)).normal
};
_columnWorkerBufferCount++;
}
}
}
private IEnumerator PerformSlidingWindowScan(Vector3 centerPosition)
{
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
Vector2Int centerSnapped2D = SnapToGrid2D(centerPosition);
_centerWorldPosBuffer.x = (float)((Vector2Int)(ref centerSnapped2D)).x * 0.5f;
_centerWorldPosBuffer.y = centerPosition.y;
_centerWorldPosBuffer.z = (float)((Vector2Int)(ref centerSnapped2D)).y * 0.5f;
float raycastStartY = _centerWorldPosBuffer.y + 10f;
float raycastDistance = 20f;
float maxDistanceSq = 625f;
Vector3 val2;
if (configMode.Value != Mode.FadeAway)
{
int count = _columnCache.Count;
if (_keyPruneArrayBuffer.Length < count)
{
_keyPruneArrayBuffer = new int[count + 1000];
}
_columnCache.Keys.CopyTo(_keyPruneArrayBuffer, 0);
Vector3 val = default(Vector3);
for (int i = 0; i < count; i++)
{
int num = _keyPruneArrayBuffer[i];
int num2 = num >> 22;
int num3 = num & 0x3FF;
if ((num2 & 0x200) != 0)
{
num2 |= -1024;
}
if ((num3 & 0x200) != 0)
{
num3 |= -1024;
}
((Vector3)(ref val))..ctor((float)num2 * 0.5f, centerPosition.y, (float)num3 * 0.5f);
val2 = val - centerPosition;
if (((Vector3)(ref val2)).sqrMagnitude > maxDistanceSq)
{
_columnCache.Remove(num);
}
}
}
_budgetTimer.Restart();
_standableParticlesList.Clear();
_nonStandableParticlesList.Clear();
for (_xPosCalc = -15f; _xPosCalc <= 15f; _xPosCalc += 0.5f)
{
for (_zPosCalc = -15f; _zPosCalc <= 15f; _zPosCalc += 0.5f)
{
_xGridKey = ((Vector2Int)(ref centerSnapped2D)).x + Mathf.RoundToInt(_xPosCalc * 2f);
_zGridKey = ((Vector2Int)(ref centerSnapped2D)).y + Mathf.RoundToInt(_zPosCalc * 2f);
_uniqueIntKey = ((_xGridKey & 0x3FF) << 22) | ((Mathf.RoundToInt(centerPosition.y * 2f) & 0xFFF) << 10) | (_zGridKey & 0x3FF);
if (!_columnCache.TryGetValue(_uniqueIntKey, out var value))
{
_raycastOriginBuffer.x = _centerWorldPosBuffer.x + _xPosCalc;
_raycastOriginBuffer.y = raycastStartY;
_raycastOriginBuffer.z = _centerWorldPosBuffer.z + _zPosCalc;
CalculateVerticalColumnData(_raycastOriginBuffer, raycastDistance);
value = new FixedColumnData
{
HitCount = Mathf.Min(_columnWorkerBufferCount, 10)
};
if (value.HitCount >= 1)
{
value.Hit1 = _columnWorkerBuffer[0];
}
if (value.HitCount >= 2)
{
value.Hit2 = _columnWorkerBuffer[1];
}
if (value.HitCount >= 3)
{
value.Hit3 = _columnWorkerBuffer[2];
}
if (value.HitCount >= 4)
{
value.Hit4 = _columnWorkerBuffer[3];
}
if (value.HitCount >= 5)
{
value.Hit5 = _columnWorkerBuffer[4];
}
if (value.HitCount >= 6)
{
value.Hit6 = _columnWorkerBuffer[5];
}
if (value.HitCount >= 7)
{
value.Hit7 = _columnWorkerBuffer[6];
}
if (value.HitCount >= 8)
{
value.Hit8 = _columnWorkerBuffer[7];
}
if (value.HitCount >= 9)
{
value.Hit9 = _columnWorkerBuffer[8];
}
if (value.HitCount >= 10)
{
value.Hit10 = _columnWorkerBuffer[9];
}
_columnCache[_uniqueIntKey] = value;
}
for (int j = 0; j < value.HitCount; j++)
{
CachedResult cachedResult = j switch
{
8 => value.Hit9,
7 => value.Hit8,
6 => value.Hit7,
5 => value.Hit6,
4 => value.Hit5,
3 => value.Hit4,
2 => value.Hit3,
1 => value.Hit2,
0 => value.Hit1,
_ => value.Hit10,
};
val2 = cachedResult.HitPoint - centerPosition;
if (((Vector3)(ref val2)).sqrMagnitude > maxDistanceSq)
{
continue;
}
bool flag = cachedResult.IsStandable && cachedResult.Angle < 50f;
Color val3 = (flag ? _standableColorValue : _nonStandableColorValue);
float num4 = 0.15f;
Vector3 position = cachedResult.HitPoint + cachedResult.HitNormal * num4;
float remainingLifetime = ((configMode.Value == Mode.FadeAway) ? 4f : float.PositiveInfinity);
Particle val4 = default(Particle);
((Particle)(ref val4)).position = position;
((Particle)(ref val4)).startColor = Color32.op_Implicit(val3);
((Particle)(ref val4)).startSize = 0.2f;
((Particle)(ref val4)).remainingLifetime = remainingLifetime;
Particle item = val4;
for (int k = 0; k < IndicatorDensityMultiplier.Value; k++)
{
if (flag)
{
_standableParticlesList.Add(item);
}
else
{
_nonStandableParticlesList.Add(item);
}
}
}
if (_budgetTimer.Elapsed.TotalMilliseconds > 1.5)
{
yield return null;
_budgetTimer.Restart();
}
}
}
int count2 = _standableParticlesList.Count;
if ((Object)(object)_standableParticleSystem != (Object)null)
{
if (count2 > 0)
{
if (_standableDataBuffer.Length < count2)
{
_standableDataBuffer = (Particle[])(object)new Particle[count2 + 1000];
}
_standableParticlesList.CopyTo(_standableDataBuffer);
_standableParticleSystem.SetParticles(_standableDataBuffer, count2);
if (configMode.Value == Mode.FadeAway)
{
if (_activeStandableFadeCoroutine != null)
{
((MonoBehaviour)this).StopCoroutine(_activeStandableFadeCoroutine);
}
_activeStandableFadeCoroutine = ((MonoBehaviour)this).StartCoroutine(SmoothStandableFadeRoutine(_standableParticleSystem, _standableDataBuffer, count2));
}
}
else if (configMode.Value == Mode.Continuous)
{
_standableParticleSystem.Clear();
}
}
int count3 = _nonStandableParticlesList.Count;
if (!((Object)(object)_nonStandableParticleSystem != (Object)null))
{
yield break;
}
if (count3 > 0)
{
if (_nonStandableDataBuffer.Length < count3)
{
_nonStandableDataBuffer = (Particle[])(object)new Particle[count3 + 1000];
}
_nonStandableParticlesList.CopyTo(_nonStandableDataBuffer);
_nonStandableParticleSystem.SetParticles(_nonStandableDataBuffer, count3);
if (configMode.Value == Mode.FadeAway)
{
if (_activeNonStandableFadeCoroutine != null)
{
((MonoBehaviour)this).StopCoroutine(_activeNonStandableFadeCoroutine);
}
_activeNonStandableFadeCoroutine = ((MonoBehaviour)this).StartCoroutine(SmoothNonStandableFadeRoutine(_nonStandableParticleSystem, _nonStandableDataBuffer, count3));
}
}
else if (configMode.Value == Mode.Continuous)
{
_nonStandableParticleSystem.Clear();
}
}
private IEnumerator SmoothStandableFadeRoutine(ParticleSystem targetSystem, Particle[] systemBuffer, int particleCount)
{
yield return (object)new WaitForSeconds(3f);
float elapsedFadeTime = 0f;
float fadeDuration = 1f;
Color baseConfigColor = _standableColorValue;
while (elapsedFadeTime < fadeDuration)
{
elapsedFadeTime += Time.deltaTime;
float num = Mathf.Clamp01(1f - elapsedFadeTime / fadeDuration);
if ((Object)(object)targetSystem == (Object)null || configMode.Value != Mode.FadeAway)
{
yield break;
}
targetSystem.GetParticles(systemBuffer, particleCount);
for (int i = 0; i < particleCount; i++)
{
((Particle)(ref systemBuffer[i])).startColor = Color32.op_Implicit(new Color(baseConfigColor.r * num, baseConfigColor.g * num, baseConfigColor.b * num, 1f));
}
targetSystem.SetParticles(systemBuffer, particleCount);
yield return null;
}
if ((Object)(object)targetSystem != (Object)null)
{
targetSystem.Clear();
}
_activeStandableFadeCoroutine = null;
}
private IEnumerator SmoothNonStandableFadeRoutine(ParticleSystem targetSystem, Particle[] systemBuffer, int particleCount)
{
yield return (object)new WaitForSeconds(3f);
float elapsedFadeTime = 0f;
float fadeDuration = 1f;
Color baseConfigColor = _nonStandableColorValue;
while (elapsedFadeTime < fadeDuration)
{
elapsedFadeTime += Time.deltaTime;
float num = Mathf.Clamp01(1f - elapsedFadeTime / fadeDuration);
if ((Object)(object)targetSystem == (Object)null || configMode.Value != Mode.FadeAway)
{
yield break;
}
targetSystem.GetParticles(systemBuffer, particleCount);
for (int i = 0; i < particleCount; i++)
{
((Particle)(ref systemBuffer[i])).startColor = Color32.op_Implicit(new Color(baseConfigColor.r * num, baseConfigColor.g * num, baseConfigColor.b * num, 1f));
}
targetSystem.SetParticles(systemBuffer, particleCount);
yield return null;
}
if ((Object)(object)targetSystem != (Object)null)
{
targetSystem.Clear();
}
_activeNonStandableFadeCoroutine = null;
}
private void BindConfig()
{
//IL_0083: Unknown result type (might be due to invalid IL or missing references)
//IL_008d: Expected O, but got Unknown
configStandableBallColor = ((BaseUnityPlugin)this).Config.Bind<StandableColor>("General", "Standable ground Color", StandableColor.Green, "Change the ball color of standable ground.");
configNonStandableBallColor = ((BaseUnityPlugin)this).Config.Bind<NonStandableColor>("General", "Non-standable ground Color", NonStandableColor.Red, "Change the ball color of non-standable ground.");
configActivationKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("General", "Activation Key", (KeyCode)102, (ConfigDescription)null);
IndicatorDensityMultiplier = ((BaseUnityPlugin)this).Config.Bind<int>("General", "Indicators Density", 3, new ConfigDescription("Density of the indicator. Higher value makes them easier to see in bright daylight.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 5), Array.Empty<object>()));
configMode = ((BaseUnityPlugin)this).Config.Bind<Mode>("General", "Activation Mode", Mode.FadeAway, "Toggle: Press once to activate. Press again to hide.\r\nTrigger: Activates every time the button is pressed. The indicators will remain visible.\r\nFade Away: Activates every time the button is pressed. The indicators will fade away after 3 seconds.\r\nContinuous: Press once to activate repeat scanning. Press again to stop.");
}
private Vector2Int SnapToGrid2D(Vector3 position)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
return new Vector2Int(Mathf.RoundToInt(position.x * 2f + 1E-06f), Mathf.RoundToInt(position.z * 2f + 1E-06f));
}
private Vector3Int SnapToGrid(Vector3 position)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: 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)
return new Vector3Int(Mathf.RoundToInt(position.x * 2f + 1E-06f), Mathf.RoundToInt(position.y * 2f + 1E-06f), Mathf.RoundToInt(position.z * 2f + 1E-06f));
}
private void ResolveColorSettings()
{
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: 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)
//IL_0036: 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)
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
_standableColorValue = ((configStandableBallColor.Value == StandableColor.Green) ? Color.green : Color.white);
_nonStandableColorValue = ((configNonStandableBallColor.Value == NonStandableColor.Magenta) ? Color.magenta : Color.red);
_standableColorValue.a = 1f;
_nonStandableColorValue.a = 1f;
}
private Texture2D CreateDonutTexture(int size)
{
//IL_0004: Unknown result type (might be due to invalid IL or missing references)
//IL_000a: Expected O, but got Unknown
//IL_008a: Unknown result type (might be due to invalid IL or missing references)
//IL_0079: Unknown result type (might be due to invalid IL or missing references)
Texture2D val = new Texture2D(size, size, (TextureFormat)4, false);
float num = (float)size / 2f;
float num2 = (float)size * 0.46f;
float num3 = (float)size * 0.24f;
Color val2 = default(Color);
((Color)(ref val2))..ctor(0f, 0f, 0f, 1f);
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size; j++)
{
float num4 = (float)i - num;
float num5 = (float)j - num;
float num6 = Mathf.Sqrt(num4 * num4 + num5 * num5);
if (num6 <= num2 && num6 >= num3)
{
val.SetPixel(i, j, Color.white);
}
else
{
val.SetPixel(i, j, val2);
}
}
}
val.Apply();
return val;
}
private Texture2D CreateCrossTexture(int size)
{
//IL_0004: Unknown result type (might be due to invalid IL or missing references)
//IL_000a: Expected O, but got Unknown
//IL_007b: Unknown result type (might be due to invalid IL or missing references)
//IL_006a: Unknown result type (might be due to invalid IL or missing references)
Texture2D val = new Texture2D(size, size, (TextureFormat)4, false);
int num = size - 1;
float num2 = 10f;
Color val2 = default(Color);
((Color)(ref val2))..ctor(0f, 0f, 0f, 1f);
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size; j++)
{
float num3 = Mathf.Abs(i - j);
float num4 = Mathf.Abs(i + j - num);
float num5 = Mathf.Min(num3, num4);
if (num5 <= num2)
{
val.SetPixel(i, j, Color.white);
}
else
{
val.SetPixel(i, j, val2);
}
}
}
val.Apply();
return val;
}
}
}
namespace System.Diagnostics.CodeAnalysis
{
[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class ConstantExpectedAttribute : Attribute
{
public object? Min { get; set; }
public object? Max { get; set; }
}
[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class ExperimentalAttribute : Attribute
{
public string DiagnosticId { get; }
public string? UrlFormat { get; set; }
public ExperimentalAttribute(string diagnosticId)
{
DiagnosticId = diagnosticId;
}
}
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
[ExcludeFromCodeCoverage]
internal sealed class MemberNotNullAttribute : Attribute
{
public string[] Members { get; }
public MemberNotNullAttribute(string member)
{
Members = new string[1] { member };
}
public MemberNotNullAttribute(params string[] members)
{
Members = members;
}
}
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
[ExcludeFromCodeCoverage]
internal sealed class MemberNotNullWhenAttribute : Attribute
{
public bool ReturnValue { get; }
public string[] Members { get; }
public MemberNotNullWhenAttribute(bool returnValue, string member)
{
ReturnValue = returnValue;
Members = new string[1] { member };
}
public MemberNotNullWhenAttribute(bool returnValue, params string[] members)
{
ReturnValue = returnValue;
Members = members;
}
}
[AttributeUsage(AttributeTargets.Constructor, AllowMultiple = false, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class SetsRequiredMembersAttribute : Attribute
{
}
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class StringSyntaxAttribute : Attribute
{
public const string CompositeFormat = "CompositeFormat";
public const string DateOnlyFormat = "DateOnlyFormat";
public const string DateTimeFormat = "DateTimeFormat";
public const string EnumFormat = "EnumFormat";
public const string GuidFormat = "GuidFormat";
public const string Json = "Json";
public const string NumericFormat = "NumericFormat";
public const string Regex = "Regex";
public const string TimeOnlyFormat = "TimeOnlyFormat";
public const string TimeSpanFormat = "TimeSpanFormat";
public const string Uri = "Uri";
public const string Xml = "Xml";
public string Syntax { get; }
public object?[] Arguments { get; }
public StringSyntaxAttribute(string syntax)
{
Syntax = syntax;
Arguments = new object[0];
}
public StringSyntaxAttribute(string syntax, params object?[] arguments)
{
Syntax = syntax;
Arguments = arguments;
}
}
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class UnscopedRefAttribute : Attribute
{
}
}
namespace System.Runtime.Versioning
{
[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class RequiresPreviewFeaturesAttribute : Attribute
{
public string? Message { get; }
public string? Url { get; set; }
public RequiresPreviewFeaturesAttribute()
{
}
public RequiresPreviewFeaturesAttribute(string? message)
{
Message = message;
}
}
}
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
internal sealed class IgnoresAccessChecksToAttribute : Attribute
{
public IgnoresAccessChecksToAttribute(string assemblyName)
{
}
}
[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class CallerArgumentExpressionAttribute : Attribute
{
public string ParameterName { get; }
public CallerArgumentExpressionAttribute(string parameterName)
{
ParameterName = parameterName;
}
}
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class CollectionBuilderAttribute : Attribute
{
public Type BuilderType { get; }
public string MethodName { get; }
public CollectionBuilderAttribute(Type builderType, string methodName)
{
BuilderType = builderType;
MethodName = methodName;
}
}
[AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class CompilerFeatureRequiredAttribute : Attribute
{
public const string RefStructs = "RefStructs";
public const string RequiredMembers = "RequiredMembers";
public string FeatureName { get; }
public bool IsOptional { get; set; }
public CompilerFeatureRequiredAttribute(string featureName)
{
FeatureName = featureName;
}
}
[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class InterpolatedStringHandlerArgumentAttribute : Attribute
{
public string[] Arguments { get; }
public InterpolatedStringHandlerArgumentAttribute(string argument)
{
Arguments = new string[1] { argument };
}
public InterpolatedStringHandlerArgumentAttribute(params string[] arguments)
{
Arguments = arguments;
}
}
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class InterpolatedStringHandlerAttribute : Attribute
{
}
[EditorBrowsable(EditorBrowsableState.Never)]
[ExcludeFromCodeCoverage]
internal static class IsExternalInit
{
}
[AttributeUsage(AttributeTargets.Method, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class ModuleInitializerAttribute : Attribute
{
}
[AttributeUsage(AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class OverloadResolutionPriorityAttribute : Attribute
{
public int Priority { get; }
public OverloadResolutionPriorityAttribute(int priority)
{
Priority = priority;
}
}
[AttributeUsage(AttributeTargets.Parameter, Inherited = true, AllowMultiple = false)]
[ExcludeFromCodeCoverage]
internal sealed class ParamCollectionAttribute : Attribute
{
}
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class RequiredMemberAttribute : Attribute
{
}
[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
[EditorBrowsable(EditorBrowsableState.Never)]
[ExcludeFromCodeCoverage]
internal sealed class RequiresLocationAttribute : Attribute
{
}
[AttributeUsage(AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Event | AttributeTargets.Interface, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class SkipLocalsInitAttribute : Attribute
{
}
}