Decompiled source of PsychoValuable v1.2.1

com.github.zehsteam.PsychoValuable.dll

Decompiled a month ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using REPOLib;
using REPOLib.Modules;
using UnityEngine;
using com.github.zehsteam.PsychoValuable.MonoBehaviours;
using com.github.zehsteam.PsychoValuable.Objects;
using com.github.zehsteam.PsychoValuable.Patches;

[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("Zehs")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright © 2025 Zehs")]
[assembly: AssemblyDescription("A sassy talking potato valuable that reacts to your presence, your interactions, and has an explosive exit. Made for and voiced by the Twitch streamer PsychoHypnotic.")]
[assembly: AssemblyFileVersion("1.2.1.0")]
[assembly: AssemblyInformationalVersion("1.2.1+34a887931659822a74f73c5614bd68d1ac96a569")]
[assembly: AssemblyProduct("PsychoValuable")]
[assembly: AssemblyTitle("com.github.zehsteam.PsychoValuable")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.2.1.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 com.github.zehsteam.PsychoValuable
{
	internal static class Assets
	{
		public static GameObject PsychoPrefab { get; private set; }

		public static void Initialize()
		{
			string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
			string text = "psychovaluable_assets";
			string text2 = Path.Combine(directoryName, text);
			if (!File.Exists(text2))
			{
				Logger.LogFatal("Failed to load assets. AssetBundle file could not be found at path \"" + text2 + "\". Make sure the \"" + text + "\" file is in the same folder as the mod's DLL file.");
			}
			else
			{
				BundleLoader.LoadBundle(text2, (Action<AssetBundle>)HandleAssetBundleLoaded, false);
			}
		}

		private static void HandleAssetBundleLoaded(AssetBundle assetBundle)
		{
			if (TryLoadAsset<GameObject>("Valuable Psycho", assetBundle, out GameObject asset))
			{
				PsychoPrefab = asset;
				Valuables.RegisterValuable(PsychoPrefab);
			}
		}

		private static T LoadAsset<T>(string name, AssetBundle assetBundle) where T : Object
		{
			if (string.IsNullOrWhiteSpace(name))
			{
				Logger.LogError("Failed to load asset of type \"" + typeof(T).Name + "\" from AssetBundle. Name is null or whitespace.");
				return default(T);
			}
			if ((Object)(object)assetBundle == (Object)null)
			{
				Logger.LogError("Failed to load asset of type \"" + typeof(T).Name + "\" with name \"" + name + "\" from AssetBundle. AssetBundle is null.");
				return default(T);
			}
			T val = assetBundle.LoadAsset<T>(name);
			if ((Object)(object)val == (Object)null)
			{
				Logger.LogError("Failed to load asset of type \"" + typeof(T).Name + "\" with name \"" + name + "\" from AssetBundle. No asset found with that type and name.");
				return default(T);
			}
			return val;
		}

		private static bool TryLoadAsset<T>(string name, AssetBundle assetBundle, out T asset) where T : Object
		{
			asset = LoadAsset<T>(name, assetBundle);
			return (Object)(object)asset != (Object)null;
		}
	}
	internal static class ConfigManager
	{
		public static ConfigFile ConfigFile { get; private set; }

		public static ConfigEntry<bool> ExtendedLogging { get; private set; }

		public static ConfigEntry<bool> Psycho_ContinuouslySpeakInProximity { get; private set; }

		public static DummyConfigEntry<float> Psycho_IdleSoundChance { get; private set; } = new DummyConfigEntry<float>(70f);


		public static DummyConfigEntry<float> Psycho_IdleSoundCooldownMin { get; private set; } = new DummyConfigEntry<float>(15f);


		public static DummyConfigEntry<float> Psycho_IdleSoundCooldownMax { get; private set; } = new DummyConfigEntry<float>(45f);


		public static DummyConfigEntry<float> Psycho_HeldSoundCooldownMin { get; private set; } = new DummyConfigEntry<float>(5f);


		public static DummyConfigEntry<float> Psycho_HeldSoundCooldownMax { get; private set; } = new DummyConfigEntry<float>(10f);


		public static DummyConfigEntry<float> Psycho_InnerRadius { get; private set; } = new DummyConfigEntry<float>(5f);


		public static DummyConfigEntry<float> Psycho_OuterRadius { get; private set; } = new DummyConfigEntry<float>(12f);


		public static DummyConfigEntry<float> Psycho_InnerRadiusTriggerCooldownMin { get; private set; } = new DummyConfigEntry<float>(5f);


		public static DummyConfigEntry<float> Psycho_InnerRadiusTriggerCooldownMax { get; private set; } = new DummyConfigEntry<float>(10f);


		public static DummyConfigEntry<float> Psycho_OuterRadiusRadiusTriggerCooldown { get; private set; } = new DummyConfigEntry<float>(10f);


		public static DummyConfigEntry<float> Psycho_ExplosionRadius { get; private set; } = new DummyConfigEntry<float>(1.5f);


		public static DummyConfigEntry<int> Psycho_ExplosionDamage { get; private set; } = new DummyConfigEntry<int>(100);


		public static DummyConfigEntry<int> Psycho_ExplosionEnemyDamage { get; private set; } = new DummyConfigEntry<int>(150);


		public static void Initialize(ConfigFile configFile)
		{
			ConfigFile = configFile;
			BindConfigs();
		}

		private static void BindConfigs()
		{
			ExtendedLogging = ConfigFile.Bind<bool>("General", "ExtendedLogging", false, "Enable extended logging.");
			Psycho_ContinuouslySpeakInProximity = ConfigFile.Bind<bool>("Psycho", "ContinuouslySpeakInProximity", false, $"If enabled, Psycho will continuously speak every {Psycho_InnerRadiusTriggerCooldownMin.Value} to {Psycho_InnerRadiusTriggerCooldownMax.Value} seconds when a player is within {Psycho_InnerRadius.Value} meters.");
			Psycho_ContinuouslySpeakInProximity.SettingChanged += delegate
			{
				Psycho.HandleConfigSettingsChanged();
			};
		}
	}
	internal static class Logger
	{
		public static ManualLogSource ManualLogSource { get; private set; }

		public static void Initialize(ManualLogSource manualLogSource)
		{
			ManualLogSource = manualLogSource;
		}

		public static void LogDebug(object data)
		{
			Log((LogLevel)32, data);
		}

		public static void LogInfo(object data, bool extended = false)
		{
			Log((LogLevel)16, data, extended);
		}

		public static void LogWarning(object data, bool extended = false)
		{
			Log((LogLevel)4, data, extended);
		}

		public static void LogError(object data, bool extended = false)
		{
			Log((LogLevel)2, data, extended);
		}

		public static void LogFatal(object data, bool extended = false)
		{
			Log((LogLevel)1, data, extended);
		}

		public static void Log(LogLevel logLevel, object data, bool extended = false)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			if (!extended || IsExtendedLoggingEnabled())
			{
				ManualLogSource manualLogSource = ManualLogSource;
				if (manualLogSource != null)
				{
					manualLogSource.Log(logLevel, data);
				}
			}
		}

		public static bool IsExtendedLoggingEnabled()
		{
			if (ConfigManager.ExtendedLogging == null)
			{
				return false;
			}
			return ConfigManager.ExtendedLogging.Value;
		}
	}
	[BepInPlugin("com.github.zehsteam.PsychoValuable", "PsychoValuable", "1.2.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	internal class Plugin : BaseUnityPlugin
	{
		private readonly Harmony _harmony = new Harmony("com.github.zehsteam.PsychoValuable");

		internal static Plugin Instance { get; private set; }

		private void Awake()
		{
			Instance = this;
			Logger.Initialize(Logger.CreateLogSource("com.github.zehsteam.PsychoValuable"));
			Logger.LogInfo("PsychoValuable has awoken!");
			_harmony.PatchAll(typeof(EnemyValuableThrowerPatch));
			ConfigManager.Initialize(((BaseUnityPlugin)this).Config);
			Assets.Initialize();
		}
	}
	internal static class Utils
	{
		public static bool RollChance(float percent)
		{
			if (percent <= 0f)
			{
				return false;
			}
			if (percent >= 100f)
			{
				return true;
			}
			return Random.value * 100f <= percent;
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "com.github.zehsteam.PsychoValuable";

		public const string PLUGIN_NAME = "PsychoValuable";

		public const string PLUGIN_VERSION = "1.2.1";
	}
}
namespace com.github.zehsteam.PsychoValuable.Patches
{
	[HarmonyPatch(typeof(EnemyValuableThrower))]
	internal static class EnemyValuableThrowerPatch
	{
		public class Addon : MonoBehaviour
		{
			private PhysGrabObject _heldPhysGrabObject;

			private EnemyValuableThrower _enemyValuableThrower;

			private void Awake()
			{
				_enemyValuableThrower = ((Component)this).GetComponent<EnemyValuableThrower>();
				if ((Object)(object)_enemyValuableThrower == (Object)null)
				{
					Object.Destroy((Object)(object)this);
				}
			}

			private void OnEnable()
			{
				if (!_addons.ContainsKey(_enemyValuableThrower))
				{
					_addons.Add(_enemyValuableThrower, this);
				}
			}

			private void OnDisable()
			{
				_addons.Remove(_enemyValuableThrower);
			}

			private void Update()
			{
				if ((Object)(object)_enemyValuableThrower == (Object)null)
				{
					Object.Destroy((Object)(object)this);
				}
				else if ((Object)(object)_enemyValuableThrower.valuableTarget == (Object)null && (Object)(object)_heldPhysGrabObject != (Object)null)
				{
					HandleDrop(_heldPhysGrabObject);
				}
			}

			public void ValuableTargetFollow()
			{
				//IL_001c: 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)
				PhysGrabObject valuableTarget = _enemyValuableThrower.valuableTarget;
				if (!((Object)(object)valuableTarget == (Object)null) && !(Vector3.Distance(((Component)valuableTarget).transform.position, _enemyValuableThrower.pickupTarget.position) > 2f) && (Object)(object)valuableTarget != (Object)(object)_heldPhysGrabObject)
				{
					HandleGrab(valuableTarget);
				}
			}

			private void HandleGrab(PhysGrabObject physGrabObject)
			{
				if (!((Object)(object)physGrabObject == (Object)null))
				{
					IPhysGrabObjectEvents physGrabObjectEvents = default(IPhysGrabObjectEvents);
					if (((Component)physGrabObject).TryGetComponent<IPhysGrabObjectEvents>(ref physGrabObjectEvents))
					{
						physGrabObjectEvents.HandleGrabbedByEnemy(_enemyValuableThrower.enemy);
					}
					_heldPhysGrabObject = physGrabObject;
				}
			}

			private void HandleDrop(PhysGrabObject physGrabObject)
			{
				if (!((Object)(object)physGrabObject == (Object)null))
				{
					IPhysGrabObjectEvents physGrabObjectEvents = default(IPhysGrabObjectEvents);
					if (((Component)physGrabObject).TryGetComponent<IPhysGrabObjectEvents>(ref physGrabObjectEvents))
					{
						physGrabObjectEvents.HandleDroppedByEnemy(_enemyValuableThrower.enemy);
					}
					_heldPhysGrabObject = null;
				}
			}
		}

		private static Dictionary<EnemyValuableThrower, Addon> _addons = new Dictionary<EnemyValuableThrower, Addon>();

		[HarmonyPatch("Awake")]
		[HarmonyPostfix]
		private static void AwakePatch(EnemyValuableThrower __instance)
		{
			((Component)__instance).gameObject.AddComponent<Addon>();
		}

		[HarmonyPatch("ValuableTargetFollow")]
		[HarmonyPostfix]
		private static void ValuableTargetFollowPatch(EnemyValuableThrower __instance)
		{
			if (_addons.TryGetValue(__instance, out var value))
			{
				value.ValuableTargetFollow();
			}
		}
	}
}
namespace com.github.zehsteam.PsychoValuable.Objects
{
	internal class DummyConfigEntry<T>
	{
		public T Value { get; set; }

		public DummyConfigEntry(T value)
		{
			Value = value;
			base..ctor();
		}
	}
	internal interface IPhysGrabObjectEvents
	{
		void HandleGrabbedByEnemy(Enemy enemy);

		void HandleDroppedByEnemy(Enemy enemy);
	}
	internal class RadiusPlayerChecker
	{
		public float Radius;

		public bool ContinuouslyTrigger;

		private float _triggerCooldown;

		public float TriggerCooldownMin { get; private set; }

		public float TriggerCooldownMax { get; private set; }

		public bool HasPlayer { get; private set; }

		public float TimeLastTriggered { get; private set; }

		public event Action OnTrigger;

		public RadiusPlayerChecker(float radius, bool continuouslyTrigger = false)
		{
			Radius = radius;
			ContinuouslyTrigger = continuouslyTrigger;
		}

		public RadiusPlayerChecker(float radius, float triggerCooldownMin, float triggerCooldownMax, bool continuouslyTrigger = false)
			: this(radius, continuouslyTrigger)
		{
			SetTriggerCooldown(triggerCooldownMin, triggerCooldownMax);
		}

		public RadiusPlayerChecker(float radius, float triggerCooldown, bool continuouslyTrigger = false)
			: this(radius, triggerCooldown, triggerCooldown, continuouslyTrigger)
		{
		}

		public void CheckRadius(Vector3 position)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			bool hasPlayer = HasPlayer;
			HasPlayer = SemiFunc.PlayerGetAllPlayerAvatarWithinRange(Radius, position, false, default(LayerMask)).Count > 0;
			if (HasPlayer && !(!ContinuouslyTrigger && hasPlayer) && !IsOnTriggerCooldown())
			{
				this.OnTrigger?.Invoke();
				RandomizeCooldown();
				TimeLastTriggered = Time.realtimeSinceStartup;
			}
		}

		public bool IsOnTriggerCooldown()
		{
			return Time.realtimeSinceStartup - TimeLastTriggered <= _triggerCooldown;
		}

		public void SetTriggerCooldown(float value)
		{
			SetTriggerCooldown(value, value);
		}

		public void SetTriggerCooldown(float min, float max)
		{
			TriggerCooldownMin = min;
			TriggerCooldownMax = max;
			ValidateCooldown();
		}

		private void ValidateCooldown()
		{
			if (_triggerCooldown < TriggerCooldownMin || _triggerCooldown > TriggerCooldownMax)
			{
				RandomizeCooldown();
			}
		}

		private void RandomizeCooldown()
		{
			_triggerCooldown = Random.Range(TriggerCooldownMin, TriggerCooldownMax);
		}
	}
}
namespace com.github.zehsteam.PsychoValuable.MonoBehaviours
{
	public abstract class AdvancedPhysGrabObject : MonoBehaviour
	{
		private bool _previouslyGrabbed;

		public PhotonView PhotonView { get; private set; }

		public PhysGrabObject PhysGrabObject { get; private set; }

		public PhysGrabObjectImpactDetector PhysGrabObjectImpactDetector { get; private set; }

		public bool Grabbed => PhysGrabObject?.grabbed ?? false;

		protected virtual void Awake()
		{
			PhotonView = ((Component)this).GetComponent<PhotonView>();
			PhysGrabObject = ((Component)this).GetComponent<PhysGrabObject>();
			PhysGrabObjectImpactDetector = ((Component)this).GetComponent<PhysGrabObjectImpactDetector>();
		}

		protected virtual void Update()
		{
			GrabLogic();
		}

		private void GrabLogic()
		{
			if ((Object)(object)PhysGrabObject == (Object)null)
			{
				return;
			}
			bool grabbed = PhysGrabObject.grabbed;
			if (grabbed)
			{
				if (!_previouslyGrabbed)
				{
					HandleGrabbedByPlayer();
				}
			}
			else if (_previouslyGrabbed)
			{
				HandleDroppedByPlayer();
			}
			_previouslyGrabbed = grabbed;
		}

		protected virtual void HandleGrabbedByPlayer()
		{
		}

		protected virtual void HandleDroppedByPlayer()
		{
		}

		protected void EnemyInvestigate(float radius = 6f)
		{
			PhysGrabObjectImpactDetector physGrabObjectImpactDetector = PhysGrabObjectImpactDetector;
			if (physGrabObjectImpactDetector != null)
			{
				physGrabObjectImpactDetector.EnemyInvestigate(radius);
			}
		}
	}
	public class Psycho : AdvancedPhysGrabObject, IPhysGrabObjectEvents
	{
		public enum SoundType
		{
			Idle,
			Pickup,
			Drop,
			Damage,
			EnterInnerRadius,
			EnterOuterRadius
		}

		[Serializable]
		public class SoundCollection
		{
			public SoundType Type;

			public AudioClip[] Entries = Array.Empty<AudioClip>();
		}

		[Space(20f)]
		[Header("Properties")]
		[Space(5f)]
		[SerializeField]
		private Transform _centerTransform;

		[Header("Visuals")]
		[Space(5f)]
		[SerializeField]
		private MeshRenderer _meshRenderer;

		[SerializeField]
		private Material _defaultMaterial;

		[SerializeField]
		private Material _mouthOpenMaterial;

		[Space(20f)]
		[Header("Audio")]
		[Space(5f)]
		[SerializeField]
		private AudioSource _audioSource;

		[SerializeField]
		private SoundCollection[] _soundCollections = Array.Empty<SoundCollection>();

		[Space(20f)]
		[Header("Debug")]
		[Space(5f)]
		[SerializeField]
		private float _debugInnerRadius = 5f;

		[SerializeField]
		private float _debugOuterRadius = 12f;

		private ParticleScriptExplosion _particleScriptExplosion;

		private Dictionary<SoundType, int> _previousSoundIndex = new Dictionary<SoundType, int>();

		private float _talkAnimationTimer;

		private float _talkAnimationCooldown = 0.1f;

		private RadiusPlayerChecker _innerRadiusChecker;

		private RadiusPlayerChecker _outerRadiusChecker;

		private float _radiusCheckTimer;

		private float _radiusCheckCooldown = 0.25f;

		private float _heldSoundTimer;

		private float _heldSoundCooldown = 5f;

		private float _idleTimer;

		private float _idleCooldown = 15f;

		public static List<Psycho> Instances { get; private set; } = new List<Psycho>();


		public bool IsTalking
		{
			get
			{
				AudioSource audioSource = _audioSource;
				if (audioSource == null)
				{
					return false;
				}
				return audioSource.isPlaying;
			}
		}

		public bool IsMouthOpen { get; private set; }

		protected override void Awake()
		{
			base.Awake();
			_particleScriptExplosion = ((Component)this).GetComponent<ParticleScriptExplosion>();
			_innerRadiusChecker = new RadiusPlayerChecker(5f, 5f, 10f);
			_outerRadiusChecker = new RadiusPlayerChecker(12f, 10f);
		}

		private void OnEnable()
		{
			if (!Instances.Contains(this))
			{
				Instances.Add(this);
			}
			_outerRadiusChecker.OnTrigger += HandlePlayerEnterOuterRadius;
			_innerRadiusChecker.OnTrigger += HandlePlayerEnterInnerRadius;
			UseConfigSettings();
		}

		private void OnDisable()
		{
			Instances.Remove(this);
			_outerRadiusChecker.OnTrigger -= HandlePlayerEnterOuterRadius;
			_innerRadiusChecker.OnTrigger -= HandlePlayerEnterInnerRadius;
		}

		protected override void Update()
		{
			base.Update();
			TalkAnimationLogic();
			if (SemiFunc.IsMasterClientOrSingleplayer())
			{
				RadiusCheckLogic();
				HeldLogic();
				IdleLogic();
			}
		}

		private void TalkAnimationLogic()
		{
			if ((Object)(object)_audioSource == (Object)null)
			{
				return;
			}
			if (!IsTalking)
			{
				if (IsMouthOpen)
				{
					CloseMouth();
				}
				return;
			}
			if (_talkAnimationTimer <= _talkAnimationCooldown)
			{
				_talkAnimationTimer += Time.deltaTime;
				return;
			}
			_talkAnimationTimer = 0f;
			_talkAnimationCooldown = Random.Range(0.05f, 0.2f);
			if (IsMouthOpen)
			{
				CloseMouth();
			}
			else
			{
				OpenMouth();
			}
		}

		private void RadiusCheckLogic()
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: 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)
			if (_radiusCheckTimer <= _radiusCheckCooldown)
			{
				_radiusCheckTimer += Time.deltaTime;
				return;
			}
			_radiusCheckTimer = 0f;
			Vector3 position = _centerTransform.position;
			_outerRadiusChecker.CheckRadius(position);
			_innerRadiusChecker.CheckRadius(position);
		}

		private void HandlePlayerEnterInnerRadius()
		{
			if (!base.Grabbed && !IsTalking)
			{
				PlaySound(SoundType.EnterInnerRadius);
			}
		}

		private void HandlePlayerEnterOuterRadius()
		{
			if (!_innerRadiusChecker.HasPlayer)
			{
				PlaySound(SoundType.EnterOuterRadius);
			}
		}

		protected override void HandleGrabbedByPlayer()
		{
			PlaySoundFromHostOnly(SoundType.Pickup, enemyInvestigate: true);
		}

		protected override void HandleDroppedByPlayer()
		{
			PlaySoundFromHostOnly(SoundType.Drop);
		}

		public void HandleGrabbedByEnemy(Enemy enemy)
		{
			Logger.LogInfo($"Psycho({((Object)((Component)this).gameObject).GetInstanceID()}): Grabbed by enemy \"{enemy.EnemyParent.enemyName}\" ({((Object)enemy).GetInstanceID()})", extended: true);
			PlaySound(SoundType.Pickup, enemyInvestigate: true);
		}

		public void HandleDroppedByEnemy(Enemy enemy)
		{
			Logger.LogInfo($"Psycho({((Object)((Component)this).gameObject).GetInstanceID()}): Dropped by enemy \"{enemy.EnemyParent.enemyName}\" ({((Object)enemy).GetInstanceID()})", extended: true);
			PlaySoundFromHostOnly(SoundType.Drop);
		}

		private void HeldLogic()
		{
			if (base.Grabbed && !IsTalking)
			{
				if (_heldSoundTimer <= _heldSoundCooldown)
				{
					_heldSoundTimer += Time.deltaTime;
					return;
				}
				float value = ConfigManager.Psycho_HeldSoundCooldownMin.Value;
				float value2 = ConfigManager.Psycho_HeldSoundCooldownMax.Value;
				_heldSoundTimer = 0f;
				_heldSoundCooldown = Random.Range(value, value2);
				PlaySound(SoundType.Pickup, enemyInvestigate: true);
			}
		}

		private void IdleLogic()
		{
			if (base.Grabbed || IsTalking)
			{
				return;
			}
			if (_idleTimer <= _idleCooldown)
			{
				_idleTimer += Time.deltaTime;
				return;
			}
			float value = ConfigManager.Psycho_IdleSoundChance.Value;
			float value2 = ConfigManager.Psycho_IdleSoundCooldownMin.Value;
			float value3 = ConfigManager.Psycho_IdleSoundCooldownMax.Value;
			_idleTimer = 0f;
			_idleCooldown = Random.Range(value2, value3);
			if (Utils.RollChance(value))
			{
				PlaySound(SoundType.Idle);
			}
		}

		private void OpenMouth()
		{
			IsMouthOpen = true;
			if (!((Object)(object)_meshRenderer == (Object)null) && !((Object)(object)_mouthOpenMaterial == (Object)null))
			{
				((Renderer)_meshRenderer).sharedMaterial = _mouthOpenMaterial;
			}
		}

		private void CloseMouth()
		{
			IsMouthOpen = false;
			if (!((Object)(object)_meshRenderer == (Object)null) && !((Object)(object)_defaultMaterial == (Object)null))
			{
				((Renderer)_meshRenderer).sharedMaterial = _defaultMaterial;
			}
		}

		public void PlayDamageSoundFromHostOnly()
		{
			PlaySoundFromHostOnly(SoundType.Damage);
		}

		public void PlaySoundFromHostOnly(SoundType type, bool enemyInvestigate = false)
		{
			if (SemiFunc.IsMasterClientOrSingleplayer())
			{
				PlaySound(type, enemyInvestigate);
			}
		}

		public void PlaySoundFromHostOnly(SoundType type, int index, bool enemyInvestigate = false)
		{
			if (SemiFunc.IsMasterClientOrSingleplayer())
			{
				PlaySound(type, index, enemyInvestigate);
			}
		}

		public void PlaySound(SoundType type, bool enemyInvestigate = false)
		{
			SoundCollection soundCollection = GetSoundCollection(type);
			if (soundCollection == null)
			{
				Logger.LogError($"Psycho: Failed to play sound. Could not find SoundCollection of type {type}");
				return;
			}
			if (soundCollection.Entries == null || soundCollection.Entries.Length == 0)
			{
				Logger.LogError($"Psycho: Failed to play sound. SoundCollection of type {type} does not have any valid entries.");
				return;
			}
			AudioClip[] entries = soundCollection.Entries;
			int num;
			if (entries.Length == 1)
			{
				num = 0;
			}
			else
			{
				int value;
				int num2 = (_previousSoundIndex.TryGetValue(type, out value) ? value : (-1));
				do
				{
					num = Random.Range(0, entries.Length);
				}
				while (num == num2);
			}
			_previousSoundIndex[type] = num;
			PlaySound(type, num, enemyInvestigate);
		}

		public void PlaySound(SoundType type, int index, bool enemyInvestigate = false)
		{
			if (SemiFunc.IsMultiplayer())
			{
				base.PhotonView.RPC("PlaySoundRPC", (RpcTarget)0, new object[3] { type, index, enemyInvestigate });
			}
			else
			{
				PlaySoundLocal(type, index, enemyInvestigate);
			}
		}

		[PunRPC]
		private void PlaySoundRPC(SoundType type, int index, bool enemyInvestigate = false)
		{
			PlaySoundLocal(type, index, enemyInvestigate);
		}

		private void PlaySoundLocal(SoundType type, int index, bool enemyInvestigate = false)
		{
			if ((Object)(object)_audioSource == (Object)null)
			{
				Logger.LogError("Psycho: Failed to play sound local. AudioSource is null.");
				return;
			}
			SoundCollection soundCollection = GetSoundCollection(type);
			if (soundCollection == null)
			{
				Logger.LogError($"Psycho: Failed to play sound local. Could not find SoundCollection of type {type}");
				return;
			}
			if (index < 0 || index > soundCollection.Entries.Length - 1)
			{
				Logger.LogError($"Psycho: Failed to play sound local. SoundCollection {soundCollection.Type} does not contian an entry at index {index}");
				return;
			}
			AudioClip val = soundCollection.Entries[index];
			if ((Object)(object)val == (Object)null)
			{
				Logger.LogError($"Psycho: Failed to play sound local. SoundCollection {soundCollection.Type} at index {index} has an invalid clip.");
				return;
			}
			if (_audioSource.isPlaying)
			{
				_audioSource.Stop();
			}
			_audioSource.clip = val;
			_audioSource.Play();
			_previousSoundIndex[type] = index;
			if (enemyInvestigate && SemiFunc.IsMasterClientOrSingleplayer())
			{
				EnemyInvestigate();
			}
			Logger.LogInfo($"Psycho({((Object)((Component)this).gameObject).GetInstanceID()}): Played sound local. Type: {type}, Index: {index}", extended: true);
		}

		private SoundCollection GetSoundCollection(SoundType type)
		{
			return _soundCollections.FirstOrDefault((SoundCollection x) => x.Type == type);
		}

		public void Explode()
		{
			//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_0047: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_centerTransform == (Object)null))
			{
				Vector3 position = _centerTransform.position;
				float value = ConfigManager.Psycho_ExplosionRadius.Value;
				int value2 = ConfigManager.Psycho_ExplosionDamage.Value;
				int value3 = ConfigManager.Psycho_ExplosionEnemyDamage.Value;
				ParticleScriptExplosion particleScriptExplosion = _particleScriptExplosion;
				if (particleScriptExplosion != null)
				{
					particleScriptExplosion.Spawn(position, value, value2, value3, 1f, false, false, 1f);
				}
			}
		}

		private void UseConfigSettings()
		{
			if (_innerRadiusChecker != null)
			{
				float value = ConfigManager.Psycho_InnerRadiusTriggerCooldownMin.Value;
				float value2 = ConfigManager.Psycho_InnerRadiusTriggerCooldownMax.Value;
				_innerRadiusChecker.Radius = ConfigManager.Psycho_InnerRadius.Value;
				_innerRadiusChecker.SetTriggerCooldown(value, value2);
				bool value3 = ConfigManager.Psycho_ContinuouslySpeakInProximity.Value;
				_innerRadiusChecker.ContinuouslyTrigger = value3;
			}
			if (_outerRadiusChecker != null)
			{
				float value4 = ConfigManager.Psycho_OuterRadiusRadiusTriggerCooldown.Value;
				_outerRadiusChecker.Radius = ConfigManager.Psycho_OuterRadius.Value;
				_outerRadiusChecker.SetTriggerCooldown(value4);
			}
		}

		public static void HandleConfigSettingsChanged()
		{
			foreach (Psycho instance in Instances)
			{
				instance.UseConfigSettings();
			}
		}

		private void OnDrawGizmos()
		{
			//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_001b: 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_0031: 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)
			if (!((Object)(object)_centerTransform == (Object)null))
			{
				Vector3 position = _centerTransform.position;
				Gizmos.color = Color.cyan;
				Gizmos.DrawWireSphere(position, _debugInnerRadius);
				Gizmos.color = Color.blue;
				Gizmos.DrawWireSphere(position, _debugOuterRadius);
			}
		}
	}
}
namespace com.github.zehsteam.PsychoValuable.Extensions
{
	internal static class ConfigFileExtensions
	{
		public static ConfigEntry<T> Bind<T>(this ConfigFile configFile, string section, string key, T defaultValue, string description, AcceptableValueBase acceptableValues)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			return configFile.Bind<T>(section, key, defaultValue, new ConfigDescription(description, acceptableValues, Array.Empty<object>()));
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}