Decompiled source of VentrixSyncDisks v0.8.0

VentrixSyncDisks.dll

Decompiled 6 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Il2CppInterop.Runtime.Attributes;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem.Collections.Generic;
using Microsoft.CodeAnalysis;
using SOD.Common;
using SOD.Common.BepInEx;
using SOD.Common.Helpers;
using SOD.Common.Helpers.SyncDiskObjects;
using UnityEngine;
using UniverseLib;
using VentrixSyncDisks.Hooks;
using VentrixSyncDisks.Implementation.Common;
using VentrixSyncDisks.Implementation.Config;
using VentrixSyncDisks.Implementation.Config.Caches;
using VentrixSyncDisks.Implementation.Disks;
using VentrixSyncDisks.Implementation.Freakouts;
using VentrixSyncDisks.Implementation.Mapping;
using VentrixSyncDisks.Implementation.Mapping.Explorer;
using VentrixSyncDisks.Implementation.Pooling;
using VentrixSyncDisks.Implementation.Snooping;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("Arsonide")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyCopyright("Arsonide")]
[assembly: AssemblyDescription("Plugin that adds three sync disks with vent related abilities to Shadows of Doubt.")]
[assembly: AssemblyFileVersion("0.8.0")]
[assembly: AssemblyInformationalVersion("0.8.0")]
[assembly: AssemblyProduct("VentrixSyncDisks")]
[assembly: AssemblyTitle("VentrixSyncDisks")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/Arsonide/VentrixSyncDisks")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.8.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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace VentrixSyncDisks
{
	[BepInPlugin("VentrixSyncDisks", "VentrixSyncDisks", "0.8.0")]
	public class VentrixPlugin : PluginController<VentrixPlugin>
	{
		public static Action OnLoaded;

		public override void Load()
		{
			((PluginController<VentrixPlugin, IEmptyBindings>)(object)this).Load();
			VentrixConfig.Initialize(base.Config);
			if (!VentrixConfig.Enabled.Value)
			{
				Utilities.Log("Plugin VentrixSyncDisks is disabled.", (LogLevel)16);
				return;
			}
			Utilities.Log("Plugin VentrixSyncDisks is loaded!", (LogLevel)16);
			((PluginController<VentrixPlugin, IEmptyBindings>)(object)this).Harmony.PatchAll();
			Utilities.Log("Plugin VentrixSyncDisks is patched!", (LogLevel)16);
			ClassInjector.RegisterTypeInIl2Cpp<BasePoolObject>();
			ClassInjector.RegisterTypeInIl2Cpp<DuctMarker>();
			ClassInjector.RegisterTypeInIl2Cpp<EcholocationPulse>();
			ClassInjector.RegisterTypeInIl2Cpp<SnoopHighlighter>();
			ClassInjector.RegisterTypeInIl2Cpp<Timer>();
			Utilities.Log("Plugin VentrixSyncDisks has added custom types!", (LogLevel)16);
			Initialize();
		}

		public override bool Unload()
		{
			Uninitialize();
			return ((PluginController<VentrixPlugin, IEmptyBindings>)(object)this).Unload();
		}

		private void Initialize()
		{
			DiskRegistry.Initialize();
			SnoopManager.Initialize();
			FreakoutManager.Initialize();
			InputManager.Initialize();
			Lib.SaveGame.OnAfterLoad -= OnAfterLoad;
			Lib.SaveGame.OnAfterLoad += OnAfterLoad;
		}

		private void Uninitialize()
		{
			if (EcholocationPulsePool.Instance != null)
			{
				EcholocationPulsePool.Instance.Uninitialize();
			}
			if (SnoopHighlighterPool.Instance != null)
			{
				SnoopHighlighterPool.Instance.Uninitialize();
			}
			if (DuctMarkerPool.Instance != null)
			{
				DuctMarkerPool.Instance.Uninitialize();
			}
			DiskRegistry.Uninitialize();
			SnoopManager.Uninitialize();
			FreakoutManager.Uninitialize();
			InputManager.Uninitialize();
			Lib.SaveGame.OnAfterLoad -= OnAfterLoad;
		}

		private void OnAfterLoad(object sender, SaveGameArgs args)
		{
			if (EcholocationPulsePool.Instance == null)
			{
				EcholocationPulsePool.Instance = new EcholocationPulsePool();
				EcholocationPulsePool.Instance.Initialize();
			}
			if (SnoopHighlighterPool.Instance == null)
			{
				SnoopHighlighterPool.Instance = new SnoopHighlighterPool();
				SnoopHighlighterPool.Instance.Initialize();
			}
			if (DuctMarkerPool.Instance == null)
			{
				DuctMarkerPool.Instance = new DuctMarkerPool();
				DuctMarkerPool.Instance.Initialize();
			}
			Timer.Create();
			OnLoaded?.Invoke();
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "VentrixSyncDisks";

		public const string PLUGIN_NAME = "VentrixSyncDisks";

		public const string PLUGIN_VERSION = "0.8.0";
	}
}
namespace VentrixSyncDisks.Implementation.Snooping
{
	public class SnoopHighlighter : BasePoolObject
	{
		private const int HIGHLIGHTED_LAYER = 30;

		private const int ACTOR_UNHIGHLIGHTED_LAYER = 24;

		private readonly List<GameObject> _highlightObjects = new List<GameObject>();

		private readonly List<int> _highlightLayers = new List<int>();

		private bool _isActor;

		private Actor _actor;

		private NewRoom _startRoom;

		private void OnEnable()
		{
			VentrixPlugin.OnLoaded = (Action)Delegate.Remove(VentrixPlugin.OnLoaded, new Action(OnLoaded));
			VentrixPlugin.OnLoaded = (Action)Delegate.Combine(VentrixPlugin.OnLoaded, new Action(OnLoaded));
		}

		private void OnDisable()
		{
			VentrixPlugin.OnLoaded = (Action)Delegate.Remove(VentrixPlugin.OnLoaded, new Action(OnLoaded));
		}

		private void OnLoaded()
		{
			SnoopHighlighterPool.Instance.CheckinPoolObject(this);
		}

		public override void OnCheckout()
		{
			base.OnCheckout();
			ResetDefaults();
		}

		public override void OnCheckin()
		{
			base.OnCheckin();
			Cleanup();
			ResetDefaults();
		}

		private void ResetDefaults()
		{
			_highlightObjects.Clear();
			_highlightLayers.Clear();
			_isActor = false;
			_actor = null;
			_startRoom = null;
		}

		public void Setup(NewRoom room, Actor actor)
		{
			_isActor = true;
			_actor = actor;
			_startRoom = room;
		}

		public void Setup(NewRoom room, GameObject staticObject)
		{
			if ((Object)(object)staticObject != (Object)null)
			{
				_highlightObjects.Add(staticObject);
				_highlightLayers.Add(staticObject.layer);
				staticObject.layer = 30;
			}
			_isActor = false;
			_startRoom = room;
		}

		public void Setup(NewRoom room, GameObject staticObject, GameObject auxObject)
		{
			if ((Object)(object)staticObject != (Object)null)
			{
				_highlightObjects.Add(staticObject);
				_highlightLayers.Add(staticObject.layer);
				staticObject.layer = 30;
			}
			if ((Object)(object)auxObject != (Object)null)
			{
				_highlightObjects.Add(auxObject);
				_highlightLayers.Add(auxObject.layer);
				auxObject.layer = 30;
			}
			_isActor = false;
			_startRoom = room;
		}

		private void Cleanup()
		{
			for (int num = _highlightObjects.Count - 1; num >= 0; num--)
			{
				GameObject val = _highlightObjects[num];
				if (!_isActor)
				{
					if ((Object)(object)val != (Object)null)
					{
						val.layer = _highlightLayers[num];
					}
					_highlightObjects.RemoveAt(num);
					_highlightLayers.RemoveAt(num);
				}
				else
				{
					if ((Object)(object)val != (Object)null)
					{
						val.layer = (((Object)(object)_actor != (Object)null && _actor.outline.outlineActive) ? 30 : 24);
					}
					_highlightObjects.RemoveAt(num);
				}
			}
		}

		private void LateUpdate()
		{
			if (ShouldReturnToPool())
			{
				SnoopHighlighterPool.Instance.CheckinPoolObject(this);
			}
			else
			{
				if (!_isActor)
				{
					return;
				}
				for (int num = _highlightObjects.Count - 1; num >= 0; num--)
				{
					GameObject val = _highlightObjects[num];
					if ((Object)(object)val != (Object)null)
					{
						val.layer = 24;
					}
					_highlightObjects.RemoveAt(num);
				}
				Enumerator<MeshRenderer> enumerator = _actor.outline.meshesToOutline.GetEnumerator();
				while (enumerator.MoveNext())
				{
					MeshRenderer current = enumerator.Current;
					if (!((Object)(object)current == (Object)null))
					{
						GameObject gameObject = ((Component)current).gameObject;
						_highlightObjects.Add(gameObject);
						gameObject.layer = 30;
						((Renderer)current).SetPropertyBlock(SnoopHighlighterPool.FullAlphaBlock);
					}
				}
			}
		}

		private bool ShouldReturnToPool()
		{
			if (!SnoopManager.IsSnooping || (Object)(object)SnoopManager.SnoopingRoom == (Object)null)
			{
				return true;
			}
			int level = DiskRegistry.SnoopingDisk.Level;
			if (level <= 0 || (Object)(object)SnoopManager.SnoopingRoom == (Object)null)
			{
				return true;
			}
			if (_isActor)
			{
				if (!VentrixConfig.SnoopingCanSnoopCivilians.GetLevel(level))
				{
					return true;
				}
				return (Object)(object)_actor == (Object)null || (Object)(object)_actor.outline == (Object)null || (Object)(object)_actor.currentRoom == (Object)null || !Utilities.RoomsEqual(SnoopManager.SnoopingRoom, _actor.currentRoom);
			}
			if (!VentrixConfig.SnoopingCanSnoopSecurity.GetLevel(level))
			{
				return true;
			}
			return !Utilities.RoomsEqual(SnoopManager.SnoopingRoom, _startRoom);
		}
	}
	public class SnoopHighlighterPool : BasePoolManager<SnoopHighlighter>
	{
		public static MaterialPropertyBlock FullAlphaBlock;

		private static readonly int _fullAlphaKey = Shader.PropertyToID("_AlphaVal");

		public static SnoopHighlighterPool Instance;

		protected override void SetupManager()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			base.SetupManager();
			FullAlphaBlock = new MaterialPropertyBlock();
			FullAlphaBlock.SetFloat(_fullAlphaKey, 1f);
		}

		protected override SnoopHighlighter CreateBaseObject()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("SnoopHighlighter");
			SnoopHighlighter result = val.AddComponent<SnoopHighlighter>();
			Transform transform = val.transform;
			transform.SetPositionAndRotation(Vector3.zero, Quaternion.identity);
			transform.localScale = Vector3.one;
			Object.DontDestroyOnLoad((Object)(object)val);
			val.SetActive(false);
			return result;
		}
	}
	public static class SnoopManager
	{
		public static bool IsSnooping;

		public static NewRoom SnoopingRoom;

		private static List<AirDuctSection> _neighbors = new List<AirDuctSection>();

		private static List<Vector3Int> _neighborOffsets = new List<Vector3Int>();

		private static List<AirVent> _vents = new List<AirVent>();

		public static void Initialize()
		{
			Reset();
			Lib.SaveGame.OnAfterLoad -= OnAfterLoad;
			Lib.SaveGame.OnAfterLoad += OnAfterLoad;
			SnoopWarp.Initialize();
		}

		public static void Uninitialize()
		{
			Reset();
			Lib.SaveGame.OnAfterLoad -= OnAfterLoad;
			SnoopWarp.Uninitialize();
		}

		private static void OnAfterLoad(object sender, SaveGameArgs args)
		{
			Reset();
		}

		public static void Reset()
		{
			IsSnooping = false;
			SnoopingRoom = null;
		}

		public static void RefreshSnoopingState()
		{
			int level = DiskRegistry.SnoopingDisk.Level;
			if (level <= 0)
			{
				IsSnooping = false;
				SnoopingRoom = null;
				return;
			}
			NewRoom snoopingRoom = SnoopingRoom;
			NewRoom playerSnoopingRoom = GetPlayerSnoopingRoom(level);
			if (!Utilities.RoomsEqual(snoopingRoom, playerSnoopingRoom))
			{
				SnoopingRoom = playerSnoopingRoom;
				IsSnooping = (Object)(object)SnoopingRoom != (Object)null;
				if ((Object)(object)playerSnoopingRoom != (Object)null)
				{
					OnEnterSnooping(playerSnoopingRoom, level);
				}
			}
		}

		private static NewRoom GetPlayerSnoopingRoom(int level)
		{
			if (level <= 0)
			{
				return null;
			}
			if ((Object)(object)Player.Instance == (Object)null)
			{
				return null;
			}
			if (!((Actor)Player.Instance).inAirVent)
			{
				return null;
			}
			AirDuctSection currentDuctSection = Player.Instance.currentDuctSection;
			if (currentDuctSection == null)
			{
				return null;
			}
			if (currentDuctSection.peekSection && VentrixConfig.SnoopingCanSnoopPeeks.GetLevel(level))
			{
				NewNode node = currentDuctSection.node;
				return (node != null) ? node.room : null;
			}
			Utilities.GetVentInformation(currentDuctSection, ref _neighbors, ref _neighborOffsets, ref _vents);
			if (_vents.Count <= 0)
			{
				return null;
			}
			AirVent val = _vents[0];
			object obj;
			if (val == null)
			{
				obj = null;
			}
			else
			{
				NewNode roomNode = val.roomNode;
				obj = ((roomNode != null) ? roomNode.room : null);
			}
			NewRoom val2 = (NewRoom)obj;
			if ((Object)(object)val2 != (Object)null)
			{
				return val2;
			}
			NewRoom val3 = ((val != null) ? val.room : null);
			if ((Object)(object)val3 != (Object)null)
			{
				return val3;
			}
			NewNode node2 = currentDuctSection.node;
			return (node2 != null) ? node2.room : null;
		}

		public static void OnActorRoomChanged(Actor actor)
		{
			if (IsSnooping && !actor.isPlayer && !actor.isMachine && Utilities.RoomsEqual(actor.currentRoom, SnoopingRoom) && VentrixConfig.SnoopingCanSnoopCivilians.GetLevel(DiskRegistry.SnoopingDisk.Level))
			{
				SnoopHighlighter snoopHighlighter = SnoopHighlighterPool.Instance.CheckoutPoolObject();
				snoopHighlighter.Setup(SnoopingRoom, actor);
			}
		}

		private static void OnEnterSnooping(NewRoom room, int level)
		{
			if (VentrixConfig.SnoopingCanSnoopCivilians.GetLevel(level))
			{
				SnoopActorsInRoom(room);
			}
			if (VentrixConfig.SnoopingCanSnoopSecurity.GetLevel(level))
			{
				SnoopSecurityInRoom(room);
			}
		}

		private static void SnoopActorsInRoom(NewRoom room)
		{
			Enumerator<Actor> enumerator = room.currentOccupants.GetEnumerator();
			while (enumerator.MoveNext())
			{
				Actor current = enumerator.Current;
				SnoopHighlighter snoopHighlighter = SnoopHighlighterPool.Instance.CheckoutPoolObject();
				snoopHighlighter.Setup(room, current);
			}
		}

		private static void SnoopSecurityInRoom(NewRoom room)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: 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)
			//IL_0024: 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)
			//IL_0028: Invalid comparison between Unknown and I4
			//IL_002c: 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_0031: Invalid comparison between Unknown and I4
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: 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_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Invalid comparison between Unknown and I4
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Invalid comparison between Unknown and I4
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Invalid comparison between Unknown and I4
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Invalid comparison between Unknown and I4
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Invalid comparison between Unknown and I4
			Enumerator<SpecialCase, List<Interactable>> enumerator = room.specialCaseInteractables.GetEnumerator();
			while (enumerator.MoveNext())
			{
				KeyValuePair<SpecialCase, List<Interactable>> current = enumerator.Current;
				SpecialCase key = current.Key;
				SpecialCase val = key;
				if (val - 7 > 1 && val - 32 > 1)
				{
					continue;
				}
				Enumerator<Interactable> enumerator2 = current.Value.GetEnumerator();
				while (enumerator2.MoveNext())
				{
					Interactable current2 = enumerator2.Current;
					if (current2 == null || (Object)(object)current2.controller == (Object)null)
					{
						continue;
					}
					SpecialCase key2 = current.Key;
					SpecialCase val2 = key2;
					if ((int)val2 <= 8)
					{
						if ((int)val2 != 7)
						{
							if ((int)val2 == 8)
							{
								SnoopHighlighter snoopHighlighter = SnoopHighlighterPool.Instance.CheckoutPoolObject();
								snoopHighlighter.Setup(room, current2.controller.isActor);
							}
						}
						else
						{
							SnoopHighlighter snoopHighlighter = SnoopHighlighterPool.Instance.CheckoutPoolObject();
							snoopHighlighter.Setup(room, ((Component)current2.controller.securitySystem.rend).gameObject);
						}
					}
					else if ((int)val2 != 32)
					{
						if ((int)val2 == 33)
						{
							SnoopHighlighter snoopHighlighter = SnoopHighlighterPool.Instance.CheckoutPoolObject();
							snoopHighlighter.Setup(room, ((Component)current2.controller).gameObject);
						}
					}
					else if (((SoCustomComparison)current2.preset).presetName.ToLowerInvariant().Contains("scout"))
					{
						GameObject gameObject = ((Component)current2.controller).gameObject;
						Transform transform = gameObject.transform;
						object obj;
						if (transform == null)
						{
							obj = null;
						}
						else
						{
							Transform child = transform.GetChild(0);
							obj = ((child != null) ? child.GetChild(0) : null);
						}
						Transform val3 = (Transform)obj;
						GameObject auxObject = ((val3 != null) ? ((Component)val3).gameObject : null);
						SnoopHighlighter snoopHighlighter = SnoopHighlighterPool.Instance.CheckoutPoolObject();
						snoopHighlighter.Setup(room, gameObject, auxObject);
					}
				}
			}
		}
	}
	public static class SnoopWarp
	{
		private static SnoopWarpState _state;

		private static float _timer;

		private static bool _notification;

		public static void Initialize()
		{
			Lib.SaveGame.OnAfterLoad -= OnAfterLoad;
			Lib.SaveGame.OnAfterLoad += OnAfterLoad;
			Reset();
		}

		public static void Uninitialize()
		{
			Lib.SaveGame.OnAfterLoad -= OnAfterLoad;
			Reset();
		}

		private static void OnAfterLoad(object sender, SaveGameArgs args)
		{
			Reset();
		}

		private static void Reset()
		{
			SetState(SnoopWarpState.None, force: true);
		}

		public static void OnUpdate()
		{
			//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)
			int level = DiskRegistry.SnoopingDisk.Level;
			if (level <= 0 || !VentrixConfig.SnoopingCanPassTime.GetLevel(level))
			{
				return;
			}
			if (!((Actor)Player.Instance).inAirVent || !((SoCustomComparison)(object)FirstPersonItemController.Instance.currentItem == (SoCustomComparison)(object)GameplayControls.Instance.watchItem) || !SnoopManager.IsSnooping)
			{
				SetState(SnoopWarpState.None);
				return;
			}
			switch (_state)
			{
			case SnoopWarpState.None:
				SetState(SnoopWarpState.Engaging);
				break;
			case SnoopWarpState.Engaging:
				_timer += Time.deltaTime;
				if (!_notification && VentrixConfig.SnoopingPassTimeNotificationDelay.Value > 0f && _timer >= VentrixConfig.SnoopingPassTimeNotificationDelay.Value)
				{
					InterfaceController.Instance.NewGameMessage((GameMessageType)0, 0, "Starting to pass time at vent...", (Icon)3, (AudioEvent)null, false, default(Color), -1, 0f, (RectTransform)null, (PingOnComplete)0, (Evidence)null, (List<DataKey>)null, (Sprite)null);
					_notification = true;
				}
				if (_timer >= VentrixConfig.SnoopingPassTimeWarpDelay.Value)
				{
					SetState(SnoopWarpState.TimeWarping);
				}
				break;
			case SnoopWarpState.TimeWarping:
				PushOutPlayerAlarm();
				DisableLoitering();
				break;
			}
		}

		private static void SetState(SnoopWarpState state, bool force = false)
		{
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			SnoopWarpState state2 = _state;
			if (force || state != state2)
			{
				_state = state;
				_timer = 0f;
				_notification = false;
				if (state2 == SnoopWarpState.TimeWarping && state != SnoopWarpState.TimeWarping)
				{
					Player.Instance.SetSpendingTimeMode(false);
					AudioController.Instance.PlayWorldOneShot(AudioControls.Instance.watchAlarm, (Actor)(object)Player.Instance, ((Actor)Player.Instance).currentNode, ((Actor)Player.Instance).lookAtThisTransform.position, (Interactable)null, (List<FMODParam>)null, 1f, (List<NewNode>)null, false, (SoundMaterialOverride)null, false);
					ResetPlayerAlarm();
				}
				SnoopWarpState snoopWarpState = state;
				SnoopWarpState snoopWarpState2 = snoopWarpState;
				if (snoopWarpState2 == SnoopWarpState.TimeWarping)
				{
					PushOutPlayerAlarm();
					Player.Instance.SetSpendingTimeMode(true);
				}
			}
		}

		private static void PushOutPlayerAlarm()
		{
			Player.Instance.alarm = SessionData.Instance.gameTime + 9999f;
		}

		private static void ResetPlayerAlarm()
		{
			Player.Instance.alarm = SessionData.Instance.gameTime - 1f;
		}

		private static void DisableLoitering()
		{
			Player instance = Player.Instance;
			object obj;
			if (instance == null)
			{
				obj = null;
			}
			else
			{
				NewRoom currentRoom = ((Actor)instance).currentRoom;
				obj = ((currentRoom != null) ? currentRoom.gameLocation : null);
			}
			if ((Object)obj != (Object)null)
			{
				((Actor)Player.Instance).currentRoom.gameLocation.ResetLoiteringTimer();
			}
		}
	}
	public enum SnoopWarpState
	{
		None,
		Engaging,
		TimeWarping
	}
}
namespace VentrixSyncDisks.Implementation.Pooling
{
	public class BasePoolManager<T> where T : BasePoolObject
	{
		private T _baseObject;

		private string _typeName = string.Empty;

		private readonly List<T> _availableObjects = new List<T>();

		private readonly List<T> _allObjects = new List<T>();

		public virtual void Initialize()
		{
			//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)
			SetupManager();
			_typeName = typeof(T).Name;
			_baseObject = CreateBaseObject();
			GameObject gameObject = ((Component)_baseObject).gameObject;
			((Object)gameObject).name = _typeName;
			Transform transform = gameObject.transform;
			transform.SetPositionAndRotation(Vector3.zero, Quaternion.identity);
			Object.DontDestroyOnLoad((Object)(object)gameObject);
			gameObject.SetActive(false);
		}

		public virtual void Uninitialize()
		{
			for (int num = _allObjects.Count - 1; num >= 0; num--)
			{
				T val = _allObjects[num];
				if (((Component)val).gameObject.activeSelf)
				{
					((Component)val).gameObject.SetActive(false);
				}
				Object.Destroy((Object)(object)((Component)val).gameObject);
			}
		}

		protected virtual void SetupManager()
		{
		}

		protected virtual T CreateBaseObject()
		{
			return null;
		}

		public T CheckoutPoolObject()
		{
			int num = _availableObjects.Count - 1;
			T copyObject;
			if (num >= 0)
			{
				copyObject = _availableObjects[num];
				_availableObjects.RemoveAt(num);
				((Component)copyObject).gameObject.SetActive(true);
			}
			else
			{
				copyObject = Object.Instantiate<T>(_baseObject);
				Object.DontDestroyOnLoad((Object)(object)((Component)copyObject).gameObject);
				((Component)copyObject).gameObject.SetActive(true);
				ConfigureCopyObject(ref copyObject);
				_allObjects.Add(copyObject);
			}
			copyObject.OnCheckout();
			return copyObject;
		}

		protected virtual void ConfigureCopyObject(ref T copyObject)
		{
		}

		public void CheckinPoolObject(T poolObject)
		{
			((Component)poolObject).gameObject.SetActive(false);
			_availableObjects.Add(poolObject);
			poolObject.OnCheckin();
		}
	}
	public abstract class BasePoolObject : MonoBehaviour
	{
		public virtual void OnCheckout()
		{
		}

		public virtual void OnCheckin()
		{
		}
	}
}
namespace VentrixSyncDisks.Implementation.Mapping
{
	public class DuctMarker : BasePoolObject
	{
		private static readonly Vector3 _minimumScale = new Vector3(float.Epsilon, float.Epsilon, float.Epsilon);

		public Renderer Renderer;

		public Transform Transform;

		private Vector3 _targetScale;

		private float _lifetime;

		private float _timer;

		private DuctMarkerState _state;

		public void OnSpawn(Vector3 targetScale, float lifetime)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			_targetScale = targetScale;
			_lifetime = lifetime;
			SetState(DuctMarkerState.Spawning, force: true);
			Transform.localScale = _minimumScale;
		}

		private void OnDespawn()
		{
			DuctMarkerPool.Instance.ReleaseMarker(this);
		}

		private void SetState(DuctMarkerState newState, bool force = false)
		{
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			DuctMarkerState state = _state;
			if (force || newState != state)
			{
				_state = newState;
				_timer = 0f;
				switch (_state)
				{
				case DuctMarkerState.Spawning:
					Transform.localScale = _minimumScale;
					break;
				case DuctMarkerState.Spawned:
					Transform.localScale = _targetScale;
					break;
				case DuctMarkerState.Despawning:
					Transform.localScale = _targetScale;
					break;
				case DuctMarkerState.Despawned:
					Transform.localScale = _minimumScale;
					OnDespawn();
					break;
				}
			}
		}

		private void Update()
		{
			_timer += GetAdjustedDeltaTime();
			switch (_state)
			{
			case DuctMarkerState.Spawning:
				UpdateSpawning();
				break;
			case DuctMarkerState.Spawned:
				UpdateSpawned();
				break;
			case DuctMarkerState.Despawning:
				UpdateDespawning();
				break;
			}
		}

		private void UpdateSpawning()
		{
			//IL_0007: 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)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			Transform.localScale = Vector3.Lerp(_minimumScale, _targetScale, _timer / VentrixConfig.RenderingNodeSpawnTime.Value);
			if (_timer >= VentrixConfig.RenderingNodeSpawnTime.Value)
			{
				SetState(DuctMarkerState.Spawned);
			}
		}

		private void UpdateSpawned()
		{
			if (_timer >= _lifetime)
			{
				SetState(DuctMarkerState.Despawning);
			}
		}

		private void UpdateDespawning()
		{
			//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)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			Transform.localScale = Vector3.Lerp(_targetScale, _minimumScale, _timer / VentrixConfig.RenderingNodeDespawnTime.Value);
			if (_timer >= VentrixConfig.RenderingNodeDespawnTime.Value)
			{
				SetState(DuctMarkerState.Despawned);
			}
		}

		private float GetAdjustedDeltaTime()
		{
			float deltaTime = Time.deltaTime;
			if (_state != DuctMarkerState.Spawned)
			{
				return deltaTime;
			}
			int level = DiskRegistry.MappingDisk.Level;
			if (level <= 0)
			{
				return deltaTime;
			}
			FirstPersonItem currentItem = FirstPersonItemController.Instance.currentItem;
			if ((SoCustomComparison)(object)currentItem != (SoCustomComparison)null && ((SoCustomComparison)currentItem).presetName.StartsWith("coin"))
			{
				return deltaTime * VentrixConfig.MappingCoinMultiplier.GetLevel(level);
			}
			return deltaTime;
		}
	}
	public class DuctMarkerPool : BasePoolManager<DuctMarker>
	{
		public static DuctMarkerPool Instance;

		private static Material _normalDuctMaterial;

		private static Material _peekDuctMaterial;

		private static Material _normalVentMaterial;

		protected override void SetupManager()
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Expected O, but got Unknown
			//IL_004f: 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_007f: Expected O, but got Unknown
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Expected O, but got Unknown
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			base.SetupManager();
			Shader val = Shader.Find("HDRP/Unlit");
			int num = Shader.PropertyToID("_UnlitColor");
			int num2 = Shader.PropertyToID("_ZTestDepthEqualForOpaque");
			int num3 = Shader.PropertyToID("_ZWrite");
			_normalDuctMaterial = new Material(val);
			_normalDuctMaterial.SetColor(num, Utilities.HexToColor(VentrixConfig.RenderingNodeColorNormal.Value));
			_normalDuctMaterial.SetInt(num2, 8);
			_normalDuctMaterial.SetInt(num3, 0);
			_peekDuctMaterial = new Material(val);
			_peekDuctMaterial.SetColor(num, Utilities.HexToColor(VentrixConfig.RenderingNodeColorPeek.Value));
			_peekDuctMaterial.SetInt(num2, 8);
			_peekDuctMaterial.SetInt(num3, 0);
			_normalVentMaterial = new Material(val);
			_normalVentMaterial.SetColor(num, Utilities.HexToColor(VentrixConfig.RenderingNodeColorVent.Value));
			_normalVentMaterial.SetInt(num2, 8);
			_normalVentMaterial.SetInt(num3, 0);
		}

		protected override DuctMarker CreateBaseObject()
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = GameObject.CreatePrimitive((PrimitiveType)3);
			Renderer component = val.GetComponent<Renderer>();
			component.sharedMaterial = _normalDuctMaterial;
			DuctMarker ductMarker = val.AddComponent<DuctMarker>();
			ductMarker.Renderer = component;
			ductMarker.Transform = ((Component)ductMarker).transform;
			Collider component2 = val.GetComponent<Collider>();
			Object.Destroy((Object)(object)component2);
			Transform transform = val.transform;
			transform.SetPositionAndRotation(Vector3.zero, Quaternion.identity);
			transform.localScale = new Vector3(0.1f, 0.1f, 0.1f);
			Object.DontDestroyOnLoad((Object)(object)val);
			val.SetActive(false);
			return ductMarker;
		}

		protected override void ConfigureCopyObject(ref DuctMarker copyObject)
		{
			copyObject.Renderer = ((Component)copyObject).gameObject.GetComponent<Renderer>();
			copyObject.Transform = ((Component)copyObject).transform;
		}

		public void CreateMarker(DuctMarkerType type, Vector3 position, Vector3 scale, float time)
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: 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)
			DuctMarker ductMarker = CheckoutPoolObject();
			switch (type)
			{
			case DuctMarkerType.NormalDuct:
				ductMarker.Renderer.sharedMaterial = _normalDuctMaterial;
				break;
			case DuctMarkerType.PeekDuct:
				ductMarker.Renderer.sharedMaterial = _peekDuctMaterial;
				break;
			case DuctMarkerType.NormalVent:
				ductMarker.Renderer.sharedMaterial = _normalVentMaterial;
				break;
			}
			Transform transform = ((Component)ductMarker).transform;
			transform.SetPositionAndRotation(position, Quaternion.identity);
			transform.localScale = scale;
			ductMarker.OnSpawn(scale, time);
		}

		public void ReleaseMarker(DuctMarker marker)
		{
			CheckinPoolObject(marker);
		}
	}
	public enum DuctMarkerState
	{
		None,
		Spawning,
		Spawned,
		Despawning,
		Despawned
	}
	public enum DuctMarkerType
	{
		NormalDuct,
		PeekDuct,
		NormalVent
	}
	public class EcholocationPulse : BasePoolObject
	{
		private static readonly SoundMaterialOverride _coinMaterial = new SoundMaterialOverride(0f, 0f, 0f, 0.5f, 0f, 0f, 0.5f, 0f);

		private Coroutine _pulseCoroutine;

		private readonly DuctExplorer _explorer = new DuctExplorer();

		public override void OnCheckout()
		{
			base.OnCheckout();
			StopPulse();
			_explorer.Reset();
		}

		public override void OnCheckin()
		{
			base.OnCheckin();
			StopPulse();
			_explorer.Reset();
		}

		public void StopPulse()
		{
			if (_pulseCoroutine != null)
			{
				RuntimeHelper.StopCoroutine(_pulseCoroutine);
				_pulseCoroutine = null;
			}
		}

		public void StartPulse(AirDuctSection startDuct)
		{
			StopPulse();
			_pulseCoroutine = RuntimeHelper.StartCoroutine(PulseRoutine(startDuct));
		}

		[HideFromIl2Cpp]
		private IEnumerator PulseRoutine(AirDuctSection startDuct)
		{
			int level = DiskRegistry.MappingDisk.Level;
			if (level <= 0)
			{
				yield break;
			}
			_explorer.StartExploration(startDuct);
			int pulseRange = VentrixConfig.MappingEcholocationRange.GetLevel(level);
			float pulseDuration = VentrixConfig.MappingEcholocationDuration.GetLevel(level);
			int i = 0;
			while (i < pulseRange)
			{
				List<DuctExplorerTick> results = _explorer.TickExploration(startDuct);
				if (VentrixConfig.MappingEcholocationSoundVolume.Value > float.Epsilon && i % 2 == 0)
				{
					PlayCoinSound((1f - (float)i / (float)pulseRange) * VentrixConfig.MappingEcholocationSoundVolume.Value);
				}
				foreach (DuctExplorerTick result in results)
				{
					SpawnNodes(position: Utilities.AirDuctToPosition(result.Duct), result: result, pulseDuration: pulseDuration);
				}
				yield return EcholocationPulsePool.Instance.PulseDelays[level];
				int num = i + 1;
				i = num;
			}
			EcholocationPulsePool.Instance.CheckinPoolObject(this);
		}

		private void SpawnNodes(DuctExplorerTick result, Vector3 position, float pulseDuration)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: 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_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0205: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_020f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0230: Unknown result type (might be due to invalid IL or missing references)
			//IL_0245: Unknown result type (might be due to invalid IL or missing references)
			//IL_024a: Unknown result type (might be due to invalid IL or missing references)
			//IL_024f: Unknown result type (might be due to invalid IL or missing references)
			DuctMarkerPool.Instance.CreateMarker(result.Type, position, new Vector3(VentrixConfig.RenderingCentralNodeSize.Value, VentrixConfig.RenderingCentralNodeSize.Value, VentrixConfig.RenderingCentralNodeSize.Value), pulseDuration);
			if (VentrixConfig.RenderingUseDirectionalNodes.Value)
			{
				DuctMarkerType type = (VentrixConfig.RenderingSpecialDirectionalNodeColors.Value ? result.Type : DuctMarkerType.NormalDuct);
				Vector3 scale = default(Vector3);
				((Vector3)(ref scale))..ctor(VentrixConfig.RenderingDirectionalNodeLength.Value, VentrixConfig.RenderingDirectionalNodeDiameter.Value, VentrixConfig.RenderingDirectionalNodeDiameter.Value);
				Vector3 scale2 = default(Vector3);
				((Vector3)(ref scale2))..ctor(VentrixConfig.RenderingDirectionalNodeDiameter.Value, VentrixConfig.RenderingDirectionalNodeLength.Value, VentrixConfig.RenderingDirectionalNodeDiameter.Value);
				Vector3 scale3 = default(Vector3);
				((Vector3)(ref scale3))..ctor(VentrixConfig.RenderingDirectionalNodeDiameter.Value, VentrixConfig.RenderingDirectionalNodeDiameter.Value, VentrixConfig.RenderingDirectionalNodeLength.Value);
				if (result.Connections.NegativeX)
				{
					DuctMarkerPool.Instance.CreateMarker(type, position + new Vector3(0f - VentrixConfig.RenderingDirectionalNodeOffset.Value, 0f, 0f), scale, pulseDuration);
				}
				if (result.Connections.PositiveX)
				{
					DuctMarkerPool.Instance.CreateMarker(type, position + new Vector3(VentrixConfig.RenderingDirectionalNodeOffset.Value, 0f, 0f), scale, pulseDuration);
				}
				if (result.Connections.NegativeY)
				{
					DuctMarkerPool.Instance.CreateMarker(type, position + new Vector3(0f, 0f, 0f - VentrixConfig.RenderingDirectionalNodeOffset.Value), scale3, pulseDuration);
				}
				if (result.Connections.PositiveY)
				{
					DuctMarkerPool.Instance.CreateMarker(type, position + new Vector3(0f, 0f, VentrixConfig.RenderingDirectionalNodeOffset.Value), scale3, pulseDuration);
				}
				if (result.Connections.NegativeZ)
				{
					DuctMarkerPool.Instance.CreateMarker(type, position + new Vector3(0f, 0f - VentrixConfig.RenderingDirectionalNodeOffset.Value, 0f), scale2, pulseDuration);
				}
				if (result.Connections.PositiveZ)
				{
					DuctMarkerPool.Instance.CreateMarker(type, position + new Vector3(0f, VentrixConfig.RenderingDirectionalNodeOffset.Value, 0f), scale2, pulseDuration);
				}
			}
		}

		private void PlayCoinSound(float volume)
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			if (!((SoCustomComparison)(object)MappingHooks.CoinImpactPhysicsProfile == (SoCustomComparison)null))
			{
				Camera main = Camera.main;
				Transform val = ((main != null) ? ((Component)main).transform : null);
				if (!((Object)(object)val == (Object)null))
				{
					AudioController.Instance.PlayWorldOneShot(MappingHooks.CoinImpactPhysicsProfile.physicsCollisionAudio, (Actor)(object)Player.Instance, ((Actor)Player.Instance).currentNode, val.position, (Interactable)null, (List<FMODParam>)null, volume, (List<NewNode>)null, true, _coinMaterial, false);
				}
			}
		}
	}
	public class EcholocationPulsePool : BasePoolManager<EcholocationPulse>
	{
		public static EcholocationPulsePool Instance;

		public WaitForSeconds[] PulseDelays;

		protected override void SetupManager()
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			base.SetupManager();
			if (PulseDelays == null)
			{
				PulseDelays = (WaitForSeconds[])(object)new WaitForSeconds[4];
				int i = 0;
				for (int num = PulseDelays.Length; i < num; i++)
				{
					PulseDelays[i] = new WaitForSeconds(VentrixConfig.MappingEcholocationSpeed.GetLevel(i));
				}
			}
		}

		protected override EcholocationPulse CreateBaseObject()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("EcholocationPulse");
			EcholocationPulse result = val.AddComponent<EcholocationPulse>();
			Transform transform = val.transform;
			transform.SetPositionAndRotation(Vector3.zero, Quaternion.identity);
			transform.localScale = Vector3.one;
			Object.DontDestroyOnLoad((Object)(object)val);
			val.SetActive(false);
			return result;
		}
	}
}
namespace VentrixSyncDisks.Implementation.Mapping.Explorer
{
	public class DuctExplorer
	{
		private readonly Queue<AirDuctSection> _queue = new Queue<AirDuctSection>();

		private readonly HashSet<Vector3Int> _visited = new HashSet<Vector3Int>();

		private readonly List<DuctExplorerTick> _results = new List<DuctExplorerTick>();

		private List<AirDuctSection> _neighbors = new List<AirDuctSection>();

		private List<Vector3Int> _neighborOffsets = new List<Vector3Int>();

		private List<AirVent> _vents = new List<AirVent>();

		public void Reset()
		{
			_queue.Clear();
			_visited.Clear();
			_results.Clear();
			_neighbors.Clear();
			_vents.Clear();
		}

		public void StartExploration(AirDuctSection startSection)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			_queue.Enqueue(startSection);
			_visited.Add(startSection.duct);
		}

		public List<DuctExplorerTick> TickExploration(AirDuctSection duct)
		{
			//IL_008f: 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_0098: 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_00d1: Unknown result type (might be due to invalid IL or missing references)
			_results.Clear();
			if (_queue.Count <= 0)
			{
				return _results;
			}
			int count = _queue.Count;
			for (int i = 0; i < count; i++)
			{
				AirDuctSection val = _queue.Dequeue();
				Utilities.GetVentInformation(val, ref _neighbors, ref _neighborOffsets, ref _vents);
				DuctExplorerConnections connections = default(DuctExplorerConnections);
				for (int j = 0; j < _neighbors.Count; j++)
				{
					AirDuctSection val2 = _neighbors[j];
					Vector3Int offset = _neighborOffsets[j];
					connections.AddConnection(offset);
					if (!_visited.Contains(val2.duct))
					{
						_queue.Enqueue(val2);
						_visited.Add(val2.duct);
					}
				}
				_results.Add(new DuctExplorerTick(val, _vents.Count > 0, connections));
			}
			return _results;
		}
	}
	public struct DuctExplorerConnections
	{
		public bool PositiveX;

		public bool PositiveY;

		public bool PositiveZ;

		public bool NegativeX;

		public bool NegativeY;

		public bool NegativeZ;

		public void AddConnection(Vector3Int offset)
		{
			if (((Vector3Int)(ref offset)).x > 0)
			{
				PositiveX = true;
			}
			else if (((Vector3Int)(ref offset)).x < 0)
			{
				NegativeX = true;
			}
			if (((Vector3Int)(ref offset)).y > 0)
			{
				PositiveY = true;
			}
			else if (((Vector3Int)(ref offset)).y < 0)
			{
				NegativeY = true;
			}
			if (((Vector3Int)(ref offset)).z > 0)
			{
				PositiveZ = true;
			}
			else if (((Vector3Int)(ref offset)).z < 0)
			{
				NegativeZ = true;
			}
		}
	}
	public struct DuctExplorerTick
	{
		public readonly AirDuctSection Duct;

		public readonly DuctMarkerType Type;

		public readonly DuctExplorerConnections Connections;

		public DuctExplorerTick(AirDuctSection duct, bool hasVent, DuctExplorerConnections connections)
		{
			Duct = duct;
			if (hasVent)
			{
				Type = DuctMarkerType.NormalVent;
			}
			else if (Duct.peekSection)
			{
				Type = DuctMarkerType.PeekDuct;
			}
			else
			{
				Type = DuctMarkerType.NormalDuct;
			}
			Connections = connections;
		}
	}
}
namespace VentrixSyncDisks.Implementation.Freakouts
{
	[Serializable]
	public class Freakout
	{
		public int HumanID;

		public int TicksLeft;

		public float NerveTaken;

		[JsonIgnore]
		public Human HumanCache;

		public bool TryGetHuman(out Human human)
		{
			if ((Object)(object)HumanCache != (Object)null)
			{
				human = HumanCache;
				return true;
			}
			return CityData.Instance.citizenDictionary.TryGetValue(HumanID, ref human);
		}
	}
	[Serializable]
	public class FreakoutList
	{
		public List<Freakout> Active = new List<Freakout>();

		public HashSet<int> Hourly = new HashSet<int>();
	}
	public static class FreakoutManager
	{
		private static FreakoutList _freakouts = new FreakoutList();

		public static void Initialize()
		{
			Timer.OnTick = (Action)Delegate.Remove(Timer.OnTick, new Action(OnTick));
			Timer.OnTick = (Action)Delegate.Combine(Timer.OnTick, new Action(OnTick));
			Lib.Time.OnHourChanged -= OnHourChanged;
			Lib.Time.OnHourChanged += OnHourChanged;
			Lib.SaveGame.OnAfterLoad -= OnAfterLoad;
			Lib.SaveGame.OnAfterLoad += OnAfterLoad;
			Lib.SaveGame.OnAfterSave -= OnAfterSave;
			Lib.SaveGame.OnAfterSave += OnAfterSave;
		}

		public static void Uninitialize()
		{
			Timer.OnTick = (Action)Delegate.Remove(Timer.OnTick, new Action(OnTick));
			Lib.Time.OnHourChanged -= OnHourChanged;
			Lib.SaveGame.OnAfterLoad -= OnAfterLoad;
			Lib.SaveGame.OnAfterSave -= OnAfterSave;
		}

		private static void OnTick()
		{
			if (Lib.Time.IsGamePaused)
			{
				return;
			}
			for (int num = _freakouts.Active.Count - 1; num >= 0; num--)
			{
				Freakout freakout = _freakouts.Active[num];
				freakout.TicksLeft--;
				if (freakout.TicksLeft <= 0 && freakout.TryGetHuman(out var human))
				{
					ForceSetNerve(human, freakout.NerveTaken);
					_freakouts.Active.RemoveAt(num);
				}
			}
		}

		private static void OnHourChanged(object sender, TimeChangedArgs args)
		{
			_freakouts.Hourly.Clear();
		}

		public static void StartFreakout(Human human, int seconds)
		{
			if (!((Object)(object)human == (Object)null) && !((Object)(object)((Actor)human).ai == (Object)null) && !_freakouts.Hourly.Contains(human.humanID))
			{
				_freakouts.Active.Add(new Freakout
				{
					HumanID = human.humanID,
					HumanCache = human,
					NerveTaken = ((Actor)human).currentNerve,
					TicksLeft = seconds
				});
				_freakouts.Hourly.Add(human.humanID);
				ForceSetNerve(human, 0f);
			}
		}

		private static void ForceSetNerve(Human human, float nerve)
		{
			((Actor)human).ai.SetPersuit(false);
			((Actor)human).ai.ResetInvestigate();
			((Actor)human).ai.CancelCombat();
			((Actor)human).SetNerve(Mathf.Clamp(nerve, 0f, ((Actor)human).maxNerve));
			((Actor)human).ai.AITick(true, true);
		}

		private static void ResetDefaults()
		{
			_freakouts = new FreakoutList();
		}

		private static void OnAfterSave(object sender, SaveGameArgs args)
		{
			try
			{
				string savePath = GetSavePath(args);
				JsonSerializerOptions options = new JsonSerializerOptions
				{
					IncludeFields = true
				};
				string contents = JsonSerializer.Serialize(_freakouts, options);
				File.WriteAllText(savePath, contents);
			}
			catch
			{
				ResetDefaults();
			}
		}

		private static void OnAfterLoad(object sender, SaveGameArgs args)
		{
			try
			{
				string savePath = GetSavePath(args);
				string json = File.ReadAllText(savePath);
				JsonSerializerOptions options = new JsonSerializerOptions
				{
					IncludeFields = true
				};
				_freakouts = JsonSerializer.Deserialize<FreakoutList>(json, options);
			}
			catch
			{
				ResetDefaults();
			}
		}

		private static string GetSavePath(SaveGameArgs args)
		{
			string uniqueString = Lib.SaveGame.GetUniqueString(args.FilePath);
			string text = "ModJsonData_" + uniqueString + "_VentrixFreakouts.jsonc";
			return Lib.SaveGame.GetSavestoreDirectoryPath(Assembly.GetExecutingAssembly(), text);
		}
	}
}
namespace VentrixSyncDisks.Implementation.Disks
{
	public class DiskCache
	{
		private readonly int _effectId;

		private readonly HashSet<int> _upgradeOptionIds;

		private int _level = -1;

		private int _maxLevel = -1;

		public int Level => _level;

		public DiskCache(int effect, OptionIds options)
		{
			//IL_002f: 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_0043: 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_0072: 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)
			_effectId = effect;
			_upgradeOptionIds = new HashSet<int>();
			_maxLevel = 1;
			if (options.Option1Id != 0)
			{
				_upgradeOptionIds.Add(options.Option1Id);
				_maxLevel++;
			}
			if (options.Option2Id != 0)
			{
				_upgradeOptionIds.Add(options.Option2Id);
				_maxLevel++;
			}
			if (options.Option3Id != 0)
			{
				_upgradeOptionIds.Add(options.Option3Id);
				_maxLevel++;
			}
			Reset();
		}

		public void Reset()
		{
			_level = 0;
		}

		public bool Install(int id)
		{
			if (id != _effectId)
			{
				return false;
			}
			_level = 1;
			return true;
		}

		public bool Uninstall(int id)
		{
			if (id != _effectId)
			{
				return false;
			}
			_level = 0;
			return true;
		}

		public bool Upgrade(int id)
		{
			if (!_upgradeOptionIds.Contains(id))
			{
				return false;
			}
			_level++;
			return true;
		}
	}
	public class DiskDefinition
	{
		public string Name = string.Empty;

		public int Price = 1000;

		public readonly List<DiskEffectDefinition> Effects = new List<DiskEffectDefinition>();

		public void Register()
		{
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			SyncDiskBuilder val = Lib.SyncDisks.Builder(Name, "VentrixSyncDisks", true);
			val.SetManufacturer((Manufacturer)2);
			val.SetPrice(Price);
			val.SetRarity((Rarity)1);
			if (VentrixConfig.AvailableAtLegitSyncDiskClinics.Value)
			{
				val.AddSaleLocation((SyncDiskSaleLocation[])(object)new SyncDiskSaleLocation[1] { (SyncDiskSaleLocation)25 });
			}
			if (VentrixConfig.AvailableAtShadySyncDiskClinics.Value)
			{
				val.AddSaleLocation((SyncDiskSaleLocation[])(object)new SyncDiskSaleLocation[1] { (SyncDiskSaleLocation)4 });
			}
			if (VentrixConfig.AvailableAtBlackMarkets.Value)
			{
				val.AddSaleLocation((SyncDiskSaleLocation[])(object)new SyncDiskSaleLocation[1] { (SyncDiskSaleLocation)23 });
			}
			foreach (DiskEffectDefinition effect in Effects)
			{
				val.AddEffect(effect.Name, effect.Description, ref effect.EffectId, effect.Icon);
				Options val2 = default(Options);
				switch (effect.Upgrades.Count)
				{
				case 1:
					((Options)(ref val2))..ctor(effect.Upgrades[0]);
					break;
				case 2:
					((Options)(ref val2))..ctor(effect.Upgrades[0], effect.Upgrades[1]);
					break;
				case 3:
					((Options)(ref val2))..ctor(effect.Upgrades[0], effect.Upgrades[1], effect.Upgrades[2]);
					break;
				}
				val.AddUpgradeOption(val2, ref effect.OptionIds);
			}
			val.SetCanBeSideJobReward(true);
			val.SetWorldSpawnOption(true);
			val.CreateAndRegister();
		}
	}
	public class DiskEffectDefinition
	{
		public string Name = string.Empty;

		public string Icon = string.Empty;

		public string Description = string.Empty;

		public readonly List<string> Upgrades = new List<string>();

		public int EffectId = -1;

		public OptionIds OptionIds;
	}
	public static class DiskRegistry
	{
		public static DiskCache ScootingDisk;

		public static DiskCache ParkourDisk;

		public static DiskCache MappingDisk;

		public static DiskCache SnoopingDisk;

		public static DiskCache SpecterDisk;

		public static DiskCache TerrorDisk;

		private static readonly List<DiskCache> _allDisks = new List<DiskCache>();

		private static readonly List<string> _cacheDescriptions = new List<string>();

		private static readonly StringBuilder _builder = new StringBuilder();

		public static void Initialize()
		{
			Register();
			SetEvents(registered: true);
		}

		public static void Uninitialize()
		{
			SetEvents(registered: false);
		}

		private static void Register()
		{
			_allDisks.Clear();
			if (VentrixConfig.MobilityEnabled.Value)
			{
				RegisterMobility();
				_allDisks.Add(ScootingDisk);
				_allDisks.Add(ParkourDisk);
			}
			if (VentrixConfig.ReconEnabled.Value)
			{
				RegisterRecon();
				_allDisks.Add(MappingDisk);
				_allDisks.Add(SnoopingDisk);
			}
			if (VentrixConfig.MischiefEnabled.Value)
			{
				RegisterMischief();
				_allDisks.Add(SpecterDisk);
				_allDisks.Add(TerrorDisk);
			}
		}

		private static string GetDiskLevelDescription(int level, params ConfigCacheDiskEffect[] caches)
		{
			_cacheDescriptions.Clear();
			foreach (ConfigCacheDiskEffect configCacheDiskEffect in caches)
			{
				if (configCacheDiskEffect.GetDescriptionRelevant(level))
				{
					_cacheDescriptions.Add(configCacheDiskEffect.GetDescription(level));
				}
			}
			int count = _cacheDescriptions.Count;
			if (count <= 0)
			{
				return "Error Getting Description";
			}
			_builder.Clear();
			for (int j = 0; j < count; j++)
			{
				bool flag = j == 0;
				bool flag2 = j == count - 1;
				string text = _cacheDescriptions[j];
				_builder.Append(flag ? text[0] : char.ToLowerInvariant(text[0]));
				_builder.Append(text, 1, text.Length - 2);
				_builder.Append(flag2 ? "." : "; ");
			}
			return _builder.ToString();
		}

		private static void SetEvents(bool registered)
		{
			Lib.SaveGame.OnAfterLoad -= OnAfterLoad;
			Lib.SyncDisks.OnAfterSyncDiskInstalled -= OnAfterSyncDiskInstalled;
			Lib.SyncDisks.OnAfterSyncDiskUpgraded -= OnAfterSyncDiskUpgraded;
			Lib.SyncDisks.OnAfterSyncDiskUninstalled -= OnAfterSyncDiskUninstalled;
			if (registered)
			{
				Lib.SaveGame.OnAfterLoad += OnAfterLoad;
				Lib.SyncDisks.OnAfterSyncDiskInstalled += OnAfterSyncDiskInstalled;
				Lib.SyncDisks.OnAfterSyncDiskUpgraded += OnAfterSyncDiskUpgraded;
				Lib.SyncDisks.OnAfterSyncDiskUninstalled += OnAfterSyncDiskUninstalled;
			}
		}

		private static void OnAfterLoad(object sender, SaveGameArgs e)
		{
			foreach (DiskCache allDisk in _allDisks)
			{
				allDisk.Reset();
			}
			OnLevelsModified();
		}

		private static void OnAfterSyncDiskInstalled(object sender, SyncDiskArgs args)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			if (!args.Effect.HasValue)
			{
				return;
			}
			int id = args.Effect.Value.Id;
			bool flag = false;
			foreach (DiskCache allDisk in _allDisks)
			{
				if (allDisk.Install(id))
				{
					flag = true;
				}
			}
			if (flag)
			{
				OnLevelsModified();
			}
		}

		private static void OnAfterSyncDiskUpgraded(object sender, SyncDiskArgs args)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			if (!args.UpgradeOption.HasValue)
			{
				return;
			}
			int id = args.UpgradeOption.Value.Id;
			bool flag = false;
			foreach (DiskCache allDisk in _allDisks)
			{
				if (allDisk.Upgrade(id))
				{
					flag = true;
				}
			}
			if (flag)
			{
				OnLevelsModified();
			}
		}

		private static void OnAfterSyncDiskUninstalled(object sender, SyncDiskArgs args)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			if (!args.Effect.HasValue)
			{
				return;
			}
			int id = args.Effect.Value.Id;
			bool flag = false;
			foreach (DiskCache allDisk in _allDisks)
			{
				if (allDisk.Uninstall(id))
				{
					flag = true;
				}
			}
			if (flag)
			{
				OnLevelsModified();
			}
		}

		private static void OnLevelsModified()
		{
			ParkourHooks.InteractableControllerSetupHook.RefreshVentInteractionRanges();
		}

		private static void RegisterMobility()
		{
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			DiskDefinition diskDefinition = new DiskDefinition
			{
				Name = "Vent Mobility",
				Price = VentrixConfig.MobilityPrice.Value
			};
			DiskEffectDefinition diskEffectDefinition = new DiskEffectDefinition();
			diskEffectDefinition.Name = "Chute Scooting";
			diskEffectDefinition.Icon = "IconRun";
			diskEffectDefinition.Description = GetDiskLevelDescription(1, VentrixConfig.ScootingSpeedMultiplier);
			DiskEffectDefinition diskEffectDefinition2 = diskEffectDefinition;
			diskEffectDefinition2.Upgrades.Add(GetDiskLevelDescription(2, VentrixConfig.ScootingSpeedMultiplier));
			diskEffectDefinition2.Upgrades.Add(GetDiskLevelDescription(3, VentrixConfig.ScootingSpeedMultiplier));
			diskEffectDefinition = new DiskEffectDefinition();
			diskEffectDefinition.Name = "Duct Parkour";
			diskEffectDefinition.Icon = "IconWetFloor";
			diskEffectDefinition.Description = GetDiskLevelDescription(1, VentrixConfig.ParkourTransitionSpeed, VentrixConfig.ParkourInteractRange, VentrixConfig.ParkourAutoClose);
			DiskEffectDefinition diskEffectDefinition3 = diskEffectDefinition;
			diskEffectDefinition3.Upgrades.Add(GetDiskLevelDescription(2, VentrixConfig.ParkourTransitionSpeed, VentrixConfig.ParkourInteractRange, VentrixConfig.ParkourAutoClose));
			diskEffectDefinition3.Upgrades.Add(GetDiskLevelDescription(3, VentrixConfig.ParkourTransitionSpeed, VentrixConfig.ParkourInteractRange, VentrixConfig.ParkourAutoClose));
			diskDefinition.Effects.Add(diskEffectDefinition2);
			diskDefinition.Effects.Add(diskEffectDefinition3);
			diskDefinition.Register();
			ScootingDisk = new DiskCache(diskEffectDefinition2.EffectId, diskEffectDefinition2.OptionIds);
			ParkourDisk = new DiskCache(diskEffectDefinition3.EffectId, diskEffectDefinition3.OptionIds);
		}

		private static void RegisterRecon()
		{
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			DiskDefinition diskDefinition = new DiskDefinition
			{
				Name = "Vent Recon",
				Price = VentrixConfig.ReconPrice.Value
			};
			DiskEffectDefinition diskEffectDefinition = new DiskEffectDefinition();
			diskEffectDefinition.Name = "Acoustic Mapping";
			diskEffectDefinition.Icon = "IconCoinDistraction";
			diskEffectDefinition.Description = GetDiskLevelDescription(1, VentrixConfig.MappingEcholocationRange, VentrixConfig.MappingEcholocationSpeed, VentrixConfig.MappingEcholocationDuration, VentrixConfig.MappingCoinMultiplier);
			DiskEffectDefinition diskEffectDefinition2 = diskEffectDefinition;
			diskEffectDefinition2.Upgrades.Add(GetDiskLevelDescription(2, VentrixConfig.MappingEcholocationRange, VentrixConfig.MappingEcholocationSpeed, VentrixConfig.MappingEcholocationDuration, VentrixConfig.MappingCoinMultiplier));
			diskEffectDefinition2.Upgrades.Add(GetDiskLevelDescription(3, VentrixConfig.MappingEcholocationRange, VentrixConfig.MappingEcholocationSpeed, VentrixConfig.MappingEcholocationDuration, VentrixConfig.MappingCoinMultiplier));
			diskEffectDefinition = new DiskEffectDefinition();
			diskEffectDefinition.Name = "Grate Snooping";
			diskEffectDefinition.Icon = "IconOpticalCammo";
			diskEffectDefinition.Description = GetDiskLevelDescription(1, VentrixConfig.SnoopingCanSnoopCivilians, VentrixConfig.SnoopingCanSnoopSecurity, VentrixConfig.SnoopingCanPassTime, VentrixConfig.SnoopingCanSnoopPeeks);
			DiskEffectDefinition diskEffectDefinition3 = diskEffectDefinition;
			diskEffectDefinition3.Upgrades.Add(GetDiskLevelDescription(2, VentrixConfig.SnoopingCanSnoopCivilians, VentrixConfig.SnoopingCanSnoopSecurity, VentrixConfig.SnoopingCanPassTime, VentrixConfig.SnoopingCanSnoopPeeks));
			diskEffectDefinition3.Upgrades.Add(GetDiskLevelDescription(3, VentrixConfig.SnoopingCanSnoopCivilians, VentrixConfig.SnoopingCanSnoopSecurity, VentrixConfig.SnoopingCanPassTime, VentrixConfig.SnoopingCanSnoopPeeks));
			diskDefinition.Effects.Add(diskEffectDefinition2);
			diskDefinition.Effects.Add(diskEffectDefinition3);
			diskDefinition.Register();
			MappingDisk = new DiskCache(diskEffectDefinition2.EffectId, diskEffectDefinition2.OptionIds);
			SnoopingDisk = new DiskCache(diskEffectDefinition3.EffectId, diskEffectDefinition3.OptionIds);
		}

		private static void RegisterMischief()
		{
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			DiskDefinition diskDefinition = new DiskDefinition
			{
				Name = "Vent Mischief",
				Price = VentrixConfig.MischiefPrice.Value
			};
			DiskEffectDefinition diskEffectDefinition = new DiskEffectDefinition();
			diskEffectDefinition.Name = "Shaft Specter";
			diskEffectDefinition.Icon = "IconDeath";
			diskEffectDefinition.Description = GetDiskLevelDescription(1, VentrixConfig.SpecterFootstepChance, VentrixConfig.SpecterColdImmunity);
			DiskEffectDefinition diskEffectDefinition2 = diskEffectDefinition;
			diskEffectDefinition2.Upgrades.Add(GetDiskLevelDescription(2, VentrixConfig.SpecterFootstepChance, VentrixConfig.SpecterColdImmunity));
			diskEffectDefinition2.Upgrades.Add(GetDiskLevelDescription(3, VentrixConfig.SpecterFootstepChance, VentrixConfig.SpecterColdImmunity));
			diskEffectDefinition = new DiskEffectDefinition();
			diskEffectDefinition.Name = "Tunnel Terror";
			diskEffectDefinition.Icon = "IconPassedOut";
			diskEffectDefinition.Description = GetDiskLevelDescription(1, VentrixConfig.TerrorFreakoutDuration, VentrixConfig.TerrorToxicImmunity);
			DiskEffectDefinition diskEffectDefinition3 = diskEffectDefinition;
			diskEffectDefinition3.Upgrades.Add(GetDiskLevelDescription(2, VentrixConfig.TerrorFreakoutDuration, VentrixConfig.TerrorToxicImmunity));
			diskEffectDefinition3.Upgrades.Add(GetDiskLevelDescription(3, VentrixConfig.TerrorFreakoutDuration, VentrixConfig.TerrorToxicImmunity));
			diskDefinition.Effects.Add(diskEffectDefinition2);
			diskDefinition.Effects.Add(diskEffectDefinition3);
			diskDefinition.Register();
			SpecterDisk = new DiskCache(diskEffectDefinition2.EffectId, diskEffectDefinition2.OptionIds);
			TerrorDisk = new DiskCache(diskEffectDefinition3.EffectId, diskEffectDefinition3.OptionIds);
		}
	}
}
namespace VentrixSyncDisks.Implementation.Config
{
	public static class VentrixConfig
	{
		private const string EXPECTED_VERSION = "e3b0c304664e45b0852a433cd8641f98";

		private const string LEVEL_1_TITLE = "(No Upgrades)";

		private const string LEVEL_2_TITLE = "(First Upgrade)";

		private const string LEVEL_3_TITLE = "(Second Upgrade)";

		private const string LEVEL_1_DESCRIPTION = "with no upgrades in";

		private const string LEVEL_2_DESCRIPTION = "with the first upgrade of";

		private const string LEVEL_3_DESCRIPTION = "with the second upgrade of";

		private const string NAME_SHORT_GENERAL = "General";

		private const int ID_GENERAL = 1;

		public static ConfigEntry<bool> Enabled;

		private static ConfigEntry<string> _version;

		public static ConfigCacheSimple<bool> MobilityEnabled;

		public static ConfigCacheSimple<bool> ReconEnabled;

		public static ConfigCacheSimple<bool> MischiefEnabled;

		public static ConfigCacheSimple<int> MobilityPrice;

		public static ConfigCacheSimple<int> ReconPrice;

		public static ConfigCacheSimple<int> MischiefPrice;

		public static ConfigCacheSimple<bool> AvailableAtLegitSyncDiskClinics;

		public static ConfigCacheSimple<bool> AvailableAtShadySyncDiskClinics;

		public static ConfigCacheSimple<bool> AvailableAtBlackMarkets;

		public static ConfigCacheSimple<bool> VentVerticalMovementEnabled;

		private static ConfigEntry<bool> _mobilityEnabled;

		private static ConfigEntry<bool> _reconEnabled;

		private static ConfigEntry<bool> _mischiefEnabled;

		private static ConfigEntry<int> _mobilityPrice;

		private static ConfigEntry<int> _reconPrice;

		private static ConfigEntry<int> _mischiefPrice;

		private static ConfigEntry<bool> _availableAtLegitSyncDiskClinics;

		private static ConfigEntry<bool> _availableAtShadySyncDiskClinics;

		private static ConfigEntry<bool> _availableAtBlackMarkets;

		private static ConfigEntry<bool> _ventVerticalMovementEnabled;

		public const string NAME_LONG_MAPPING = "Acoustic Mapping";

		private const string NAME_SHORT_MAPPING = "Mapping";

		private const int ID_MAPPING = 4;

		public static ConfigCacheSimple<float> MappingEcholocationSoundVolume;

		public static ConfigCacheDiskEffect<int> MappingEcholocationRange;

		public static ConfigCacheDiskEffect<float> MappingEcholocationSpeed;

		public static ConfigCacheDiskEffect<float> MappingEcholocationDuration;

		public static ConfigCacheDiskEffect<float> MappingCoinMultiplier;

		private static ConfigEntry<int> _mappingEcholocationRangeBase;

		private static ConfigEntry<int> _mappingEcholocationRangeFirst;

		private static ConfigEntry<int> _mappingEcholocationRangeSecond;

		private static ConfigEntry<float> _mappingEcholocationSpeedBase;

		private static ConfigEntry<float> _mappingEcholocationSpeedFirst;

		private static ConfigEntry<float> _mappingEcholocationSpeedSecond;

		private static ConfigEntry<float> _mappingEcholocationDurationBase;

		private static ConfigEntry<float> _mappingEcholocationDurationFirst;

		private static ConfigEntry<float> _mappingEcholocationDurationSecond;

		private static ConfigEntry<float> _mappingCoinMultiplierBase;

		private static ConfigEntry<float> _mappingCoinMultiplierFirst;

		private static ConfigEntry<float> _mappingCoinMultiplierSecond;

		private static ConfigEntry<float> _mappingEcholocationSoundVolume;

		public const string NAME_LONG_PARKOUR = "Duct Parkour";

		private const string NAME_SHORT_PARKOUR = "Parkour";

		private const int ID_PARKOUR = 3;

		public static ConfigCacheDiskEffect<float> ParkourInteractRange;

		public static ConfigCacheDiskEffect<float> ParkourTransitionSpeed;

		public static ConfigCacheDiskEffect<bool> ParkourAutoClose;

		private static ConfigEntry<float> _parkourInteractRangeBase;

		private static ConfigEntry<float> _parkourInteractRangeFirst;

		private static ConfigEntry<float> _parkourInteractRangeSecond;

		private static ConfigEntry<float> _parkourTransitionSpeedBase;

		private static ConfigEntry<float> _parkourTransitionSpeedFirst;

		private static ConfigEntry<float> _parkourTransitionSpeedSecond;

		private static ConfigEntry<bool> _parkourAutoCloseBase;

		private static ConfigEntry<bool> _parkourAutoCloseFirst;

		private static ConfigEntry<bool> _parkourAutoCloseSecond;

		private const string NAME_SHORT_RENDERING = "Rendering";

		private const int ID_RENDERING = 8;

		public static ConfigCacheSimple<float> RenderingCentralNodeSize;

		public static ConfigCacheSimple<bool> RenderingUseDirectionalNodes;

		public static ConfigCacheSimple<bool> RenderingSpecialDirectionalNodeColors;

		public static ConfigCacheSimple<float> RenderingDirectionalNodeLength;

		public static ConfigCacheSimple<float> RenderingDirectionalNodeDiameter;

		public static ConfigCacheSimple<float> RenderingDirectionalNodeOffset;

		public static ConfigCacheSimple<string> RenderingNodeColorNormal;

		public static ConfigCacheSimple<string> RenderingNodeColorVent;

		public static ConfigCacheSimple<string> RenderingNodeColorPeek;

		public static ConfigCacheSimple<float> RenderingNodeSpawnTime;

		public static ConfigCacheSimple<float> RenderingNodeDespawnTime;

		private static ConfigEntry<float> _renderingCentralNodeSize;

		private static ConfigEntry<bool> _renderingUseDirectionalNodes;

		private static ConfigEntry<bool> _renderingSpecialDirectionalNodeColors;

		private static ConfigEntry<float> _renderingDirectionalNodeLength;

		private static ConfigEntry<float> _renderingDirectionalNodeDiameter;

		private static ConfigEntry<float> _renderingDirectionalNodeOffset;

		private static ConfigEntry<string> _renderingNodeColorNormal;

		private static ConfigEntry<string> _renderingNodeColorVent;

		private static ConfigEntry<string> _renderingNodeColorPeek;

		private static ConfigEntry<float> _renderingNodeSpawnTime;

		private static ConfigEntry<float> _renderingNodeDespawnTime;

		public const string NAME_LONG_SCOOTING = "Chute Scooting";

		private const string NAME_SHORT_SCOOTING = "Scooting";

		private const int ID_SCOOTING = 2;

		public static ConfigCacheDiskEffect<float> ScootingSpeedMultiplier;

		private static ConfigEntry<float> _scootingSpeedMultiplierBase;

		private static ConfigEntry<float> _scootingSpeedMultiplierFirst;

		private static ConfigEntry<float> _scootingSpeedMultiplierSecond;

		public const string NAME_LONG_SNOOPING = "Grate Snooping";

		private const string NAME_SHORT_SNOOPING = "Snooping";

		private const int ID_SNOOPING = 5;

		public static ConfigCacheSimple<float> SnoopingPassTimeWarpDelay;

		public static ConfigCacheSimple<float> SnoopingPassTimeNotificationDelay;

		public static ConfigCacheDiskEffect<bool> SnoopingCanSnoopCivilians;

		public static ConfigCacheDiskEffect<bool> SnoopingCanSnoopPeeks;

		public static ConfigCacheDiskEffect<bool> SnoopingCanSnoopSecurity;

		public static ConfigCacheDiskEffect<bool> SnoopingCanPassTime;

		private static ConfigEntry<bool> _snoopingCanSnoopCiviliansBase;

		private static ConfigEntry<bool> _snoopingCanSnoopCiviliansFirst;

		private static ConfigEntry<bool> _snoopingCanSnoopCiviliansSecond;

		private static ConfigEntry<bool> _snoopingCanSnoopPeeksBase;

		private static ConfigEntry<bool> _snoopingCanSnoopPeeksFirst;

		private static ConfigEntry<bool> _snoopingCanSnoopPeeksSecond;

		private static ConfigEntry<bool> _snoopingCanSnoopSecurityBase;

		private static ConfigEntry<bool> _snoopingCanSnoopSecurityFirst;

		private static ConfigEntry<bool> _snoopingCanSnoopSecuritySecond;

		private static ConfigEntry<bool> _snoopingCanPassTimeBase;

		private static ConfigEntry<bool> _snoopingCanPassTimeFirst;

		private static ConfigEntry<bool> _snoopingCanPassTimeSecond;

		private static ConfigEntry<float> _snoopingPassTimeWarpDelay;

		private static ConfigEntry<float> _snoopingPassTimeNotificationDelay;

		public const string NAME_LONG_SPECTER = "Shaft Specter";

		private const string NAME_SHORT_SPECTER = "Specter";

		private const int ID_SPECTER = 6;

		public static ConfigCacheDiskEffect<float> SpecterFootstepChance;

		public static ConfigCacheDiskEffect<bool> SpecterColdImmunity;

		private static ConfigEntry<float> _specterFootstepChanceBase;

		private static ConfigEntry<float> _specterFootstepChanceFirst;

		private static ConfigEntry<float> _specterFootstepChanceSecond;

		private static ConfigEntry<bool> _specterColdImmunityBase;

		private static ConfigEntry<bool> _specterColdImmunityFirst;

		private static ConfigEntry<bool> _specterColdImmunitySecond;

		public const string NAME_LONG_TERROR = "Tunnel Terror";

		private const string NAME_SHORT_TERROR = "Terror";

		private const int ID_TERROR = 7;

		public static ConfigCacheSimple<int> TerrorScareableCitizensResidence;

		public static ConfigCacheSimple<int> TerrorScareableCitizensWorkplace;

		public static ConfigCacheDiskEffect<int> TerrorFreakoutDuration;

		public static ConfigCacheDiskEffect<bool> TerrorToxicImmunity;

		private static ConfigEntry<int> _terrorFreakoutDurationBase;

		private static ConfigEntry<int> _terrorFreakoutDurationFirst;

		private static ConfigEntry<int> _terrorFreakoutDurationSecond;

		private static ConfigEntry<bool> _terrorToxicImmunityBase;

		private static ConfigEntry<bool> _terrorToxicImmunityFirst;

		private static ConfigEntry<bool> _terrorToxicImmunitySecond;

		private static ConfigEntry<int> _terrorScareableCitizensResidence;

		private static ConfigEntry<int> _terrorScareableCitizensWorkplace;

		public static void Initialize(ConfigFile config)
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Expected O, but got Unknown
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Expected O, but got Unknown
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Expected O, but got Unknown
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Expected O, but got Unknown
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Expected O, but got Unknown
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Expected O, but got Unknown
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Expected O, but got Unknown
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Expected O, but got Unknown
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Expected O, but got Unknown
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Expected O, but got Unknown
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Expected O, but got Unknown
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Expected O, but got Unknown
			string text = $"{1}. {"General"}";
			Enabled = config.Bind<bool>(text, "Enabled", true, new ConfigDescription("Another method of enabling and disabling Ventrix Sync Disks.", (AcceptableValueBase)null, Array.Empty<object>()));
			_version = config.Bind<string>(text, "Version", string.Empty, new ConfigDescription("Ventrix Sync Disks uses this to reset your configuration between major versions. Don't modify it or it will reset your configuration!", (AcceptableValueBase)null, Array.Empty<object>()));
			_mobilityEnabled = config.Bind<bool>(text, "Vent Mobility Enabled", true, new ConfigDescription("Whether or not the \"Vent Mobility\" sync disk is available in the game.", (AcceptableValueBase)null, Array.Empty<object>()));
			_reconEnabled = config.Bind<bool>(text, "Vent Recon Enabled", true, new ConfigDescription("Whether or not the \"Vent Recon\" sync disk is available in the game.", (AcceptableValueBase)null, Array.Empty<object>()));
			_mischiefEnabled = config.Bind<bool>(text, "Vent Mischief Enabled", true, new ConfigDescription("Whether or not the \"Vent Mischief\" sync disk is available in the game.", (AcceptableValueBase)null, Array.Empty<object>()));
			_mobilityPrice = config.Bind<int>(text, "Vent Mobility Price", 750, new ConfigDescription("The price of the \"Vent Mobility\" sync disk at vendors.", (AcceptableValueBase)null, Array.Empty<object>()));
			_reconPrice = config.Bind<int>(text, "Vent Recon Price", 750, new ConfigDescription("The price of the \"Vent Recon\" sync disk at vendors.", (AcceptableValueBase)null, Array.Empty<object>()));
			_mischiefPrice = config.Bind<int>(text, "Vent Mischief Price", 750, new ConfigDescription("The price of the \"Vent Mischief\" sync disk at vendors.", (AcceptableValueBase)null, Array.Empty<object>()));
			_availableAtLegitSyncDiskClinics = config.Bind<bool>(text, "Available At Legit Sync Disk Clinics", false, new ConfigDescription("The sync disks appear in the world, but with this, they will also be purchasable at legitimate sync clinics.", (AcceptableValueBase)null, Array.Empty<object>()));
			_availableAtShadySyncDiskClinics = config.Bind<bool>(text, "Available At Shady Sync Disk Clinics", true, new ConfigDescription("The sync disks appear in the world, but with this, they will also be purchasable at black market sync clinics.", (AcceptableValueBase)null, Array.Empty<object>()));
			_availableAtBlackMarkets = config.Bind<bool>(text, "Available At Black Market Traders", false, new ConfigDescription("The sync disks appear in the world, but with this, they will also be purchasable at black market traders.", (AcceptableValueBase)null, Array.Empty<object>()));
			_ventVerticalMovementEnabled = config.Bind<bool>(text, "Vent Vertical Movement Enabled", true, new ConfigDescription("Whether you can now use the jump and crouch keys to move up and down in vents.", (AcceptableValueBase)null, Array.Empty<object>()));
			InitializeScooting(config);
			InitializeParkour(config);
			InitializeMapping(config);
			InitializeSnooping(config);
			InitializeSpecter(config);
			InitializeTerror(config);
			InitializeRendering(config);
			ProcessUpgrades();
			CacheGeneral();
			CacheScooting();
			CacheParkour();
			CacheMapping();
			CacheSnooping();
			CacheSpecter();
			CacheTerror();
			CacheRendering();
			Utilities.Log("VentrixConfig has initialized!", (LogLevel)32);
		}

		private static void ProcessUpgrades()
		{
			if (!(_version.Value == "e3b0c304664e45b0852a433cd8641f98"))
			{
				Utilities.Log("Detected either a new installation or a major upgrade of Ventrix Sync Disks, resetting the configuration file!", (LogLevel)16);
				_version.Value = "e3b0c304664e45b0852a433cd8641f98";
				Reset();
			}
		}

		private static void CacheGeneral()
		{
			MobilityEnabled = new ConfigCacheSimple<bool>(_mobilityEnabled);
			ReconEnabled = new ConfigCacheSimple<bool>(_reconEnabled);
			MischiefEnabled = new ConfigCacheSimple<bool>(_mischiefEnabled);
			MobilityPrice = new ConfigCacheSimple<int>(_mobilityPrice);
			ReconPrice = new ConfigCacheSimple<int>(_reconPrice);
			MischiefPrice = new ConfigCacheSimple<int>(_mischiefPrice);
			AvailableAtLegitSyncDiskClinics = new ConfigCacheSimple<bool>(_availableAtLegitSyncDiskClinics);
			AvailableAtShadySyncDiskClinics = new ConfigCacheSimple<bool>(_availableAtShadySyncDiskClinics);
			AvailableAtBlackMarkets = new ConfigCacheSimple<bool>(_availableAtBlackMarkets);
			VentVerticalMovementEnabled = new ConfigCacheSimple<bool>(_ventVerticalMovementEnabled);
		}

		private static void Reset()
		{
			Enabled.Value = (bool)((ConfigEntryBase)Enabled).DefaultValue;
			_mobilityEnabled.Value = (bool)((ConfigEntryBase)_mobilityEnabled).DefaultValue;
			_reconEnabled.Value = (bool)((ConfigEntryBase)_reconEnabled).DefaultValue;
			_mischiefEnabled.Value = (bool)((ConfigEntryBase)_mischiefEnabled).DefaultValue;
			_mobilityPrice.Value = (int)((ConfigEntryBase)_mobilityPrice).DefaultValue;
			_reconPrice.Value = (int)((ConfigEntryBase)_reconPrice).DefaultValue;
			_mischiefPrice.Value = (int)((ConfigEntryBase)_mischiefPrice).DefaultValue;
			_availableAtLegitSyncDiskClinics.Value = (bool)((ConfigEntryBase)_availableAtLegitSyncDiskClinics).DefaultValue;
			_availableAtShadySyncDiskClinics.Value = (bool)((ConfigEntryBase)_availableAtShadySyncDiskClinics).DefaultValue;
			_availableAtBlackMarkets.Value = (bool)((ConfigEntryBase)_availableAtBlackMarkets).DefaultValue;
			_ventVerticalMovementEnabled.Value = (bool)((ConfigEntryBase)_ventVerticalMovementEnabled).DefaultValue;
			ResetScooting();
			ResetParkour();
			ResetMapping();
			ResetSnooping();
			ResetSpecter();
			ResetTerror();
			ResetRendering();
		}

		private static void InitializeMapping(ConfigFile config)
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Expected O, but got Unknown
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Expected O, but got Unknown
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Expected O, but got Unknown
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Expected O, but got Unknown
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Expected O, but got Unknown
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Expected O, but got Unknown
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Expected O, but got Unknown
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Expected O, but got Unknown
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Expected O, but got Unknown
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Expected O, but got Unknown
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Expected O, but got Unknown
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Expected O, but got Unknown
			//IL_020b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Expected O, but got Unknown
			string text = $"{4}. {"Mapping"}";
			_mappingEcholocationRangeBase = config.Bind<int>(text, "Echolocation Range (No Upgrades)", 10, new ConfigDescription("How far your echolocation pulse travels down vents with no upgrades in Mapping.", (AcceptableValueBase)null, Array.Empty<object>()));
			_mappingEcholocationRangeFirst = config.Bind<int>(text, "Echolocation Range (First Upgrade)", 20, new ConfigDescription("How far your echolocation pulse travels down vents with the first upgrade of Mapping.", (AcceptableValueBase)null, Array.Empty<object>()));
			_mappingEcholocationRangeSecond = config.Bind<int>(text, "Echolocation Range (Second Upgrade)", 20, new ConfigDescription("How far your echolocation pulse travels down vents with the second upgrade of Mapping.", (AcceptableValueBase)null, Array.Empty<object>()));
			_mappingEcholocationSpeedBase = config.Bind<float>(text, "Echolocation Speed (No Upgrades)", 0.1f, new ConfigDescription("How quickly your echolocation pulse travels down vents with no upgrades in Mapping.", (AcceptableValueBase)null, Array.Empty<object>()));
			_mappingEcholocationSpeedFirst = config.Bind<float>(text, "Echolocation Speed (First Upgrade)", 0.1f, new ConfigDescription("How quickly your echolocation pulse travels down vents with the first upgrade of Mapping.", (AcceptableValueBase)null, Array.Empty<object>()));
			_mappingEcholocationSpeedSecond = config.Bind<float>(text, "Echolocation Speed (Second Upgrade)", 0.1f, new ConfigDescription("How quickly your echolocation pulse travels down vents with the second upgrade of Mapping.", (AcceptableValueBase)null, Array.Empty<object>()));
			_mappingEcholocationDurationBase = config.Bind<float>(text, "Echolocation Duration (No Upgrades)", 1f, new ConfigDescription("How long it takes for your echolocation pulse to expire with no upgrades in Mapping.", (AcceptableValueBase)null, Array.Empty<object>()));
			_mappingEcholocationDurationFirst = config.Bind<float>(text, "Echolocation Duration (First Upgrade)", 1f, new ConfigDescription("How long it takes for your echolocation pulse to expire with the first upgrade of Mapping.", (AcceptableValueBase)null, Array.Empty<object>()));
			_mappingEcholocationDurationSecond = config.Bind<float>(text, "Echolocation Duration (Second Upgrade)", 1f, new ConfigDescription("How long it takes for your echolocation pulse to expire with the second upgrade of Mapping.", (AcceptableValueBase)null, Array.Empty<object>()));
			_mappingCoinMultiplierBase = config.Bind<float>(text, "Coin Duration Multiplier (No Upgrades)", 1f, new ConfigDescription("A multiplier on echolocation duration while holding a coin with no upgrades in Mapping.", (AcceptableValueBase)null, Array.Empty<object>()));
			_mappingCoinMultiplierFirst = config.Bind<float>(text, "Coin Duration Multiplier (First Upgrade)", 1f, new ConfigDescription("A multiplier on echolocation duration while holding a coin with the first upgrade of Mapping.", (AcceptableValueBase)null, Array.Empty<object>()));
			_mappingCoinMultiplierSecond = config.Bind<float>(text, "Coin Duration Multiplier (Second Upgrade)", 0.1f, new ConfigDescription("A multiplier on echolocation duration while holding a coin with the second upgrade of Mapping.", (AcceptableValueBase)null, Array.Empty<object>()));
			_mappingEcholocationSoundVolume = config.Bind<float>(text, "Echolocation Sound Volume", 0.2f, new ConfigDescription("How loud the coin sounds that play during echolocation pulses are. Set to zero to turn them off.", (AcceptableValueBase)null, Array.Empty<object>()));
		}

		private static void CacheMapping()
		{
			MappingEcholocationSoundVolume = new ConfigCacheSimple<float>(_mappingEcholocationSoundVolume);
			MappingEcholocationRange = new ConfigCacheDiskEffect<int>(-1, GetEcholocationRangeDescription, _mappingEcholocationRangeBase, _mappingEcholocationRangeFirst, _mappingEcholocationRangeSecond);
			MappingEcholocationSpeed = new ConfigCacheDiskEffect<float>(0.1f, (int level, float oldValue, float newValue) => $"Your \"echolocation\" pulses now travel {Utilities.DirectMultiplierDescription(newValue / oldValue, "slower", "faster", out var description3)}% {description3}.", _mappingEcholocationSpeedBase, _mappingEcholocationSpeedFirst, _mappingEcholocationSpeedSecond);
			MappingEcholocationDuration = new ConfigCacheDiskEffect<float>(1f, (int level, float oldValue, float newValue) => $"Your \"echolocation\" pulses now expire {Utilities.DirectMultiplierDescription(newValue / oldValue, "faster", "slower", out var description2)}% {description2}.", _mappingEcholocationDurationBase, _mappingEcholocationDurationFirst, _mappingEcholocationDurationSecond);
			MappingCoinMultiplier = new ConfigCacheDiskEffect<float>(1f, (int level, float oldValue, float newValue) => $"You remember your \"echolocation\" pulse {Utilities.InverseMultiplierDescription(newValue, "longer", "shorter", out var description)}% {description} while holding a coin.", _mappingCoinMultiplierBase, _mappingCoinMultiplierFirst, _mappingCoinMultiplierSecond);
		}

		private static void ResetMapping()
		{
			_mappingEcholocationSoundVolume.Value = (float)((ConfigEntryBase)_mappingEcholocationSoundVolume).DefaultValue;
			_mappingEcholocationRangeBase.Value = (int)((ConfigEntryBase)_mappingEcholocationRangeBase).DefaultValue;
			_mappingEcholocationRangeFirst.Value = (int)((ConfigEntryBase)_mappingEcholocationRangeFirst).DefaultValue;
			_mappingEcholocationRangeSecond.Value = (int)((ConfigEntryBase)_mappingEcholocationRangeSecond).DefaultValue;
			_mappingEcholocationSpeedBase.Value = (float)((ConfigEntryBase)_mappingEcholocationSpeedBase).DefaultValue;
			_mappingEcholocationSpeedFirst.Value = (float)((ConfigEntryBase)_mappingEcholocationSpeedFirst).DefaultValue;
			_mappingEcholocationSpeedSecond.Value = (float)((ConfigEntryBase)_mappingEcholocationSpeedSecond).DefaultValue;
			_mappingEcholocationDurationBase.Value = (float)((ConfigEntryBase)_mappingEcholocationDurationBase).DefaultValue;
			_mappingEcholocationDurationFirst.Value = (float)((ConfigEntryBase)_mappingEcholocationDurationFirst).DefaultValue;
			_mappingEcholocationDurationSecond.Value = (float)((ConfigEntryBase)_mappingEcholocationDurationSecond).DefaultValue;
			_mappingCoinMultiplierBase.Value = (float)((ConfigEntryBase)_mappingCoinMultiplierBase).DefaultValue;
			_mappingCoinMultiplierFirst.Value = (float)((ConfigEntryBase)_mappingCoinMultiplierFirst).DefaultValue;
			_mappingCoinMultiplierSecond.Value = (float)((ConfigEntryBase)_mappingCoinMultiplierSecond).DefaultValue;
		}

		private static string GetEcholocationRangeDescription(int level, int oldValue, int newValue)
		{
			if (level == 1)
			{
				return "Throwing coins in air ducts will create brief \"echolocation\" pulses that show the vent network through walls.";
			}
			float multiplier = (float)newValue / (float)oldValue;
			string description;
			int value = Utilities.DirectMultiplierDescription(multiplier, "smaller", "larger", out description);
			return $"Your \"echolocation\" pulses are now {value}% {description}.";
		}

		private static void InitializeParkour(ConfigFile config)
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Expected O, but got Unknown
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Expected O, but got Unknown
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Expected O, but got Unknown
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Expected O, but got Unknown
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Expected O, but got Unknown
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Expected O, but got Unknown
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Expected O, but got Unknown
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Expected O, but got Unknown
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Expected O, but got Unknown
			string text = $"{3}. {"Parkour"}";
			_parkourInteractRangeBase = config.Bind<float>(text, "Added Interaction Range (No Upgrades)", 0f, new ConfigDescription("How much further you can reach vents with no upgrades in Parkour.", (AcceptableValueBase)null, Array.Empty<object>()));
			_parkourInteractRangeFirst = config.Bind<float>(text, "Added Interaction Range (First Upgrade)", 1f, new ConfigDescription("How much further you can reach vents with the first upgrade of Parkour.", (AcceptableValueBase)null, Array.Empty<object>()));
			_parkourInteractRangeSecond = config.Bind<float>(text, "Added Interaction Range (Second Upgrade)", 1f, new ConfigDescription("How much further you can reach vents with the second upgrade of Parkour.", (AcceptableValueBase)null, Array.Empty<object>()));
			_parkourTransitionSpeedBase = config.Bind<float>(text, "Transition Speed Multiplier (No Upgrades)", 0.8f, new ConfigDescription("A multiplier on the speed you enter and exit vents with no upgrades in Parkour.", (AcceptableValueBase)null, Array.Empty<object>()));
			_parkourTransitionSpeedFirst = config.Bind<float>(text, "Transition Speed Multiplier (First Upgrade)", 0.6f, new ConfigDescription("A multiplier on the speed you enter and exit vents with the first upgrade of Parkour.", (AcceptableValueBase)null, Array.Empty<object>()));
			_parkourTransitionSpeedSecond = config.Bind<float>(text, "Transition Speed Multiplier (Second Upgrade)", 0.6f, new ConfigDescription("A multiplier on the speed you enter and exit vents with the second upgrade of Parkour.", (AcceptableValueBase)null, Array.Empty<object>()));
			_parkourAutoCloseBase = config.Bind<bool>(text, "Auto Close Vents (No Upgrades)", false, new ConfigDescription("Whether vents close behind you automatically when you enter or exit them with no upgrades in Parkour.", (AcceptableValueBase)null, Array.Empty<object>()));
			_parkourAutoCloseFirst = config.Bind<bool>(text, "Auto Close Vents (First Upgrade)", false, new ConfigDescription("Whether vents close behind you automatically when you enter or exit them with the first upgrade of Parkour.", (AcceptableValueBase)null, Array.Empty<object>()));
			_parkourAutoCloseSecond = config.Bind<bool>(text, "Auto Close Vents (Second Upgrade)", true, new ConfigDescription("Whether vents close behind you automatically when you enter or exit them with the second upgrade of Parkour.", (AcceptableValueBase)null, Array.Empty<object>()));
		}

		private static void CacheParkour()
		{
			ParkourInteractRange = new ConfigCacheDiskEffect<float>(0f, (int level, float oldValue, float newValue) => $"You can now reach vents {newValue}m further away.", _parkourInteractRangeBase, _parkourInteractRangeFirst, _parkourInteractRangeSecond);
			ParkourTransitionSpeed = new ConfigCacheDiskEffect<float>(1f, (int level, float oldValue, float newValue) => $"You get in and out of vents {Utilities.DirectMultiplierDescription(newValue, "faster", "slower", out var description)}% {description}.", _parkourTransitionSpeedBase, _parkourTransitionSpeedFirst, _parkourTransitionSpeedSecond);
			ParkourAutoClose = new ConfigCacheDiskEffect<bool>(false, (int level, bool oldValue, bool newValue) => "Vents " + (newValue ? "now" : "no longer") + " automatically close when entering or exiting them.", _parkourAutoCloseBase, _parkourAutoCloseFirst, _parkourAutoCloseSecond);
		}

		private static void ResetParkour()
		{
			_parkourInteractRangeBase.Value = (float)((ConfigEntryBase)_parkourInteractRangeBase).DefaultValue;
			_parkourInteractRangeFirst.Value = (float)((ConfigEntryBase)_parkourInteractRangeFirst).DefaultValue;
			_parkourInteractRangeSecond.Value = (float)((ConfigEntryBase)_parkourInteractRangeSecond).DefaultValue;
			_parkourTransitionSpeedBase.Value = (float)((ConfigEntryBase)_parkourTransitionSpeedBase).DefaultValue;
			_parkourTransitionSpeedFirst.Value = (float)((ConfigEntryBase)_parkourTransitionSpeedFirst).DefaultValue;
			_parkourTransitionSpeedSecond.Value = (float)((ConfigEntryBase)_parkourTransitionSpeedSecond).DefaultValue;
			_parkourAutoCloseBase.Value = (bool)((ConfigEntryBase)_parkourAutoCloseBase).DefaultValue;
			_parkourAutoCloseFirst.Value = (bool)((ConfigEntryBase)_parkourAutoCloseFirst).DefaultValue;
			_parkourAutoCloseSecond.Value = (bool)((ConfigEntryBase)_parkourAutoCloseSecond).DefaultValue;
		}

		private static void InitializeRendering(ConfigFile config)
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Expected O, but got Unknown
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Expected O, but got Unknown
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Expected O, but got Unknown
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Expected O, but got Unknown
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Expected O, but got Unknown
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Expected O, but got Unknown
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Expected O, but got Unknown
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Expected O, but got Unknown
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Expected O, but got Unknown
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Expected O, but got Unknown
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Expected O, but got Unknown
			string text = $"{8}. {"Rendering"}";
			_renderingCentralNodeSize = config.Bind<float>(text, "Central Node Size", 0.1f, new ConfigDescription("When rendering vent networks, how large the visualized nodes are in the center of each duct.", (AcceptableValueBase)null, Array.Empty<object>()));
			_renderingUseDirectionalNodes = config.Bind<bool>(text, "Use Directional Nodes", true, new ConfigDescription("When rendering vent networks, whether to render additional indicators pointing at connected air ducts.", (AcceptableValueBase)null, Array.Empty<object>()));
			_renderingSpecialDirectionalNodeColors = config.Bind<bool>(text, "Special Directional Node Colors", false, new ConfigDescription("When rendering vent networks, whether additional connections on vents are colored as normal ducts or as vents.", (AcceptableValueBase)null, Array.Empty<object>()));
			_renderingDirectionalNodeLength = config.Bind<float>(text, "Directional Node Length", 0.5f, new ConfigDescription("When rendering vent networks, how long the indicators pointing down connected ducts are.", (AcceptableValueBase)null, Array.Empty<object>()));
			_renderingDirectionalNodeDiameter = config.Bind<float>(text, "Directional Node Diameter", 0.015f, new ConfigDescription("When rendering vent networks, how wide the indicators pointing down connected ducts are.", (AcceptableValueBase)null, Array.Empty<object>()));
			_renderingDirectionalNodeOffset = config.Bind<float>(text, "Directional Node Offset", 0.525f, new ConfigDescription("When rendering vent networks, how far apart the indicators pointing down connected ducts are.", (AcceptableValueBase)null, Array.Empty<object>()));
			_renderingNodeColorNormal = config.Bind<string>(text, "Node Color Normal", "00FFFF", new ConfigDescription("When rendering vent networks, what color normal air ducts are visualized as.", (AcceptableValueBase)null, Array.Empty<object>()));
			_renderingNodeColorVent = config.Bind<string>(text, "Node Color Vent", "FFFF00", new ConfigDescription("When rendering vent networks, what color air vents (entrances / exits) are visualized as.", (AcceptableValueBase)null, Array.Empty<object>()));
			_renderingNodeColorPeek = config.Bind<string>(text, "Node Color Peek", "00FFFF", new ConfigDescription("When rendering vent networks, what color \"peek\" ducts are visualized as, that you can see through but not exit.", (AcceptableValueBase)null, Array.Empty<object>()));
			_renderingNodeSpawnTime = config.Bind<float>(text, "Node Spawn Time", 0.2f, new ConfigDescription("When rendering vent networks, when nodes spawn in, how long it takes for them to reach full size.", (AcceptableValueBase)null, Array.Empty<object>()));
			_renderingNodeDespawnTime = config.Bind<float>(text, "Node Despawn Time", 0.2f, new ConfigDescription("When rendering vent networks, when nodes expire, how long it takes for them to shrink and disappear.", (AcceptableValueBase)null, Array.Empty<object>()));
		}

		private static void CacheRendering()
		{
			RenderingCentralNodeSize = new ConfigCacheSimple<float>(_renderingCentralNodeSize);
			RenderingUseDirectionalNodes = new ConfigCacheSimple<bool>(_renderingUseDirectionalNodes);
			RenderingSpecialDirectionalNodeColors = new ConfigCacheSimple<bool>(_renderingSpecialDirectionalNodeColors);
			RenderingDirectionalNodeLength = new ConfigCacheSimple<float>(_renderingDirectionalNodeLength);
			RenderingDirectionalNodeDiameter = new ConfigCacheSimple<float>(_renderingDirectionalNodeDiameter);
			RenderingDirectionalNodeOffset = new ConfigCacheSimple<float>(_renderingDirectionalNodeOffset);
			RenderingNodeColorNormal = new ConfigCacheSimple<string>(_renderingNodeColorNormal);
			RenderingNodeColorVent = new ConfigCacheSimple<string>(_renderingNodeColorVent);
			RenderingNodeColorPeek = new ConfigCacheSimple<string>(_renderingNodeColorPeek);
			RenderingNodeSpawnTime = new ConfigCacheSimple<float>(_renderingNodeSpawnTime);
			RenderingNodeDespawnTime = new ConfigCacheSimple<float>(_renderingNodeDespawnTime);
		}

		private static void ResetRendering()
		{
			_renderingCentralNodeSize.Value = (float)((ConfigEntryBase)_renderingCentralNodeSize).DefaultValue;
			_renderingUseDirectionalNodes.Value = (bool)((ConfigEntryBase)_renderingUseDirectionalNodes).DefaultValue;
			_renderingSpecialDirectionalNodeColors.Value = (bool)((ConfigEntryBase)_renderingSpecialDirectionalNodeColors).DefaultValue;
			_renderingDirectionalNodeLength.Value = (float)((ConfigEntryBase)_renderingDirectionalNodeLength).DefaultValue;
			_renderingDirectionalNodeDiameter.Value = (float)((ConfigEntryBase)_renderingDirectionalNodeDiameter).DefaultValue;
			_renderingDirectionalNodeOffset.Value = (float)((ConfigEntryBase)_renderingDirectionalNodeOffset).DefaultValue;
			_renderingNodeColorNormal.Value = (string)((ConfigEntryBase)_renderingNodeColorNormal).DefaultValue;
			_renderingNodeColorVent.Value = (string)((ConfigEntryBase)_renderingNodeColorVent).DefaultValue;
			_renderingNodeColorPeek.Value = (string)((ConfigEntryBase)_renderingNodeColorPeek).DefaultValue;
			_renderingNodeSpawnTime.Value = (float)((ConfigEntryBase)_renderingNodeSpawnTime).DefaultValue;
			_renderingNodeDespawnTime.Value = (float)((ConfigEntryBase)_renderingNodeDespawnTime).DefaultValue;
		}

		private static void InitializeScooting(ConfigFile config)
		{
			//IL_004c: Unknown result type (might be due to invalid IL or