Decompiled source of CapybaraDance v1.0.1

CapybaraDance.dll

Decompiled 3 weeks 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 BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Audio;
using UnityEngine.Networking;

[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("CapybaraDance")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("CapybaraDance")]
[assembly: AssemblyTitle("CapybaraDance")]
[assembly: AssemblyVersion("1.0.0.0")]
[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 CapybaraDance
{
	public class ModConfig
	{
		public readonly ConfigEntry<float> MusicVolume;

		public readonly ConfigEntry<float> MusicRange;

		public readonly ConfigEntry<float> SpatialBlend;

		public readonly ConfigEntry<float> BounceSpeed;

		public readonly ConfigEntry<float> BounceHeight;

		public readonly ConfigEntry<bool> DiscoLightEnabled;

		public readonly ConfigEntry<float> DiscoLightIntensity;

		public readonly ConfigEntry<float> DiscoLightRange;

		public readonly ConfigEntry<bool> ScalePulseEnabled;

		public readonly ConfigEntry<float> ScalePulseAmount;

		public ModConfig(ConfigFile cfg)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Expected O, but got Unknown
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Expected O, but got Unknown
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Expected O, but got Unknown
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Expected O, but got Unknown
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Expected O, but got Unknown
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Expected O, but got Unknown
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Expected O, but got Unknown
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Expected O, but got Unknown
			cfg.SaveOnConfigSet = false;
			MusicVolume = cfg.Bind<float>("CapybaraDance", "Music Volume", 0.4f, new ConfigDescription("Volume of the capybara music.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			MusicRange = cfg.Bind<float>("CapybaraDance", "Music Range", 45f, new ConfigDescription("Maximum distance the music can be heard from.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 200f), Array.Empty<object>()));
			SpatialBlend = cfg.Bind<float>("CapybaraDance", "Spatial Blend", 1f, new ConfigDescription("How 3D the music is. 0 = heard equally everywhere, 1 = full positional audio.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			BounceSpeed = cfg.Bind<float>("CapybaraDance", "Bounce Speed", 6.65f, new ConfigDescription("How fast the capybaras bounce.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 20f), Array.Empty<object>()));
			BounceHeight = cfg.Bind<float>("CapybaraDance", "Bounce Height", 1f, new ConfigDescription("How high the capybaras bounce.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2f), Array.Empty<object>()));
			DiscoLightEnabled = cfg.Bind<bool>("CapybaraDance", "Disco Light Enabled", true, "Attach a rainbow-cycling point light to each capybara.");
			DiscoLightIntensity = cfg.Bind<float>("CapybaraDance", "Disco Light Intensity", 5f, new ConfigDescription("Brightness of the disco lights.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 10f), Array.Empty<object>()));
			DiscoLightRange = cfg.Bind<float>("CapybaraDance", "Disco Light Range", 15f, new ConfigDescription("How far the disco lights reach.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 50f), Array.Empty<object>()));
			ScalePulseEnabled = cfg.Bind<bool>("CapybaraDance", "Scale Pulse Enabled", true, "Capybaras pulse in size to the beat.");
			ScalePulseAmount = cfg.Bind<float>("CapybaraDance", "Scale Pulse Amount", 0.1f, new ConfigDescription("How much the capybaras grow/shrink when pulsing.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			ClearOrphanedEntries(cfg);
			cfg.Save();
			cfg.SaveOnConfigSet = true;
		}

		private static void ClearOrphanedEntries(ConfigFile cfg)
		{
			((Dictionary<ConfigDefinition, string>)AccessTools.Property(typeof(ConfigFile), "OrphanedEntries").GetValue(cfg)).Clear();
		}
	}
	public class CapybaraDancer : MonoBehaviour
	{
		private Vector3 originalLocalPos;

		private Vector3 originalLocalScale;

		private float bounceOffset;

		private Light discoLight;

		private void Start()
		{
			//IL_0007: 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_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Expected O, but got Unknown
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			originalLocalPos = ((Component)this).transform.localPosition;
			originalLocalScale = ((Component)this).transform.localScale;
			bounceOffset = Random.Range(0f, MathF.PI * 2f);
			GameObject val = new GameObject("CapybaraDisco");
			val.transform.SetParent(((Component)this).transform, false);
			val.transform.localPosition = Vector3.up * 1.5f;
			discoLight = val.AddComponent<Light>();
			discoLight.type = (LightType)2;
			discoLight.shadows = (LightShadows)0;
			((Behaviour)discoLight).enabled = false;
		}

		private void OnEnable()
		{
			Plugin.RegisterCapybara(this);
		}

		private void Update()
		{
			//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_004e: 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_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			float value = Plugin.BoundConfig.BounceSpeed.Value;
			float value2 = Plugin.BoundConfig.BounceHeight.Value;
			float num = Mathf.Abs(Mathf.Sin((Time.time + bounceOffset) * value)) * value2;
			Vector3 val = (((Object)(object)((Component)this).transform.parent != (Object)null) ? ((Component)this).transform.parent.InverseTransformDirection(Vector3.up) : Vector3.up);
			((Component)this).transform.localPosition = originalLocalPos + val * num;
			if (Plugin.BoundConfig.ScalePulseEnabled.Value)
			{
				float num2 = Mathf.Abs(Mathf.Sin((Time.time + bounceOffset) * value));
				float value3 = Plugin.BoundConfig.ScalePulseAmount.Value;
				float num3 = 1f + num2 * value3;
				((Component)this).transform.localScale = originalLocalScale * num3;
			}
			else
			{
				((Component)this).transform.localScale = originalLocalScale;
			}
			if ((Object)(object)discoLight != (Object)null)
			{
				bool value4 = Plugin.BoundConfig.DiscoLightEnabled.Value;
				((Behaviour)discoLight).enabled = value4;
				if (value4)
				{
					float num4 = (Time.time + bounceOffset) * 0.5f % 1f;
					discoLight.color = Color.HSVToRGB(num4, 1f, 1f);
					discoLight.intensity = Plugin.BoundConfig.DiscoLightIntensity.Value;
					discoLight.range = Plugin.BoundConfig.DiscoLightRange.Value;
				}
			}
		}

		private void OnDisable()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			((Component)this).transform.localScale = originalLocalScale;
			Plugin.UnregisterCapybara(this);
		}

		private void OnDestroy()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			((Component)this).transform.localScale = originalLocalScale;
			if ((Object)(object)discoLight != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)discoLight).gameObject);
			}
			Plugin.UnregisterCapybara(this);
		}
	}
	public class CapybaraMusicPlayer : MonoBehaviour
	{
		private AudioSource audioSource;

		private void Awake()
		{
			if ((Object)(object)Plugin.MusicClip == (Object)null)
			{
				Object.Destroy((Object)(object)this);
				return;
			}
			audioSource = ((Component)this).gameObject.AddComponent<AudioSource>();
			audioSource.clip = Plugin.MusicClip;
			audioSource.loop = true;
			audioSource.playOnAwake = false;
			audioSource.rolloffMode = (AudioRolloffMode)1;
			audioSource.dopplerLevel = 0f;
			audioSource.spread = 60f;
			SFX_Player val = Object.FindFirstObjectByType<SFX_Player>();
			if ((Object)(object)val != (Object)null)
			{
				AudioMixerGroup value = Traverse.Create((object)val).Field<AudioMixerGroup>("defaultMixerGroup").Value;
				if ((Object)(object)value != (Object)null)
				{
					audioSource.outputAudioMixerGroup = value;
				}
			}
		}

		private void Update()
		{
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)audioSource == (Object)null)
			{
				return;
			}
			audioSource.volume = Plugin.BoundConfig.MusicVolume.Value;
			audioSource.maxDistance = Plugin.BoundConfig.MusicRange.Value;
			audioSource.spatialBlend = Plugin.BoundConfig.SpatialBlend.Value;
			CapybaraDancer nearestCapybara = Plugin.GetNearestCapybara();
			if ((Object)(object)nearestCapybara != (Object)null)
			{
				((Component)this).transform.position = ((Component)nearestCapybara).transform.position;
				if (!audioSource.isPlaying)
				{
					audioSource.Play();
				}
			}
			else if (audioSource.isPlaying)
			{
				audioSource.Stop();
			}
		}
	}
	[HarmonyPatch(typeof(Capybara), "OnEnable")]
	public static class PatchCapybaraOnEnable
	{
		private static void Postfix(Capybara __instance)
		{
			try
			{
				if (!((Object)(object)((Component)__instance).GetComponent<CapybaraDancer>() != (Object)null))
				{
					((Component)__instance).gameObject.AddComponent<CapybaraDancer>();
				}
			}
			catch (Exception arg)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogError((object)$"CapybaraDance patch error: {arg}");
				}
			}
		}
	}
	[BepInPlugin("CapybaraDance", "CapybaraDance", "1.0.1")]
	public class Plugin : BaseUnityPlugin
	{
		[CompilerGenerated]
		private sealed class <ScanForExistingCapybaras>d__22 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <ScanForExistingCapybaras>d__22(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = null;
					<>1__state = 1;
					return true;
				case 1:
				{
					<>1__state = -1;
					Capybara[] array = Object.FindObjectsByType<Capybara>((FindObjectsSortMode)0);
					foreach (Capybara val in array)
					{
						if ((Object)(object)((Component)val).GetComponent<CapybaraDancer>() == (Object)null)
						{
							((Component)val).gameObject.AddComponent<CapybaraDancer>();
						}
					}
					return false;
				}
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		public const string Id = "CapybaraDance";

		internal static AudioClip MusicClip;

		private static readonly List<CapybaraDancer> activeCapybaras = new List<CapybaraDancer>();

		private static CapybaraMusicPlayer musicPlayer;

		private readonly Harmony harmony = new Harmony("CapybaraDance");

		internal static ManualLogSource Log { get; private set; }

		internal static Plugin Instance { get; private set; }

		internal static ModConfig BoundConfig { get; private set; }

		internal static void RegisterCapybara(CapybaraDancer capy)
		{
			if (!activeCapybaras.Contains(capy))
			{
				activeCapybaras.Add(capy);
			}
			EnsureMusicPlayer();
		}

		internal static void UnregisterCapybara(CapybaraDancer capy)
		{
			activeCapybaras.Remove(capy);
		}

		internal static CapybaraDancer GetNearestCapybara()
		{
			//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_0086: 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)
			if ((Object)(object)MainCamera.instance == (Object)null)
			{
				if (activeCapybaras.Count <= 0)
				{
					return null;
				}
				return activeCapybaras[0];
			}
			Vector3 position = ((Component)MainCamera.instance).transform.position;
			CapybaraDancer result = null;
			float num = float.MaxValue;
			for (int num2 = activeCapybaras.Count - 1; num2 >= 0; num2--)
			{
				if ((Object)(object)activeCapybaras[num2] == (Object)null || !((Component)activeCapybaras[num2]).gameObject.activeInHierarchy)
				{
					activeCapybaras.RemoveAt(num2);
				}
				else
				{
					float num3 = Vector3.Distance(position, ((Component)activeCapybaras[num2]).transform.position);
					if (num3 < num)
					{
						num = num3;
						result = activeCapybaras[num2];
					}
				}
			}
			return result;
		}

		private static void EnsureMusicPlayer()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			if (!((Object)(object)musicPlayer != (Object)null))
			{
				GameObject val = new GameObject("CapybaraDance Music Player");
				Object.DontDestroyOnLoad((Object)val);
				musicPlayer = val.AddComponent<CapybaraMusicPlayer>();
			}
		}

		private void Awake()
		{
			if ((Object)(object)Instance != (Object)null && (Object)(object)Instance != (Object)(object)this)
			{
				Object.Destroy((Object)(object)this);
				return;
			}
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			BoundConfig = new ModConfig(((BaseUnityPlugin)this).Config);
			LoadMusic();
			harmony.PatchAll();
			((MonoBehaviour)this).StartCoroutine(ScanForExistingCapybaras());
			Log.LogInfo((object)"CapybaraDance loaded.");
		}

		[IteratorStateMachine(typeof(<ScanForExistingCapybaras>d__22))]
		private IEnumerator ScanForExistingCapybaras()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <ScanForExistingCapybaras>d__22(0);
		}

		private void LoadMusic()
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Invalid comparison between Unknown and I4
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Invalid comparison between Unknown and I4
			string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
			string[] files = Directory.GetFiles(directoryName, "*.wav");
			if (files.Length == 0)
			{
				Log.LogWarning((object)("No .wav files found in " + directoryName));
				return;
			}
			string text = files[0];
			try
			{
				UnityWebRequest audioClip = UnityWebRequestMultimedia.GetAudioClip(new Uri(text).AbsoluteUri, (AudioType)20);
				try
				{
					UnityWebRequestAsyncOperation val = audioClip.SendWebRequest();
					while (!((AsyncOperation)val).isDone)
					{
					}
					if ((int)audioClip.result == 2 || (int)audioClip.result == 3)
					{
						Log.LogError((object)("Error loading " + text + ": " + audioClip.error));
						return;
					}
					MusicClip = DownloadHandlerAudioClip.GetContent(audioClip);
					Log.LogInfo((object)("Loaded capybara music: " + Path.GetFileName(text)));
				}
				finally
				{
					((IDisposable)audioClip)?.Dispose();
				}
			}
			catch (Exception ex)
			{
				Log.LogError((object)("Failed to load music file " + text + ": " + ex.Message));
			}
		}
	}
}