Decompiled source of DidYouSeeThat v1.0.0

plugins\DidYouSeeThatMod\DidYouSeeThatMod.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using DidYouSeeThatMod.Configuration;
using DidYouSeeThatMod.Internal;
using DidYouSeeThatMod.Patches;
using DidYouSeeThatMod.Services;
using ExitGames.Client.Photon;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using Photon.Realtime;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("DidYouSeeThatMod")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+7d9522b6465209d32ffdcb35e15652914f8148eb")]
[assembly: AssemblyProduct("DidYouSeeThatMod")]
[assembly: AssemblyTitle("DidYouSeeThatMod")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace DidYouSeeThatMod
{
	[BepInPlugin("com.user.repo.didyouseethat", "Did You See That?", "1.0.0")]
	public sealed class DidYouSeeThatPlugin : BaseUnityPlugin
	{
		private Harmony? _harmony;

		private HauntDirectorService? _director;

		public static DidYouSeeThatPlugin? Instance { get; private set; }

		public ModConfig? ModConfig { get; private set; }

		private void Awake()
		{
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Expected O, but got Unknown
			Instance = this;
			ModConfig = new ModConfig(((BaseUnityPlugin)this).Config);
			SoundLibraryService soundLibraryService = new SoundLibraryService(ModConfig, ((BaseUnityPlugin)this).Logger);
			TeamProximityService proximityService = new TeamProximityService(ModConfig);
			ShadowHallucinationService shadowService = new ShadowHallucinationService(ModConfig, ((BaseUnityPlugin)this).Logger);
			_director = new HauntDirectorService(ModConfig, soundLibraryService, proximityService, shadowService, ((BaseUnityPlugin)this).Logger);
			PlayerAndLevelPatches.Initialize(_director, ModConfig);
			_harmony = new Harmony("com.user.repo.didyouseethat");
			_harmony.PatchAll(typeof(PlayerAndLevelPatches));
			((MonoBehaviour)this).StartCoroutine(soundLibraryService.LoadAllSoundsCoroutine(((BaseUnityPlugin)this).Info.Location));
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Did You See That? v1.0.0 cargado correctamente.");
		}

		private void Update()
		{
			_director?.Tick(Time.deltaTime);
		}

		private void OnDestroy()
		{
			_director?.Dispose();
			Harmony? harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}
	}
	public static class PluginInfo
	{
		public const string PluginGuid = "com.user.repo.didyouseethat";

		public const string PluginName = "Did You See That?";

		public const string PluginVersion = "1.0.0";
	}
}
namespace DidYouSeeThatMod.Services
{
	public sealed class HauntDirectorService : IDisposable
	{
		private const byte HauntPhotonEventCode = 177;

		private const byte SubEventWelcomeDecision = 1;

		private const byte SubEventGroupSound = 2;

		private const byte SubEventGroupShadow = 3;

		private readonly ModConfig _config;

		private readonly SoundLibraryService _soundLibrary;

		private readonly TeamProximityService _proximityService;

		private readonly ShadowHallucinationService _shadowService;

		private readonly ManualLogSource _logger;

		private float _audioNormalizedProgress;

		private float _shadowNormalizedProgress;

		private float _audioJitterMultiplier = 1f;

		private float _shadowJitterMultiplier = 1f;

		private float _lastWakeUpTime = -999f;

		private bool _levelWelcomeEvaluated;

		private bool _receivedHostWelcomeDecision;

		private float _levelSpawnTimestamp = -1f;

		public HauntDirectorService(ModConfig config, SoundLibraryService soundLibrary, TeamProximityService proximityService, ShadowHallucinationService shadowService, ManualLogSource logger)
		{
			_config = config ?? throw new ArgumentNullException("config");
			_soundLibrary = soundLibrary ?? throw new ArgumentNullException("soundLibrary");
			_proximityService = proximityService ?? throw new ArgumentNullException("proximityService");
			_shadowService = shadowService ?? throw new ArgumentNullException("shadowService");
			_logger = logger ?? throw new ArgumentNullException("logger");
			ResetJitterMultipliers();
			if (PhotonNetwork.NetworkingClient != null)
			{
				PhotonNetwork.NetworkingClient.EventReceived += OnPhotonEventReceived;
			}
		}

		public void Dispose()
		{
			if (PhotonNetwork.NetworkingClient != null)
			{
				PhotonNetwork.NetworkingClient.EventReceived -= OnPhotonEventReceived;
			}
		}

		public void OnNewLevelStarted()
		{
			_levelWelcomeEvaluated = false;
			_receivedHostWelcomeDecision = false;
			_levelSpawnTimestamp = -1f;
			_audioNormalizedProgress = Random.Range(0.05f, 0.25f);
			_shadowNormalizedProgress = Random.Range(0.1f, 0.35f);
			ResetJitterMultipliers();
		}

		public void NotifyPlayerSpawnedInVehicle()
		{
			if (_config.Enabled.Value && !_levelWelcomeEvaluated && SemiFunc.RunIsLevel() && !SemiFunc.RunIsLobbyMenu() && !SemiFunc.IsMainMenu() && _levelSpawnTimestamp < 0f)
			{
				_levelSpawnTimestamp = Time.time;
			}
		}

		public void OnLocalPlayerCrouched()
		{
			if (!_config.Enabled.Value || SemiFunc.IsMainMenu() || SemiFunc.IsSplashScreen() || SemiFunc.RunIsLobbyMenu())
			{
				return;
			}
			float time = Time.time;
			if (!(time - _lastWakeUpTime < _config.WakeUpCooldownSeconds.Value))
			{
				float num = Mathf.Clamp01(_config.WakeUpCrouchChance.Value);
				if (Random.value <= num)
				{
					_lastWakeUpTime = time;
					_soundLibrary.PlayWakeUpSound();
					_logger.LogDebug((object)"Activado sonido personal 'wake-up.ogg' al agacharse (10% chance).");
				}
			}
		}

		public void Tick(float deltaTime)
		{
			if (!_config.Enabled.Value || !TeamProximityService.TryGetActiveLocalPlayer(out PlayerAvatar localPlayer))
			{
				return;
			}
			TickVehicleWelcomeCheck();
			float isolationFactor = _proximityService.GetIsolationFactor(localPlayer);
			float num = Mathf.Max(8f, _proximityService.GetTargetAudioIntervalSeconds(isolationFactor) * _audioJitterMultiplier);
			_audioNormalizedProgress += deltaTime / num;
			if (_audioNormalizedProgress >= 1f)
			{
				_audioNormalizedProgress = 0f;
				_audioJitterMultiplier = Random.Range(0.85f, 1.15f);
				TriggerRandomGeneralAudio(localPlayer, isolationFactor);
			}
			float num2 = Mathf.Max(8f, _proximityService.GetTargetShadowIntervalSeconds(isolationFactor) * _shadowJitterMultiplier);
			_shadowNormalizedProgress += deltaTime / num2;
			if (_shadowNormalizedProgress >= 1f)
			{
				if (TriggerShadowHallucination(localPlayer, isolationFactor))
				{
					_shadowNormalizedProgress = 0f;
					_shadowJitterMultiplier = Random.Range(0.85f, 1.15f);
				}
				else
				{
					_shadowNormalizedProgress = 0.92f;
				}
			}
		}

		private void TickVehicleWelcomeCheck()
		{
			if (_levelWelcomeEvaluated || _levelSpawnTimestamp < 0f)
			{
				return;
			}
			float num = Time.time - _levelSpawnTimestamp;
			if (SemiFunc.IsMasterClientOrSingleplayer() && num >= 1.4f)
			{
				_levelWelcomeEvaluated = true;
				EvaluateAndBroadcastWelcomeSound();
			}
			else
			{
				if (SemiFunc.IsMasterClientOrSingleplayer() || !(num >= 2.6f))
				{
					return;
				}
				_levelWelcomeEvaluated = true;
				if (!_receivedHostWelcomeDecision)
				{
					float num2 = Mathf.Clamp01(_config.WelcomeSoundChance.Value);
					if (Random.value <= num2)
					{
						_soundLibrary.PlayWelcomeSound();
						_logger.LogDebug((object)"Activado 'welcome.ogg' al iniciar partida en el vehículo (roll local 25%).");
					}
				}
			}
		}

		private void EvaluateAndBroadcastWelcomeSound()
		{
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Expected O, but got Unknown
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			float num = Mathf.Clamp01(_config.WelcomeSoundChance.Value);
			bool flag = Random.value <= num;
			if (!SemiFunc.IsMultiplayer() || PhotonNetwork.CurrentRoom == null)
			{
				if (flag)
				{
					_soundLibrary.PlayWelcomeSound();
					_logger.LogDebug((object)"Activado 'welcome.ogg' al iniciar partida en el vehículo (Singleplayer 25%).");
				}
				return;
			}
			Player[] playerList = PhotonNetwork.PlayerList;
			if (playerList == null || playerList.Length == 0)
			{
				return;
			}
			List<int> list = new List<int>();
			if (flag)
			{
				int num2 = Random.Range(1, playerList.Length + 1);
				List<Player> list2 = new List<Player>(playerList);
				for (int i = 0; i < num2; i++)
				{
					if (list2.Count <= 0)
					{
						break;
					}
					int index = Random.Range(0, list2.Count);
					list.Add(list2[index].ActorNumber);
					list2.RemoveAt(index);
				}
			}
			object[] array = new object[2]
			{
				(byte)1,
				list.ToArray()
			};
			RaiseEventOptions val = new RaiseEventOptions
			{
				Receivers = (ReceiverGroup)0
			};
			PhotonNetwork.RaiseEvent((byte)177, (object)array, val, SendOptions.SendReliable);
			int item = ((PhotonNetwork.LocalPlayer != null) ? PhotonNetwork.LocalPlayer.ActorNumber : (-1));
			if (list.Contains(item))
			{
				_soundLibrary.PlayWelcomeSound();
				_logger.LogDebug((object)$"Activado 'welcome.ogg' en el vehículo para {list.Count} jugador(es) del equipo.");
			}
		}

		private void TriggerRandomGeneralAudio(PlayerAvatar localPlayer, float isolationFactor)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: 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_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			if (!_soundLibrary.HasGeneralSounds)
			{
				return;
			}
			string text = _soundLibrary.PickRandomGeneralClipKey();
			if (string.IsNullOrEmpty(text))
			{
				return;
			}
			bool num = ShouldTriggerAsGroupEvent(isolationFactor);
			bool flag = _soundLibrary.IsEnvironmentalClip(text);
			if (num)
			{
				Vector3 val = ComputeEnvironmentalAudioPosition(localPlayer, 3.5f, 9.5f);
				BroadcastGroupSound(text, val);
				_soundLibrary.PlayWorldSpatialSound(text, val);
				_logger.LogDebug((object)("Sonido grupal '" + text + ".ogg' reproducido para el equipo."));
				return;
			}
			if (flag)
			{
				Vector3 worldPosition = ComputeEnvironmentalAudioPosition(localPlayer, 4.5f, 11.5f);
				_soundLibrary.PlayWorldSpatialSound(text, worldPosition, 0.92f);
			}
			else
			{
				float num2 = Random.Range(-0.55f, 0.55f);
				float num3 = Random.Range(-0.75f, -0.35f);
				Vector3 localHeadOffset = default(Vector3);
				((Vector3)(ref localHeadOffset))..ctor(num2, Random.Range(-0.1f, 0.15f), num3);
				_soundLibrary.PlayCloseHallucinationSound(text, localHeadOffset);
			}
			_logger.LogDebug((object)$"Sonido personal '{text}.ogg' reproducido (aislamiento={isolationFactor:F2}).");
		}

		private bool TriggerShadowHallucination(PlayerAvatar localPlayer, float isolationFactor)
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			if (!_shadowService.TryFindShadowTrajectory(localPlayer, out var startPos, out var endPos, out var duration))
			{
				return false;
			}
			int entityIndex;
			ShadowModelKind shadowModelKind = _shadowService.PickRandomModel(out entityIndex);
			bool flag = ShouldTriggerAsGroupEvent(isolationFactor);
			if (flag)
			{
				BroadcastGroupShadow(shadowModelKind, entityIndex, startPos, endPos, duration);
			}
			_shadowService.SpawnShadow(shadowModelKind, entityIndex, startPos, endPos, duration);
			_logger.LogDebug((object)$"Sombra ({shadowModelKind}, grupal={flag}) generada por {duration:F1}s (aislamiento={isolationFactor:F2}).");
			return true;
		}

		private bool ShouldTriggerAsGroupEvent(float isolationFactor)
		{
			if (!SemiFunc.IsMultiplayer() || PhotonNetwork.CurrentRoom == null || PhotonNetwork.CurrentRoom.PlayerCount <= 1)
			{
				return false;
			}
			float num = Mathf.Clamp01(_config.GroupEventChance.Value);
			float num2 = ((isolationFactor > 0.75f) ? (num * 0.4f) : num);
			return Random.value <= num2;
		}

		private static Vector3 ComputeEnvironmentalAudioPosition(PlayerAvatar localPlayer, float minDistance, float maxDistance)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: 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)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: 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_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: 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)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = Vector3.ProjectOnPlane((SoundLibraryService.ResolveLocalListenerTransform() ?? ((Component)localPlayer).transform).forward, Vector3.up);
			Vector3 val2 = ((Vector3)(ref val)).normalized;
			if (((Vector3)(ref val2)).sqrMagnitude < 0.01f)
			{
				val2 = Vector3.forward;
			}
			float num = Random.Range(95f, 265f);
			Vector3 val3 = Quaternion.Euler(0f, num, 0f) * val2;
			float num2 = Random.Range(minDistance, maxDistance);
			return ((Component)localPlayer).transform.position + Vector3.up * 1.2f + val3 * num2;
		}

		private static void BroadcastGroupSound(string clipKey, Vector3 worldPos)
		{
			//IL_0024: 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)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			if (SemiFunc.IsMultiplayer() && PhotonNetwork.CurrentRoom != null)
			{
				object[] array = new object[3]
				{
					(byte)2,
					clipKey,
					worldPos
				};
				RaiseEventOptions val = new RaiseEventOptions
				{
					Receivers = (ReceiverGroup)0
				};
				PhotonNetwork.RaiseEvent((byte)177, (object)array, val, SendOptions.SendUnreliable);
			}
		}

		private static void BroadcastGroupShadow(ShadowModelKind modelKind, int entityIndex, Vector3 startPos, Vector3 endPos, float duration)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected O, but got Unknown
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			if (SemiFunc.IsMultiplayer() && PhotonNetwork.CurrentRoom != null)
			{
				object[] array = new object[6]
				{
					(byte)3,
					(byte)modelKind,
					entityIndex,
					startPos,
					endPos,
					duration
				};
				RaiseEventOptions val = new RaiseEventOptions
				{
					Receivers = (ReceiverGroup)0
				};
				PhotonNetwork.RaiseEvent((byte)177, (object)array, val, SendOptions.SendUnreliable);
			}
		}

		private void OnPhotonEventReceived(EventData photonEvent)
		{
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: 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)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			if (photonEvent == null || photonEvent.Code != 177 || !_config.Enabled.Value || !(photonEvent.CustomData is object[] array) || array.Length == 0)
			{
				return;
			}
			object obj = array[0];
			if (!(obj is byte))
			{
				return;
			}
			switch ((byte)obj)
			{
			case 1:
			{
				if (array.Length < 2 || !(array[1] is int[] array2))
				{
					break;
				}
				_receivedHostWelcomeDecision = true;
				_levelWelcomeEvaluated = true;
				int num = ((PhotonNetwork.LocalPlayer != null) ? PhotonNetwork.LocalPlayer.ActorNumber : (-1));
				for (int i = 0; i < array2.Length; i++)
				{
					if (array2[i] == num)
					{
						_soundLibrary.PlayWelcomeSound();
						break;
					}
				}
				break;
			}
			case 2:
				if (array.Length >= 3 && array[1] is string clipKey && array[2] is Vector3 worldPosition)
				{
					_soundLibrary.PlayWorldSpatialSound(clipKey, worldPosition);
					_audioNormalizedProgress = Mathf.Min(_audioNormalizedProgress, 0.45f);
				}
				break;
			case 3:
				if (array.Length >= 6 && array[1] is byte modelKind && array[2] is int entityIndex && array[3] is Vector3 startPos && array[4] is Vector3 endPos && array[5] is float duration)
				{
					_shadowService.SpawnShadow((ShadowModelKind)modelKind, entityIndex, startPos, endPos, duration);
					_shadowNormalizedProgress = Mathf.Min(_shadowNormalizedProgress, 0.45f);
				}
				break;
			}
		}

		private void ResetJitterMultipliers()
		{
			_audioJitterMultiplier = Random.Range(0.88f, 1.12f);
			_shadowJitterMultiplier = Random.Range(0.88f, 1.12f);
		}
	}
	public enum ShadowModelKind : byte
	{
		Player,
		Entity
	}
	public sealed class ShadowHallucinationService
	{
		private sealed class BakedMeshCleaner : MonoBehaviour
		{
			public Mesh? BakedMesh;

			private void OnDestroy()
			{
				if ((Object)(object)BakedMesh != (Object)null)
				{
					Object.Destroy((Object)(object)BakedMesh);
					BakedMesh = null;
				}
			}
		}

		private sealed class ShadowFigureBehaviour : MonoBehaviour
		{
			private const float BaseShadowAlpha = 0.88f;

			private Vector3 _startPos;

			private Vector3 _endPos;

			private bool _isStatic;

			private float _duration;

			private float _elapsed;

			private bool _fadingOutQuickly;

			private float _quickFadeProgress;

			private Material? _material;

			private Transform? _visualContainer;

			public void Initialize(Vector3 startPos, Vector3 endPos, float duration, float directGazeHoldSeconds, Material material, Transform visualContainer)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0008: Unknown result type (might be due to invalid IL or missing references)
				//IL_0009: Unknown result type (might be due to invalid IL or missing references)
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0010: Unknown result type (might be due to invalid IL or missing references)
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				//IL_0016: Unknown result type (might be due to invalid IL or missing references)
				_startPos = startPos;
				_endPos = endPos;
				Vector3 val = endPos - startPos;
				_isStatic = ((Vector3)(ref val)).sqrMagnitude < 0.05f;
				_duration = Mathf.Max(1.2f, duration);
				_material = material;
				_visualContainer = visualContainer;
				SetAlpha(0f);
			}

			private void Update()
			{
				//IL_005e: Unknown result type (might be due to invalid IL or missing references)
				//IL_004a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0050: Unknown result type (might be due to invalid IL or missing references)
				//IL_0056: Unknown result type (might be due to invalid IL or missing references)
				//IL_0063: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
				//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
				//IL_00db: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
				//IL_0127: Unknown result type (might be due to invalid IL or missing references)
				//IL_012c: Unknown result type (might be due to invalid IL or missing references)
				//IL_012d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0137: Unknown result type (might be due to invalid IL or missing references)
				//IL_013c: Unknown result type (might be due to invalid IL or missing references)
				//IL_010a: Unknown result type (might be due to invalid IL or missing references)
				//IL_010f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0114: Unknown result type (might be due to invalid IL or missing references)
				float deltaTime = Time.deltaTime;
				_elapsed += deltaTime;
				if (_elapsed >= _duration)
				{
					Object.Destroy((Object)(object)((Component)this).gameObject);
					return;
				}
				float num = Mathf.Clamp01(_elapsed / _duration);
				Vector3 val = (_isStatic ? _startPos : Vector3.Lerp(_startPos, _endPos, num));
				if (!_isStatic && (Object)(object)_visualContainer != (Object)null)
				{
					float num2 = Mathf.Sin(_elapsed * 9f) * 0.04f;
					_visualContainer.localPosition = new Vector3(0f, Mathf.Abs(num2), 0f);
				}
				((Component)this).transform.position = val;
				Transform val2 = SoundLibraryService.ResolveLocalListenerTransform();
				if ((Object)(object)val2 != (Object)null)
				{
					if (_isStatic)
					{
						Vector3 val3 = val2.position - val;
						val3.y = 0f;
						if (((Vector3)(ref val3)).sqrMagnitude > 0.01f)
						{
							((Component)this).transform.rotation = Quaternion.LookRotation(((Vector3)(ref val3)).normalized, Vector3.up);
						}
					}
					if (!_fadingOutQuickly && Vector3.Distance(val2.position, val + Vector3.up * 1f) < 3.8f)
					{
						_fadingOutQuickly = true;
					}
				}
				float alpha;
				if (_fadingOutQuickly)
				{
					_quickFadeProgress += deltaTime / 0.25f;
					alpha = Mathf.Lerp(0.88f, 0f, Mathf.Clamp01(_quickFadeProgress));
					if (_quickFadeProgress >= 1f)
					{
						Object.Destroy((Object)(object)((Component)this).gameObject);
						return;
					}
				}
				else
				{
					float num3 = Mathf.Clamp01(_elapsed / 0.18f);
					float num4 = Mathf.Clamp01((_duration - _elapsed) / 0.3f);
					alpha = 0.88f * Mathf.Min(num3, num4);
				}
				SetAlpha(alpha);
			}

			private void OnDestroy()
			{
				if ((Object)(object)_material != (Object)null)
				{
					Object.Destroy((Object)(object)_material);
					_material = null;
				}
			}

			private void SetAlpha(float alpha)
			{
				//IL_0015: Unknown result type (might be due to invalid IL or missing references)
				//IL_001a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0029: Unknown result type (might be due to invalid IL or missing references)
				if (!((Object)(object)_material == (Object)null))
				{
					Color color = _material.color;
					color.a = alpha;
					_material.color = color;
				}
			}
		}

		private readonly ModConfig _config;

		private readonly ManualLogSource _logger;

		private Material? _shadowMaterialTemplate;

		public ShadowHallucinationService(ModConfig config, ManualLogSource logger)
		{
			_config = config ?? throw new ArgumentNullException("config");
			_logger = logger ?? throw new ArgumentNullException("logger");
		}

		public ShadowModelKind PickRandomModel(out int entityIndex)
		{
			entityIndex = -1;
			EnemyDirector instance = EnemyDirector.instance;
			List<EnemyParent> list = (((Object)(object)instance != (Object)null) ? instance.enemiesSpawned : null);
			if (list != null && list.Count > 0 && Random.value < 0.5f)
			{
				entityIndex = Random.Range(0, list.Count);
				return ShadowModelKind.Entity;
			}
			return ShadowModelKind.Player;
		}

		public bool TryFindShadowTrajectory(PlayerAvatar localPlayer, out Vector3 startPos, out Vector3 endPos, out float duration)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0256: Unknown result type (might be due to invalid IL or missing references)
			//IL_025b: Unknown result type (might be due to invalid IL or missing references)
			//IL_025d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0262: Unknown result type (might be due to invalid IL or missing references)
			//IL_0275: Unknown result type (might be due to invalid IL or missing references)
			//IL_0277: Unknown result type (might be due to invalid IL or missing references)
			//IL_027d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02de: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_030c: Unknown result type (might be due to invalid IL or missing references)
			//IL_030e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0310: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0303: Unknown result type (might be due to invalid IL or missing references)
			//IL_0305: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			startPos = Vector3.zero;
			endPos = Vector3.zero;
			float num = Mathf.Max(1.5f, _config.ShadowDurationMinSeconds.Value);
			float num2 = Mathf.Max(num, _config.ShadowDurationMaxSeconds.Value);
			bool flag = Random.value < 0.5f;
			duration = (flag ? num : Random.Range(num, num2));
			Transform val = SoundLibraryService.ResolveLocalListenerTransform();
			if ((Object)(object)val == (Object)null || (Object)(object)localPlayer == (Object)null)
			{
				return false;
			}
			Vector3 position = val.position;
			Vector3 val2 = Vector3.ProjectOnPlane(val.forward, Vector3.up);
			Vector3 val3 = ((Vector3)(ref val2)).normalized;
			if (((Vector3)(ref val3)).sqrMagnitude < 0.01f)
			{
				val3 = ((Component)localPlayer).transform.forward;
			}
			LayerMask val4 = SemiFunc.LayerMaskGetVisionObstruct();
			float num3 = (RenderSettings.fog ? RenderSettings.fogEndDistance : 20f);
			float num4 = 8.5f;
			float num5 = Mathf.Clamp(num3 * 0.84f, 11.5f, 16.5f);
			List<LevelPoint> list = SemiFunc.LevelPointGetWithinDistance(((Component)localPlayer).transform.position, num4, num5);
			if (list != null && list.Count > 0)
			{
				int num6 = Random.Range(0, list.Count);
				for (int i = 0; i < list.Count; i++)
				{
					LevelPoint val5 = list[(num6 + i) % list.Count];
					if ((Object)(object)val5 == (Object)null)
					{
						continue;
					}
					Vector3 position2 = ((Component)val5).transform.position;
					Vector3 val6 = Vector3.ProjectOnPlane(position2 - position, Vector3.up);
					float magnitude = ((Vector3)(ref val6)).magnitude;
					if (magnitude < num4 || magnitude > num5 || Vector3.Angle(val3, ((Vector3)(ref val6)).normalized) > 44f)
					{
						continue;
					}
					Vector3 val7 = position2 + Vector3.up * 1.15f;
					if (!Physics.Linecast(position, val7, LayerMask.op_Implicit(val4)))
					{
						Vector3 val8 = SnapToFloor(position2, val4);
						if (flag)
						{
							startPos = val8;
							endPos = val8;
							return true;
						}
						BuildCorridorCrossingEndpoints(val8, ((Vector3)(ref val6)).normalized, val4, out startPos, out endPos);
						return true;
					}
				}
			}
			RaycastHit val10 = default(RaycastHit);
			for (int j = 0; j < 6; j++)
			{
				float num7 = ((Random.value < 0.5f) ? (-1f) : 1f) * Random.Range(0f, 26f);
				Vector3 val9 = Quaternion.Euler(0f, num7, 0f) * val3;
				float num8 = Random.Range(num4 + 0.5f, num5);
				if (Physics.Raycast(position, val9, ref val10, num8, LayerMask.op_Implicit(val4)))
				{
					if (((RaycastHit)(ref val10)).distance < num4 + 0.5f)
					{
						continue;
					}
					num8 = ((RaycastHit)(ref val10)).distance - 1f;
				}
				Vector3 val11 = SnapToFloor(((Component)localPlayer).transform.position + val9 * num8, val4);
				Vector3 val12 = val11 + Vector3.up * 1.15f;
				if (!Physics.Linecast(position, val12, LayerMask.op_Implicit(val4)))
				{
					if (flag)
					{
						startPos = val11;
						endPos = val11;
						return true;
					}
					BuildCorridorCrossingEndpoints(val11, val9, val4, out startPos, out endPos);
					return true;
				}
			}
			return false;
		}

		private static void BuildCorridorCrossingEndpoints(Vector3 centerFloorPos, Vector3 viewDirFlat, LayerMask obstructMask, out Vector3 startPos, out Vector3 endPos)
		{
			//IL_0019: 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)
			//IL_001f: 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_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			float num = ((Random.value < 0.5f) ? (-1f) : 1f);
			Vector3 val = Vector3.Cross(Vector3.up, viewDirFlat);
			Vector3 val2 = ((Vector3)(ref val)).normalized * num;
			Vector3 val3 = centerFloorPos + Vector3.up * 1f;
			float num2 = 2.4f;
			RaycastHit val4 = default(RaycastHit);
			if (Physics.Raycast(val3, -val2, ref val4, 2.8f, LayerMask.op_Implicit(obstructMask)))
			{
				num2 = Mathf.Max(0.4f, ((RaycastHit)(ref val4)).distance - 0.35f);
			}
			float num3 = 3.8f;
			RaycastHit val5 = default(RaycastHit);
			if (Physics.Raycast(val3, val2, ref val5, 4.5f, LayerMask.op_Implicit(obstructMask)))
			{
				num3 = Mathf.Max(1.8f, ((RaycastHit)(ref val5)).distance - 0.25f);
			}
			startPos = SnapToFloor(centerFloorPos - val2 * num2, obstructMask);
			endPos = SnapToFloor(centerFloorPos + val2 * num3, obstructMask);
		}

		public void SpawnShadow(ShadowModelKind modelKind, int entityIndex, Vector3 startPos, Vector3 endPos, float duration)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Expected O, but got Unknown
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//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_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			if (!_config.Enabled.Value)
			{
				return;
			}
			GameObject val = new GameObject($"DYST_Shadow_{modelKind}");
			val.transform.position = startPos;
			Vector3 val2 = endPos - startPos;
			val2.y = 0f;
			if (((Vector3)(ref val2)).sqrMagnitude > 0.05f)
			{
				val.transform.rotation = Quaternion.LookRotation(((Vector3)(ref val2)).normalized, Vector3.up);
			}
			else
			{
				Transform val3 = SoundLibraryService.ResolveLocalListenerTransform();
				if ((Object)(object)val3 != (Object)null)
				{
					Vector3 val4 = val3.position - startPos;
					val4.y = 0f;
					if (((Vector3)(ref val4)).sqrMagnitude > 0.01f)
					{
						val.transform.rotation = Quaternion.LookRotation(((Vector3)(ref val4)).normalized, Vector3.up);
					}
				}
			}
			GameObject val5 = new GameObject("Visuals");
			val5.transform.SetParent(val.transform, false);
			Material val6 = CreateShadowMaterialInstance();
			bool flag = false;
			if (modelKind == ShadowModelKind.Entity)
			{
				flag = TryBuildEntityVisuals(entityIndex, val5.transform, val6);
			}
			if (!flag)
			{
				flag = TryBuildPlayerVisuals(val5.transform, val6);
			}
			if (!flag)
			{
				BuildFallbackHumanoidVisuals(val5.transform, val6);
			}
			val.AddComponent<ShadowFigureBehaviour>().Initialize(startPos, endPos, duration, _config.ShadowDirectGazeHoldSeconds.Value, val6, val5.transform);
		}

		private static Vector3 SnapToFloor(Vector3 position, LayerMask floorMask)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			RaycastHit val = default(RaycastHit);
			if (Physics.Raycast(position + Vector3.up * 1.8f, Vector3.down, ref val, 5.5f, LayerMask.op_Implicit(floorMask)))
			{
				return ((RaycastHit)(ref val)).point;
			}
			return position;
		}

		private bool TryBuildEntityVisuals(int entityIndex, Transform targetRoot, Material shadowMaterial)
		{
			try
			{
				EnemyDirector instance = EnemyDirector.instance;
				if ((Object)(object)instance == (Object)null || instance.enemiesSpawned == null || instance.enemiesSpawned.Count == 0)
				{
					return false;
				}
				int index = Mathf.Clamp(entityIndex, 0, instance.enemiesSpawned.Count - 1);
				EnemyParent val = instance.enemiesSpawned[index];
				if ((Object)(object)val == (Object)null)
				{
					return false;
				}
				return CopyRenderersAsShadowSnapshot(((Object)(object)val.EnableObject != (Object)null) ? val.EnableObject.transform : ((Component)val).transform, targetRoot, shadowMaterial, 2.6f);
			}
			catch (Exception ex)
			{
				_logger.LogDebug((object)("Fallback a silueta de jugador al clonar entidad: " + ex.Message));
				return false;
			}
		}

		private bool TryBuildPlayerVisuals(Transform targetRoot, Material shadowMaterial)
		{
			try
			{
				PlayerAvatar val = null;
				List<PlayerAvatar> list = SemiFunc.PlayerGetList();
				if (list != null && list.Count > 0)
				{
					for (int i = 0; i < list.Count; i++)
					{
						PlayerAvatar val2 = list[i];
						if ((Object)(object)val2 != (Object)null && !PlayerAvatarAccess.IsLocal(val2) && (Object)(object)val2.playerAvatarVisuals != (Object)null)
						{
							val = val2;
							break;
						}
					}
					if ((Object)(object)val == (Object)null)
					{
						val = SemiFunc.PlayerAvatarLocal() ?? list[0];
					}
				}
				else
				{
					val = SemiFunc.PlayerAvatarLocal();
				}
				if ((Object)(object)val == (Object)null || (Object)(object)val.playerAvatarVisuals == (Object)null)
				{
					return false;
				}
				return CopyRenderersAsShadowSnapshot(((Object)(object)val.playerAvatarVisuals.meshParent != (Object)null) ? val.playerAvatarVisuals.meshParent.transform : ((Component)val.playerAvatarVisuals).transform, targetRoot, shadowMaterial, 2.1f);
			}
			catch (Exception ex)
			{
				_logger.LogDebug((object)("Fallback a silueta procedural al clonar jugador: " + ex.Message));
				return false;
			}
		}

		private static bool CopyRenderersAsShadowSnapshot(Transform sourceRoot, Transform targetRoot, Material shadowMaterial, float maxHeightMeters)
		{
			//IL_001d: 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_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0304: Unknown result type (might be due to invalid IL or missing references)
			//IL_0309: Unknown result type (might be due to invalid IL or missing references)
			//IL_030d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0316: Unknown result type (might be due to invalid IL or missing references)
			//IL_0321: Unknown result type (might be due to invalid IL or missing references)
			//IL_032a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0335: Unknown result type (might be due to invalid IL or missing references)
			//IL_033e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0362: Unknown result type (might be due to invalid IL or missing references)
			//IL_0367: Unknown result type (might be due to invalid IL or missing references)
			//IL_0369: Unknown result type (might be due to invalid IL or missing references)
			//IL_0386: Unknown result type (might be due to invalid IL or missing references)
			//IL_0395: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Expected O, but got Unknown
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Expected O, but got Unknown
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0292: Unknown result type (might be due to invalid IL or missing references)
			//IL_0297: Unknown result type (might be due to invalid IL or missing references)
			//IL_029b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cd: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)sourceRoot == (Object)null)
			{
				return false;
			}
			Renderer[] componentsInChildren = ((Component)sourceRoot).GetComponentsInChildren<Renderer>(true);
			if (componentsInChildren == null || componentsInChildren.Length == 0)
			{
				return false;
			}
			Matrix4x4 worldToLocalMatrix = sourceRoot.worldToLocalMatrix;
			bool flag = false;
			Bounds val = default(Bounds);
			bool flag2 = false;
			List<MeshFilter> list = new List<MeshFilter>();
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				Renderer val2 = componentsInChildren[i];
				if ((Object)(object)val2 == (Object)null || (!(val2 is SkinnedMeshRenderer) && !(val2 is MeshRenderer)))
				{
					continue;
				}
				string name = ((Object)((Component)val2).gameObject).name;
				if (name.IndexOf("Debug", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("Canvas", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("UI", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("Shadow", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					continue;
				}
				Mesh val3 = null;
				bool flag3 = false;
				SkinnedMeshRenderer val4 = (SkinnedMeshRenderer)(object)((val2 is SkinnedMeshRenderer) ? val2 : null);
				if (val4 != null && (Object)(object)val4.sharedMesh != (Object)null)
				{
					Mesh val5 = new Mesh
					{
						name = "DYST_Baked_" + ((Object)val4.sharedMesh).name
					};
					val4.BakeMesh(val5);
					val3 = val5;
					flag3 = true;
				}
				else if (val2 is MeshRenderer)
				{
					MeshFilter component = ((Component)val2).GetComponent<MeshFilter>();
					if ((Object)(object)component != (Object)null && (Object)(object)component.sharedMesh != (Object)null)
					{
						val3 = component.sharedMesh;
					}
				}
				if ((Object)(object)val3 == (Object)null || val3.vertexCount == 0)
				{
					if (flag3 && (Object)(object)val3 != (Object)null)
					{
						Object.Destroy((Object)(object)val3);
					}
					continue;
				}
				GameObject val6 = new GameObject($"Part_{i}");
				val6.layer = 0;
				val6.transform.SetParent(targetRoot, false);
				Matrix4x4 val7 = worldToLocalMatrix * ((Component)val2).transform.localToWorldMatrix;
				val6.transform.localPosition = Vector4.op_Implicit(((Matrix4x4)(ref val7)).GetColumn(3));
				val6.transform.localRotation = ((Matrix4x4)(ref val7)).rotation;
				val6.transform.localScale = (flag3 ? Vector3.one : ((Matrix4x4)(ref val7)).lossyScale);
				MeshFilter val8 = val6.AddComponent<MeshFilter>();
				val8.sharedMesh = val3;
				MeshRenderer val9 = val6.AddComponent<MeshRenderer>();
				int num = Mathf.Max(1, val3.subMeshCount);
				Material[] array = (Material[])(object)new Material[num];
				for (int j = 0; j < num; j++)
				{
					array[j] = shadowMaterial;
				}
				((Renderer)val9).sharedMaterials = array;
				((Renderer)val9).shadowCastingMode = (ShadowCastingMode)0;
				((Renderer)val9).receiveShadows = false;
				((Renderer)val9).lightProbeUsage = (LightProbeUsage)0;
				((Renderer)val9).reflectionProbeUsage = (ReflectionProbeUsage)0;
				if (flag3)
				{
					val6.AddComponent<BakedMeshCleaner>().BakedMesh = val3;
				}
				Bounds bounds = ((Renderer)val9).bounds;
				Vector3 size = ((Bounds)(ref bounds)).size;
				if (((Vector3)(ref size)).sqrMagnitude > 0.0001f)
				{
					size = ((Bounds)(ref bounds)).size;
					if (((Vector3)(ref size)).magnitude < 12f)
					{
						if (!flag2)
						{
							val = bounds;
							flag2 = true;
						}
						else
						{
							((Bounds)(ref val)).Encapsulate(bounds);
						}
					}
				}
				list.Add(val8);
				flag = true;
			}
			if (!flag)
			{
				return false;
			}
			if (flag2)
			{
				Vector3 position = targetRoot.position;
				Vector3 val10 = default(Vector3);
				((Vector3)(ref val10))..ctor(position.x - ((Bounds)(ref val)).center.x, position.y - ((Bounds)(ref val)).min.y, position.z - ((Bounds)(ref val)).center.z);
				for (int k = 0; k < list.Count; k++)
				{
					Transform transform = ((Component)list[k]).transform;
					transform.position += val10;
				}
				if (((Bounds)(ref val)).size.y > maxHeightMeters && ((Bounds)(ref val)).size.y > 0.1f)
				{
					float num2 = maxHeightMeters / ((Bounds)(ref val)).size.y;
					targetRoot.localScale = Vector3.one * num2;
				}
			}
			return true;
		}

		private static void BuildFallbackHumanoidVisuals(Transform targetRoot, Material shadowMaterial)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			CreatePrimitivePart((PrimitiveType)1, targetRoot, new Vector3(0f, 0.9f, 0f), new Vector3(0.48f, 0.75f, 0.32f), shadowMaterial);
			CreatePrimitivePart((PrimitiveType)0, targetRoot, new Vector3(0f, 1.78f, 0f), new Vector3(0.36f, 0.4f, 0.36f), shadowMaterial);
		}

		private static void CreatePrimitivePart(PrimitiveType type, Transform parent, Vector3 localPos, Vector3 localScale, Material shadowMaterial)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			GameObject obj = GameObject.CreatePrimitive(type);
			obj.layer = 0;
			Collider component = obj.GetComponent<Collider>();
			if ((Object)(object)component != (Object)null)
			{
				Object.Destroy((Object)(object)component);
			}
			obj.transform.SetParent(parent, false);
			obj.transform.localPosition = localPos;
			obj.transform.localScale = localScale;
			MeshRenderer component2 = obj.GetComponent<MeshRenderer>();
			if ((Object)(object)component2 != (Object)null)
			{
				((Renderer)component2).sharedMaterial = shadowMaterial;
				((Renderer)component2).shadowCastingMode = (ShadowCastingMode)0;
				((Renderer)component2).receiveShadows = false;
			}
		}

		private Material CreateShadowMaterialInstance()
		{
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Expected O, but got Unknown
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Expected O, but got Unknown
			if ((Object)(object)_shadowMaterialTemplate == (Object)null)
			{
				Shader val = Shader.Find("Sprites/Default");
				if ((Object)(object)val == (Object)null)
				{
					val = Shader.Find("Unlit/Color");
				}
				if ((Object)(object)val == (Object)null)
				{
					val = Shader.Find("Standard");
				}
				_shadowMaterialTemplate = new Material(val)
				{
					name = "DYST_ShadowMaterial",
					color = new Color(0.02f, 0.02f, 0.03f, 0.88f)
				};
			}
			return new Material(_shadowMaterialTemplate);
		}
	}
	public sealed class SoundLibraryService
	{
		private sealed class LocalHeadAudioFollower : MonoBehaviour
		{
			private Transform? _target;

			private Vector3 _localOffset;

			public void Initialize(Transform target, Vector3 localOffset)
			{
				//IL_0008: Unknown result type (might be due to invalid IL or missing references)
				//IL_0009: Unknown result type (might be due to invalid IL or missing references)
				_target = target;
				_localOffset = localOffset;
				UpdatePosition();
			}

			private void LateUpdate()
			{
				UpdatePosition();
			}

			private void UpdatePosition()
			{
				//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)
				if (!((Object)(object)_target == (Object)null))
				{
					((Component)this).transform.position = _target.TransformPoint(_localOffset);
				}
			}
		}

		public const string WelcomeClipKey = "welcome";

		public const string WakeUpClipKey = "wake-up";

		private static readonly HashSet<string> EnvironmentalClipKeys = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "chasquido-de-dedos", "door", "efecto-eco-dj-somar-2", "golpe-mesa", "haunting-ambience", "quot-sound-effect", "another-nightmare_trimmed" };

		private readonly ModConfig _config;

		private readonly ManualLogSource _logger;

		private readonly Dictionary<string, AudioClip> _clipsByName = new Dictionary<string, AudioClip>(StringComparer.OrdinalIgnoreCase);

		private readonly List<string> _generalPoolKeys = new List<string>();

		private string? _lastRandomClipKey;

		public bool HasGeneralSounds => _generalPoolKeys.Count > 0;

		public SoundLibraryService(ModConfig config, ManualLogSource logger)
		{
			_config = config ?? throw new ArgumentNullException("config");
			_logger = logger ?? throw new ArgumentNullException("logger");
		}

		public IEnumerator LoadAllSoundsCoroutine(string pluginAssemblyLocation)
		{
			string directoryName = Path.GetDirectoryName(pluginAssemblyLocation);
			if (string.IsNullOrEmpty(directoryName))
			{
				_logger.LogWarning((object)"No se pudo determinar el directorio del plugin para cargar sonidos.");
				yield break;
			}
			List<string> obj = new List<string>
			{
				Path.Combine(directoryName, "sounds"),
				directoryName
			};
			Dictionary<string, string> dictionary = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
			foreach (string item in obj)
			{
				if (!Directory.Exists(item))
				{
					continue;
				}
				string[] files = Directory.GetFiles(item, "*.ogg", SearchOption.TopDirectoryOnly);
				foreach (string text in files)
				{
					string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(text);
					if (!string.IsNullOrWhiteSpace(fileNameWithoutExtension) && !dictionary.ContainsKey(fileNameWithoutExtension))
					{
						dictionary[fileNameWithoutExtension] = text;
					}
				}
			}
			if (dictionary.Count == 0)
			{
				_logger.LogWarning((object)("No se encontraron archivos .ogg en '" + Path.Combine(directoryName, "sounds") + "'."));
				yield break;
			}
			foreach (KeyValuePair<string, string> item2 in dictionary)
			{
				string key = item2.Key;
				string filePath = item2.Value;
				string absoluteUri = new Uri(filePath).AbsoluteUri;
				UnityWebRequest request = UnityWebRequestMultimedia.GetAudioClip(absoluteUri, (AudioType)14);
				try
				{
					yield return request.SendWebRequest();
					if ((int)request.result != 1)
					{
						_logger.LogWarning((object)("Error al cargar sonido '" + filePath + "': " + request.error));
						continue;
					}
					AudioClip content = DownloadHandlerAudioClip.GetContent(request);
					if (!((Object)(object)content == (Object)null))
					{
						((Object)content).name = key;
						_clipsByName[key] = content;
						if (!string.Equals(key, "welcome", StringComparison.OrdinalIgnoreCase) && !string.Equals(key, "wake-up", StringComparison.OrdinalIgnoreCase))
						{
							_generalPoolKeys.Add(key);
						}
					}
				}
				finally
				{
					((IDisposable)request)?.Dispose();
				}
			}
			_logger.LogInfo((object)($"Sonidos cargados: {_clipsByName.Count} total ({_generalPoolKeys.Count} en pool aleatorio general, " + string.Format("welcome={0}, wake-up={1}).", _clipsByName.ContainsKey("welcome"), _clipsByName.ContainsKey("wake-up"))));
		}

		public string? PickRandomGeneralClipKey()
		{
			if (_generalPoolKeys.Count == 0)
			{
				return null;
			}
			if (_generalPoolKeys.Count == 1)
			{
				return _generalPoolKeys[0];
			}
			int num = 0;
			string text;
			do
			{
				int index = Random.Range(0, _generalPoolKeys.Count);
				text = _generalPoolKeys[index];
				num++;
			}
			while (num < 4 && string.Equals(text, _lastRandomClipKey, StringComparison.OrdinalIgnoreCase));
			_lastRandomClipKey = text;
			return text;
		}

		public bool IsEnvironmentalClip(string clipKey)
		{
			return EnvironmentalClipKeys.Contains(clipKey);
		}

		public void PlayWelcomeSound()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			PlayCloseHallucinationSound("welcome", new Vector3(0f, 0.05f, -0.55f), 0.95f);
		}

		public void PlayWakeUpSound()
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			float num = ((Random.value < 0.5f) ? (-0.45f) : 0.45f);
			PlayCloseHallucinationSound("wake-up", new Vector3(num, 0f, -0.45f), 0.95f);
		}

		public void PlayCloseHallucinationSound(string clipKey, Vector3 localHeadOffset, float volumeMultiplier = 0.9f)
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Expected O, but got Unknown
			if (_config.Enabled.Value && _clipsByName.TryGetValue(clipKey, out AudioClip value) && !((Object)(object)value == (Object)null))
			{
				Transform val = ResolveLocalListenerTransform();
				if (!((Object)(object)val == (Object)null))
				{
					GameObject val2 = new GameObject("DYST_Whisper_" + clipKey);
					val2.AddComponent<LocalHeadAudioFollower>().Initialize(val, localHeadOffset);
					AudioSource obj = val2.AddComponent<AudioSource>();
					obj.clip = value;
					obj.playOnAwake = false;
					obj.loop = false;
					obj.spatialBlend = (string.Equals(clipKey, "8d", StringComparison.OrdinalIgnoreCase) ? 0.35f : 0.85f);
					obj.minDistance = 0.25f;
					obj.maxDistance = 6f;
					obj.rolloffMode = (AudioRolloffMode)1;
					obj.dopplerLevel = 0f;
					obj.pitch = Random.Range(0.96f, 1.03f);
					obj.volume = Mathf.Clamp01(_config.MasterVolume.Value * volumeMultiplier);
					obj.Play();
					Object.Destroy((Object)val2, value.length + 0.5f);
				}
			}
		}

		public void PlayWorldSpatialSound(string clipKey, Vector3 worldPosition, float volumeMultiplier = 0.95f)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Expected O, but got Unknown
			if (_config.Enabled.Value && _clipsByName.TryGetValue(clipKey, out AudioClip value) && !((Object)(object)value == (Object)null))
			{
				GameObject val = new GameObject("DYST_WorldAudio_" + clipKey);
				val.transform.position = worldPosition;
				AudioSource obj = val.AddComponent<AudioSource>();
				obj.clip = value;
				obj.playOnAwake = false;
				obj.loop = false;
				obj.spatialBlend = 1f;
				obj.minDistance = 1.8f;
				obj.maxDistance = 22f;
				obj.rolloffMode = (AudioRolloffMode)2;
				obj.dopplerLevel = 0f;
				obj.pitch = Random.Range(0.95f, 1.04f);
				obj.volume = Mathf.Clamp01(_config.MasterVolume.Value * volumeMultiplier);
				obj.Play();
				Object.Destroy((Object)val, value.length + 0.5f);
			}
		}

		public static Transform? ResolveLocalListenerTransform()
		{
			if ((Object)(object)SemiFunc.MainCamera() != (Object)null)
			{
				return ((Component)SemiFunc.MainCamera()).transform;
			}
			if ((Object)(object)Camera.main != (Object)null)
			{
				return ((Component)Camera.main).transform;
			}
			PlayerAvatar val = SemiFunc.PlayerAvatarLocal();
			if ((Object)(object)val != (Object)null)
			{
				return ((Component)val).transform;
			}
			return null;
		}
	}
	public sealed class TeamProximityService
	{
		private const float CloseTeammateDistanceMeters = 5.5f;

		private readonly ModConfig _config;

		public TeamProximityService(ModConfig config)
		{
			_config = config ?? throw new ArgumentNullException("config");
		}

		public static bool TryGetActiveLocalPlayer(out PlayerAvatar localPlayer)
		{
			localPlayer = SemiFunc.PlayerAvatarLocal();
			if ((Object)(object)localPlayer == (Object)null || PlayerAvatarAccess.IsDead(localPlayer) || PlayerAvatarAccess.IsDisabled(localPlayer))
			{
				return false;
			}
			if (SemiFunc.IsMainMenu() || SemiFunc.IsSplashScreen() || SemiFunc.RunIsLobbyMenu())
			{
				return false;
			}
			return SemiFunc.LevelGenDone();
		}

		public float GetNearestLivingTeammateDistance(PlayerAvatar localPlayer, out int totalOtherPlayers, out int livingTeammates)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			totalOtherPlayers = 0;
			livingTeammates = 0;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return float.PositiveInfinity;
			}
			List<PlayerAvatar> list = SemiFunc.PlayerGetList();
			if (list == null || list.Count <= 1)
			{
				return float.PositiveInfinity;
			}
			Vector3 position = ((Component)localPlayer).transform.position;
			float num = float.PositiveInfinity;
			for (int i = 0; i < list.Count; i++)
			{
				PlayerAvatar val = list[i];
				if ((Object)(object)val == (Object)null || (Object)(object)val == (Object)(object)localPlayer || PlayerAvatarAccess.IsLocal(val))
				{
					continue;
				}
				totalOtherPlayers++;
				if (!PlayerAvatarAccess.IsDead(val) && !PlayerAvatarAccess.IsDisabled(val))
				{
					livingTeammates++;
					float num2 = Vector3.Distance(position, ((Component)val).transform.position);
					if (num2 < num)
					{
						num = num2;
					}
				}
			}
			return num;
		}

		public float GetIsolationFactor(PlayerAvatar localPlayer)
		{
			int totalOtherPlayers;
			int livingTeammates;
			float nearestLivingTeammateDistance = GetNearestLivingTeammateDistance(localPlayer, out totalOtherPlayers, out livingTeammates);
			if (totalOtherPlayers == 0)
			{
				return 0.45f;
			}
			if (livingTeammates == 0)
			{
				return 1.15f;
			}
			float num = Mathf.Max(7.5f, _config.IsolationDistanceThreshold.Value);
			if (nearestLivingTeammateDistance <= 5.5f)
			{
				return 0f;
			}
			return Mathf.Clamp((nearestLivingTeammateDistance - 5.5f) / (num - 5.5f), 0f, 1.3f);
		}

		public float GetTargetAudioIntervalSeconds(float isolationFactor)
		{
			float value = _config.AudioIntervalNearTeamSeconds.Value;
			float value2 = _config.AudioIntervalFarFromTeamSeconds.Value;
			return Mathf.Lerp(value, value2, Mathf.Clamp01(isolationFactor));
		}

		public float GetTargetShadowIntervalSeconds(float isolationFactor)
		{
			float value = _config.ShadowIntervalNearTeamSeconds.Value;
			float value2 = _config.ShadowIntervalFarFromTeamSeconds.Value;
			float num = Mathf.Lerp(value, value2, Mathf.Clamp01(isolationFactor));
			if (isolationFactor > 1f)
			{
				float num2 = isolationFactor - 1f;
				num *= Mathf.Lerp(1f, 0.78f, Mathf.Clamp01(num2 / 0.3f));
			}
			return Mathf.Max(12f, num);
		}
	}
}
namespace DidYouSeeThatMod.Patches
{
	[HarmonyPatch]
	internal static class PlayerAndLevelPatches
	{
		private static HauntDirectorService? _director;

		private static ModConfig? _config;

		public static void Initialize(HauntDirectorService director, ModConfig config)
		{
			_director = director;
			_config = config;
		}

		[HarmonyPatch(typeof(EnvironmentDirector), "FogLogic")]
		[HarmonyPostfix]
		private static void EnvironmentDirector_FogLogic_Postfix()
		{
			if (_config == null || !_config.Enabled.Value)
			{
				return;
			}
			float value = _config.FogDistanceMultiplier.Value;
			if (!(value <= 1.01f))
			{
				RenderSettings.fogStartDistance *= value;
				RenderSettings.fogEndDistance *= value;
				Camera val = SemiFunc.MainCamera();
				if ((Object)(object)val != (Object)null && val.farClipPlane < RenderSettings.fogEndDistance + 2f)
				{
					val.farClipPlane = RenderSettings.fogEndDistance + 2f;
				}
			}
		}

		[HarmonyPatch(typeof(LevelGenerator), "Start")]
		[HarmonyPostfix]
		private static void LevelGenerator_Start_Postfix()
		{
			_director?.OnNewLevelStarted();
		}

		[HarmonyPatch(typeof(LevelGenerator), "GenerateDoneApply")]
		[HarmonyPostfix]
		private static void LevelGenerator_GenerateDoneApply_Postfix()
		{
			_director?.NotifyPlayerSpawnedInVehicle();
		}

		[HarmonyPatch(typeof(PlayerAvatar), "LoadingLevelAnimationCompleted")]
		[HarmonyPostfix]
		private static void PlayerAvatar_LoadingLevelAnimationCompleted_Postfix(PlayerAvatar __instance)
		{
			if ((Object)(object)__instance != (Object)null && PlayerAvatarAccess.IsLocal(__instance))
			{
				_director?.NotifyPlayerSpawnedInVehicle();
			}
		}

		[HarmonyPatch(typeof(PlayerAvatar), "StandToCrouch")]
		[HarmonyPostfix]
		private static void PlayerAvatar_StandToCrouch_Postfix(PlayerAvatar __instance)
		{
			if ((Object)(object)__instance != (Object)null && PlayerAvatarAccess.IsLocal(__instance) && !PlayerAvatarAccess.IsDead(__instance))
			{
				_director?.OnLocalPlayerCrouched();
			}
		}
	}
}
namespace DidYouSeeThatMod.Internal
{
	internal static class PlayerAvatarAccess
	{
		private static readonly FieldRef<PlayerAvatar, bool> IsLocalRef = AccessTools.FieldRefAccess<PlayerAvatar, bool>("isLocal");

		private static readonly FieldRef<PlayerAvatar, bool> DeadSetRef = AccessTools.FieldRefAccess<PlayerAvatar, bool>("deadSet");

		private static readonly FieldRef<PlayerAvatar, bool> IsDisabledRef = AccessTools.FieldRefAccess<PlayerAvatar, bool>("isDisabled");

		public static bool IsLocal(PlayerAvatar avatar)
		{
			if ((Object)(object)avatar != (Object)null)
			{
				if (!IsLocalRef.Invoke(avatar))
				{
					return (Object)(object)avatar == (Object)(object)SemiFunc.PlayerAvatarLocal();
				}
				return true;
			}
			return false;
		}

		public static bool IsDead(PlayerAvatar avatar)
		{
			if (!((Object)(object)avatar == (Object)null))
			{
				return DeadSetRef.Invoke(avatar);
			}
			return true;
		}

		public static bool IsDisabled(PlayerAvatar avatar)
		{
			if (!((Object)(object)avatar == (Object)null))
			{
				return IsDisabledRef.Invoke(avatar);
			}
			return true;
		}
	}
}
namespace DidYouSeeThatMod.Configuration
{
	public sealed class ModConfig
	{
		public ConfigEntry<bool> Enabled { get; }

		public ConfigEntry<float> MasterVolume { get; }

		public ConfigEntry<float> WelcomeSoundChance { get; }

		public ConfigEntry<float> WakeUpCrouchChance { get; }

		public ConfigEntry<float> WakeUpCooldownSeconds { get; }

		public ConfigEntry<float> AudioIntervalNearTeamSeconds { get; }

		public ConfigEntry<float> AudioIntervalFarFromTeamSeconds { get; }

		public ConfigEntry<float> ShadowIntervalNearTeamSeconds { get; }

		public ConfigEntry<float> ShadowIntervalFarFromTeamSeconds { get; }

		public ConfigEntry<float> ShadowDurationMinSeconds { get; }

		public ConfigEntry<float> ShadowDurationMaxSeconds { get; }

		public ConfigEntry<float> ShadowDirectGazeHoldSeconds { get; }

		public ConfigEntry<float> FogDistanceMultiplier { get; }

		public ConfigEntry<float> IsolationDistanceThreshold { get; }

		public ConfigEntry<float> GroupEventChance { get; }

		public ModConfig(ConfigFile config)
		{
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Expected O, but got Unknown
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Expected O, but got Unknown
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Expected O, but got Unknown
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Expected O, but got Unknown
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Expected O, but got Unknown
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Expected O, but got Unknown
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Expected O, but got Unknown
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Expected O, but got Unknown
			//IL_0222: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Expected O, but got Unknown
			//IL_025b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0265: Expected O, but got Unknown
			//IL_0294: Unknown result type (might be due to invalid IL or missing references)
			//IL_029e: Expected O, but got Unknown
			//IL_02cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d7: Expected O, but got Unknown
			//IL_0306: Unknown result type (might be due to invalid IL or missing references)
			//IL_0310: Expected O, but got Unknown
			//IL_033f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0349: Expected O, but got Unknown
			if (config == null)
			{
				throw new ArgumentNullException("config");
			}
			Enabled = config.Bind<bool>("General", "Enabled", true, "Activa o desactiva por completo los efectos de alucinación, susurros y sombras.");
			MasterVolume = config.Bind<float>("Audio", "MasterVolume", 0.85f, new ConfigDescription("Volumen general de los sonidos de alucinación y susurros (0.0 a 1.0).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.05f, 1f), Array.Empty<object>()));
			WelcomeSoundChance = config.Bind<float>("SpecialSounds", "WelcomeSoundChance", 0.25f, new ConfigDescription("Probabilidad (0.25 = 25%) de que suene 'welcome.ogg' a 1 o varios miembros del equipo únicamente al iniciar la partida en el vehículo.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			WakeUpCrouchChance = config.Bind<float>("SpecialSounds", "WakeUpCrouchChance", 0.1f, new ConfigDescription("Probabilidad (0.10 = 10%) de que suene 'wake-up.ogg' exclusivamente para el jugador que se agache.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			WakeUpCooldownSeconds = config.Bind<float>("SpecialSounds", "WakeUpCooldownSeconds", 8f, new ConfigDescription("Tiempo mínimo en segundos entre activaciones de 'wake-up.ogg' al agacharse repetidamente.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 120f), Array.Empty<object>()));
			AudioIntervalNearTeamSeconds = config.Bind<float>("AudioSchedule", "AudioIntervalNearTeamSeconds", 80f, new ConfigDescription("Tiempo promedio (en segundos) entre sonidos aleatorios cuando el jugador está acompañado por su equipo.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(15f, 300f), Array.Empty<object>()));
			AudioIntervalFarFromTeamSeconds = config.Bind<float>("AudioSchedule", "AudioIntervalFarFromTeamSeconds", 40f, new ConfigDescription("Tiempo promedio (en segundos) entre sonidos aleatorios cuando el jugador está lejos del equipo / aislado.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(10f, 240f), Array.Empty<object>()));
			ShadowIntervalNearTeamSeconds = config.Bind<float>("Shadows", "ShadowIntervalNearTeamSeconds", 80f, new ConfigDescription("Tiempo promedio (en segundos) entre apariciones de sombras cuando el jugador está cerca del grupo.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(15f, 300f), Array.Empty<object>()));
			ShadowIntervalFarFromTeamSeconds = config.Bind<float>("Shadows", "ShadowIntervalFarFromTeamSeconds", 38f, new ConfigDescription("Tiempo promedio (en segundos) entre apariciones de sombras cuando el jugador está alejado del grupo (mientras más lejos, más frecuente).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(10f, 240f), Array.Empty<object>()));
			ShadowDurationMinSeconds = config.Bind<float>("Shadows", "ShadowDurationMinSeconds", 2f, new ConfigDescription("Duración mínima (en segundos) antes de que la sombra desaparezca (2.0s por defecto).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 10f), Array.Empty<object>()));
			ShadowDurationMaxSeconds = config.Bind<float>("Shadows", "ShadowDurationMaxSeconds", 2.3f, new ConfigDescription("Duración máxima (en segundos) para sombras que cruzan un pasillo a la distancia.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1.2f, 15f), Array.Empty<object>()));
			ShadowDirectGazeHoldSeconds = config.Bind<float>("Shadows", "ShadowDirectGazeHoldSeconds", 2f, new ConfigDescription("Tiempo (en segundos) que la sombra permanece visible antes de desvanecerse.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 5f), Array.Empty<object>()));
			FogDistanceMultiplier = config.Bind<float>("Shadows", "FogDistanceMultiplier", 1.35f, new ConfigDescription("Multiplicador de distancia del fog (niebla) y cámara del juego (1.35 = +35% de visión en pasillos para poder ver las sombras a lo lejos).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 2.5f), Array.Empty<object>()));
			IsolationDistanceThreshold = config.Bind<float>("Proximity", "IsolationDistanceThreshold", 18f, new ConfigDescription("Distancia en metros al compañero vivo más cercano a partir de la cual se considera que el jugador está lejos del equipo.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(6f, 60f), Array.Empty<object>()));
			GroupEventChance = config.Bind<float>("Multiplayer", "GroupEventChance", 0.35f, new ConfigDescription("Probabilidad base (0.35 = 35%) de que un evento de sonido o sombra sea grupal (para el equipo) en vez de personal.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
		}
	}
}