Decompiled source of StupidBoomboxMix v2.0.0

PersonalBoombox.dll

Decompiled 2 years ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using PersonalBoombox.Patches;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.Networking;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("PersonalBoombox")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("PersonalBoombox")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("90672a7b-b084-4f8d-9d78-46affb7b97e7")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.1", FrameworkDisplayName = ".NET Framework 4.7.1")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace PersonalBoombox
{
	public static class Assets
	{
		[Serializable]
		private class PBDataJson
		{
			public string name;

			public string description;

			public int price;

			public float volume;

			public int red;

			public int blue;

			public int green;

			public Color color;

			public static PBDataJson GetData(string path)
			{
				if (File.Exists(path))
				{
					string json = File.ReadAllText(path);
					PBDataJson pBDataJson = CreateFromJson(json);
					pBDataJson.FillMissingValues();
					pBDataJson.AdjustValues();
					return pBDataJson;
				}
				logger.LogWarning((object)"Missing .json file. Using default values");
				return GetDefault();
			}

			public static PBDataJson GetDefault()
			{
				//IL_0052: 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)
				PBDataJson pBDataJson = new PBDataJson();
				pBDataJson.name = "Untitled";
				pBDataJson.description = "Missing Description";
				pBDataJson.price = 60;
				pBDataJson.volume = 0.5f;
				pBDataJson.red = 255;
				pBDataJson.blue = 255;
				pBDataJson.green = 255;
				pBDataJson.color = Color.white;
				return pBDataJson;
			}

			private void FillMissingValues()
			{
				if (string.IsNullOrWhiteSpace(name))
				{
					name = "Untitled";
				}
				if (string.IsNullOrWhiteSpace(description))
				{
					description = "Missing Description";
				}
			}

			private void AdjustValues()
			{
				//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
				int length = Mathf.Min(name.Length, 20);
				name = name.Substring(0, length);
				price = Mathf.Clamp(price, 0, 1000);
				volume = Mathf.Clamp(volume, 0f, PersonalBoomboxPlugin.Instance.maxVolumeValue);
				red = Mathf.Clamp(red, 0, 255);
				blue = Mathf.Clamp(blue, 0, 255);
				green = Mathf.Clamp(green, 0, 255);
				color = new Color((float)red / 255f, (float)green / 255f, (float)blue / 255f, 1f);
			}

			private static PBDataJson CreateFromJson(string json)
			{
				return JsonUtility.FromJson<PBDataJson>(json);
			}

			public string ToJson()
			{
				return JsonUtility.ToJson((object)this);
			}
		}

		private const string mainAssetBundleName = "personalboombox";

		private const int prefabCopyCount = 5;

		public static AssetBundle MainAssetBundle = null;

		public static GameObject originalPrefab;

		public static GameObject[] prefabCopies;

		private static readonly string[] musicExts = new string[1] { "mp3" };

		private static ManualLogSource logger => PersonalBoomboxPlugin.Instance.logger;

		private static string GetAssemblyName()
		{
			return Assembly.GetExecutingAssembly().FullName.Split(new char[1] { ',' })[0];
		}

		public static void LoadAssetBundle()
		{
			if ((Object)(object)MainAssetBundle == (Object)null)
			{
				using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(GetAssemblyName() + ".personalboombox");
				MainAssetBundle = AssetBundle.LoadFromStream(stream);
			}
			originalPrefab = Assets.Load<GameObject>("prefab");
			prefabCopies = (GameObject[])(object)new GameObject[5];
			for (int i = 0; i < 5; i++)
			{
				prefabCopies[i] = Assets.Load<GameObject>($"prefab{i + 1}");
			}
		}

		public static T Load<T>(string name) where T : Object
		{
			if ((Object)(object)MainAssetBundle == (Object)null)
			{
				logger.LogError((object)"Trying to load in asset but asset bundle is missing");
				return default(T);
			}
			logger.LogInfo((object)("Loading asset " + name));
			return MainAssetBundle.LoadAsset<T>(name);
		}

		public static void LoadMusicFolders()
		{
			List<string> paths = PersonalBoomboxPlugin.paths;
			List<PersonalBoomboxPlugin.PBData> list = new List<PersonalBoomboxPlugin.PBData>();
			int num = 0;
			foreach (string item in paths)
			{
				string[] directories = Directory.GetDirectories(item);
				string[] array = directories;
				foreach (string text in array)
				{
					string fullName = Directory.GetParent(item).FullName;
					string text2 = text.Replace(fullName, string.Empty);
					logger.LogInfo((object)("Reading from directory " + text2 + "!"));
					try
					{
						CreateFromDirectory(text, list, num++);
					}
					catch (Exception ex)
					{
						logger.LogError((object)("Error loading at folder " + text2));
						logger.LogError((object)ex.ToString());
					}
				}
			}
			list.Sort((PersonalBoomboxPlugin.PBData first, PersonalBoomboxPlugin.PBData second) => first.name.CompareTo(second.name));
			num = 0;
			foreach (PersonalBoomboxPlugin.PBData item2 in list)
			{
				char c = (char)(65 + num);
				item2.prefixName = $"pb{c}";
				item2.boomboxName = item2.prefixName + " " + item2.name;
				((Object)item2.prefab).name = item2.boomboxName;
				num++;
			}
			PersonalBoomboxPlugin.data = list;
		}

		private static void CreateFromDirectory(string directory, List<PersonalBoomboxPlugin.PBData> data, int index)
		{
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			if (index >= 5)
			{
				logger.LogWarning((object)$"Loading too many boomboxes. There is a limit of {5}");
				return;
			}
			string path = Path.Combine(directory, "data.json");
			IEnumerable<string> enumerable = from file in Directory.EnumerateFiles(directory, "*.*")
				where musicExts.Any((string x) => file.EndsWith(x, StringComparison.InvariantCultureIgnoreCase))
				select file;
			PBDataJson data2 = PBDataJson.GetData(path);
			char c = (char)(97 + index);
			PersonalBoomboxPlugin.PBData pBData = new PersonalBoomboxPlugin.PBData();
			pBData.name = data2.name;
			pBData.description = data2.description;
			pBData.price = data2.price;
			pBData.volume = data2.volume;
			pBData.prefab = prefabCopies[index];
			pBData.script = pBData.prefab.AddComponent<PersonalBoomboxItem>();
			pBData.script.musicAudios = new List<AudioClip>();
			pBData.color = data2.color;
			List<Coroutine> list = new List<Coroutine>();
			foreach (string item2 in enumerable)
			{
				Coroutine item = MyOwnCoroutine.AddCoroutine(LoadAudioClip(pBData, item2));
				list.Add(item);
			}
			MyOwnCoroutine.AddCoroutine(WaitForClips(pBData, list));
			data.Add(pBData);
			logger.LogInfo((object)("Loaded data from boombox " + pBData.name + "!"));
		}

		private static IEnumerator WaitForClips(PersonalBoomboxPlugin.PBData data, List<Coroutine> coroutines)
		{
			yield return null;
			foreach (Coroutine coroutine in coroutines)
			{
				yield return coroutine;
			}
			PersonalBoomboxItem script = data.script;
			int count = script.musicAudios.Count;
			script.SortAudioClips();
			script.finishedLoading = true;
			logger.LogInfo((object)$"{data.boomboxName} is fully set up with {count} songs!");
			if (count == 0)
			{
				logger.LogWarning((object)"Boomboxes with 0 songs will be skipped in the initialization process");
			}
		}

		private static IEnumerator LoadAudioClip(PersonalBoomboxPlugin.PBData data, string path)
		{
			string fileName = Path.GetFileName(path);
			logger.LogInfo((object)("Loading music file " + fileName));
			AudioType fileType = GetAudioType(path);
			if ((int)fileType == 0)
			{
				logger.LogError((object)("Error loading music file " + fileName + ". Unsupported file ext."));
				yield break;
			}
			UnityWebRequest loader = UnityWebRequestMultimedia.GetAudioClip(path, GetAudioType(path));
			loader.SendWebRequest();
			while (!loader.isDone)
			{
				yield return null;
			}
			if (loader.error != null)
			{
				logger.LogError((object)("Error loading music file " + fileName + ". Download failed"));
				logger.LogError((object)loader.error);
				yield break;
			}
			AudioClip clip = DownloadHandlerAudioClip.GetContent(loader);
			if ((Object)(object)clip == (Object)null || (int)clip.loadState != 2)
			{
				logger.LogError((object)("Error loading music file " + fileName + ". File is weird"));
			}
			data.script.AddAudioClip(clip);
			logger.LogInfo((object)("Loaded music file " + ((Object)clip).name));
		}

		public static AudioType GetAudioType(string path)
		{
			//IL_0020: 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_0024: Unknown result type (might be due to invalid IL or missing references)
			string text = Path.GetExtension(path).ToLowerInvariant();
			string text2 = text;
			if (text2 == ".mp3")
			{
				return (AudioType)13;
			}
			return (AudioType)0;
		}
	}
	public class PersonalBoomboxItem : GrabbableObject
	{
		public AudioSource boomboxAudio;

		public List<AudioClip> musicAudios;

		public bool finishedLoading;

		public AudioClip[] stopAudios;

		public Random musicRandomizer;

		private StartOfRound playersManager;

		private RoundManager roundManager;

		public bool isPlayingMusic;

		private float noiseInterval;

		private int timesPlayedWithoutTurningOff;

		public int pbIndex;

		public int AudioClipCount => (musicAudios != null) ? musicAudios.Count : 0;

		public void AddAudioClip(AudioClip clip)
		{
			musicAudios.Add(clip);
		}

		public void SortAudioClips()
		{
			musicAudios.Sort((AudioClip first, AudioClip second) => ((Object)first).name.CompareTo(((Object)second).name));
		}

		public override void Start()
		{
			((GrabbableObject)this).Start();
			playersManager = Object.FindObjectOfType<StartOfRound>();
			roundManager = Object.FindObjectOfType<RoundManager>();
			musicRandomizer = new Random(playersManager.randomMapSeed - 10);
		}

		public override void ItemActivate(bool used, bool buttonDown = true)
		{
			((GrabbableObject)this).ItemActivate(used, buttonDown);
			StartMusic(used);
		}

		private void StartMusic(bool startMusic, bool pitchDown = false)
		{
			if (startMusic && musicAudios.Count > 0)
			{
				boomboxAudio.clip = musicAudios[musicRandomizer.Next(0, musicAudios.Count)];
				boomboxAudio.pitch = 1f;
				boomboxAudio.Play();
			}
			else if (isPlayingMusic)
			{
				if (pitchDown)
				{
					((MonoBehaviour)this).StartCoroutine(musicPitchDown());
				}
				else
				{
					boomboxAudio.Stop();
					boomboxAudio.PlayOneShot(stopAudios[Random.Range(0, stopAudios.Length)]);
				}
				timesPlayedWithoutTurningOff = 0;
			}
			base.isBeingUsed = startMusic;
			isPlayingMusic = startMusic;
		}

		private IEnumerator musicPitchDown()
		{
			for (int i = 0; i < 30; i++)
			{
				yield return null;
				AudioSource obj = boomboxAudio;
				obj.pitch -= 0.033f;
				if (boomboxAudio.pitch <= 0f)
				{
					break;
				}
			}
			boomboxAudio.Stop();
			boomboxAudio.PlayOneShot(stopAudios[Random.Range(0, stopAudios.Length)]);
		}

		public override void UseUpBatteries()
		{
			((GrabbableObject)this).UseUpBatteries();
			StartMusic(startMusic: false, pitchDown: true);
		}

		public override void PocketItem()
		{
			((GrabbableObject)this).PocketItem();
			StartMusic(startMusic: false);
		}

		public override void Update()
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			((GrabbableObject)this).Update();
			if (isPlayingMusic)
			{
				if (noiseInterval <= 0f)
				{
					noiseInterval = 1f;
					timesPlayedWithoutTurningOff++;
					roundManager.PlayAudibleNoise(((Component)this).transform.position, 16f, 0.9f, timesPlayedWithoutTurningOff, false, 5);
				}
				else
				{
					noiseInterval -= Time.deltaTime;
				}
				if (base.insertedBattery.charge < 0.05f)
				{
					boomboxAudio.pitch = 1f - (0.05f - base.insertedBattery.charge) * 4f;
				}
			}
		}

		protected override void __initializeVariables()
		{
			((GrabbableObject)this).__initializeVariables();
		}

		protected override string __getTypeName()
		{
			return "TouhouBoomboxItem";
		}
	}
	[BepInPlugin("ImoutoSama.PersonalBoombox", "Personal Boombox", "1.0.0")]
	[BepInProcess("Lethal Company.exe")]
	public class PersonalBoomboxPlugin : BaseUnityPlugin
	{
		public class PBData
		{
			public string path;

			public string name;

			public string prefixName;

			public string boomboxName;

			public string description;

			public int price;

			public float volume;

			public Color color;

			public GameObject prefab;

			public PersonalBoomboxItem script;

			public Item item;

			public int itemIndex;

			public bool addedToTerminalKeyword;

			public bool IsFinished => Object.op_Implicit((Object)(object)script) && script.finishedLoading;

			public bool IsValid => Object.op_Implicit((Object)(object)script) && script.AudioClipCount > 0;
		}

		private const string modGUID = "ImoutoSama.PersonalBoombox";

		private const string modName = "Personal Boombox";

		private const string modVersion = "1.0.0";

		private readonly Harmony harmony = new Harmony("ImoutoSama.PersonalBoombox");

		internal ManualLogSource logger;

		public static List<PBData> data;

		public static List<string> paths;

		public ConfigEntry<int> maxVolumeConfig;

		public float maxVolumeValue;

		public static PersonalBoomboxPlugin Instance { get; private set; }

		private void Awake()
		{
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = this;
			}
			logger = Logger.CreateLogSource("ImoutoSama.PersonalBoombox");
			logger.LogInfo((object)"Plugin Personal Boombox has been added!");
			maxVolumeConfig = ConfigBindClamp("General", "Max Volume", 100, "Max possible volume value. From 0 to 100.", 0, 100);
			maxVolumeValue = (float)maxVolumeConfig.Value * 0.01f;
			harmony.PatchAll(typeof(TerminalPatch));
			harmony.PatchAll(typeof(StartOfRoundPatch));
			harmony.PatchAll(typeof(GameNetworkManagerPatch));
			harmony.PatchAll(typeof(MenuManagerPatch));
			data = new List<PBData>();
			paths = new List<string>();
			Assets.LoadAssetBundle();
			AddFromAssemblyDll(Assembly.GetExecutingAssembly().Location);
		}

		public ConfigEntry<int> ConfigBindClamp(string section, string key, int defaultValue, string description, int min, int max)
		{
			ConfigEntry<int> val = ((BaseUnityPlugin)this).Config.Bind<int>(section, key, defaultValue, description);
			val.Value = Mathf.Clamp(val.Value, min, max);
			return val;
		}

		public static void AddFromAssemblyDll(string dllPath)
		{
			paths.Add(Path.GetDirectoryName(dllPath));
		}

		public static void AddDirectory(string path)
		{
			paths.Add(path);
		}
	}
	public class MyOwnCoroutine : MonoBehaviour
	{
		public static MyOwnCoroutine Instance { get; private set; }

		public static Coroutine AddCoroutine(IEnumerator c)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			if ((Object)(object)Instance == (Object)null)
			{
				GameObject val = new GameObject("My Own Coroutine");
				Instance = val.AddComponent<MyOwnCoroutine>();
				Object.DontDestroyOnLoad((Object)(object)val);
			}
			return ((MonoBehaviour)Instance).StartCoroutine(c);
		}
	}
}
namespace PersonalBoombox.Patches
{
	[HarmonyPatch(typeof(GameNetworkManager))]
	internal class GameNetworkManagerPatch
	{
		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		public static void StartPatch(ref GameNetworkManager __instance)
		{
			PersonalBoomboxPlugin.Instance.logger.LogInfo((object)"Adding personal boomboxes to network list");
			NetworkManager component = ((Component)__instance).GetComponent<NetworkManager>();
			foreach (PersonalBoomboxPlugin.PBData datum in PersonalBoomboxPlugin.data)
			{
				component.AddNetworkPrefab(datum.prefab);
			}
		}
	}
	[HarmonyPatch(typeof(ItemDropship))]
	internal class ItemDropshipPatch
	{
		private static void EnableBoombox(GameObject target)
		{
			PersonalBoomboxItem component = target.GetComponent<PersonalBoomboxItem>();
			if ((Object)(object)component != (Object)null)
			{
				((Component)component).gameObject.SetActive(true);
			}
		}

		[HarmonyPatch("OpenShipDoorsOnServer")]
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			bool found = false;
			int i = 0;
			foreach (CodeInstruction instruction in instructions)
			{
				if (instruction.opcode == OpCodes.Call)
				{
					i = 1;
				}
				else if (instruction.opcode == OpCodes.Dup && i == 1)
				{
					i = 2;
				}
				else if (instruction.opcode == OpCodes.Callvirt && i == 2)
				{
					MethodInfo method = typeof(ItemDropshipPatch).GetMethod("EnableBoombox", BindingFlags.Static | BindingFlags.NonPublic);
					yield return new CodeInstruction(OpCodes.Dup, (object)null);
					yield return new CodeInstruction(OpCodes.Call, (object)method);
					found = true;
					i = 0;
				}
				else
				{
					i = 0;
				}
				yield return instruction;
			}
			if (object.Equals(false, found))
			{
				PersonalBoomboxPlugin.Instance.logger.LogError((object)"Cannot find <Stdfld someField> in OriginalType.OriginalMethod");
			}
		}
	}
	[HarmonyPatch(typeof(MenuManager))]
	internal class MenuManagerPatch
	{
		public static bool done;

		[HarmonyPatch("Awake")]
		[HarmonyPostfix]
		private static void AwakePatch()
		{
			if (!done)
			{
				done = true;
				Assets.LoadMusicFolders();
			}
		}
	}
	[HarmonyPatch(typeof(StartOfRound))]
	internal class StartOfRoundPatch
	{
		public static bool done;

		[HarmonyPatch("Start")]
		[HarmonyPrefix]
		public static void StartPatch(ref StartOfRound __instance)
		{
			if (done)
			{
				return;
			}
			done = true;
			PersonalBoomboxPlugin.Instance.logger.LogInfo((object)"Adding personal boomboxes to items list");
			foreach (PersonalBoomboxPlugin.PBData datum in PersonalBoomboxPlugin.data)
			{
				bool isFinished = datum.IsFinished;
				bool isValid = datum.IsValid;
				if (datum.IsFinished && datum.IsValid)
				{
					__instance.allItemsList.itemsList.Add(datum.item);
				}
			}
		}
	}
	[HarmonyPatch(typeof(Terminal))]
	internal class TerminalPatch
	{
		public static Item boomboxItem;

		public static GameObject boomboxPrefab;

		public static MeshFilter boomboxMeshFilter;

		public static MeshRenderer boomboxMeshRenderer;

		public static AudioSource boomboxAudioSource;

		public static BoomboxItem boomboxScript;

		public static TerminalKeyword buyKeyword;

		public static TerminalKeyword infoKeyword;

		public static CompatibleNoun buyNoun;

		public static CompatibleNoun infoNoun;

		[HarmonyPatch("Awake")]
		[HarmonyPostfix]
		private static void AwakePatch(ref Terminal __instance)
		{
			foreach (PersonalBoomboxPlugin.PBData datum in PersonalBoomboxPlugin.data)
			{
				bool isFinished = datum.IsFinished;
				bool isValid = datum.IsValid;
				if (datum.IsFinished && datum.IsValid)
				{
					AddToTerminal(ref __instance, datum);
					continue;
				}
				if (!datum.IsFinished)
				{
					PersonalBoomboxPlugin.Instance.logger.LogError((object)(datum.boomboxName + " has no script initialized or it is not done loading music"));
				}
				if (!datum.IsValid)
				{
					PersonalBoomboxPlugin.Instance.logger.LogError((object)(datum.boomboxName + " has no script initialized or it has no loaded music"));
				}
			}
		}

		private static void AddToTerminal(ref Terminal __instance, PersonalBoomboxPlugin.PBData data)
		{
			PersonalBoomboxPlugin.Instance.logger.LogInfo((object)("Adding " + data.boomboxName + " to terminal"));
			if ((Object)(object)data.item == (Object)null)
			{
				SetupPrefab(ref __instance, data);
			}
			PersonalBoomboxPlugin.Instance.logger.LogInfo((object)("Loading " + data.boomboxName + " into buyable list"));
			List<Item> list = __instance.buyableItemsList.ToList();
			data.itemIndex = list.Count;
			list.Add(data.item);
			__instance.buyableItemsList = list.ToArray();
			if (!data.addedToTerminalKeyword)
			{
				AddToTerminalKeywords(ref __instance, data);
				data.addedToTerminalKeyword = true;
			}
		}

		private static void SetupPrefab(ref Terminal __instance, PersonalBoomboxPlugin.PBData data)
		{
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: 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_01d5: Expected O, but got Unknown
			PersonalBoomboxPlugin.Instance.logger.LogInfo((object)("Setting up " + data.boomboxName + " prefab"));
			if ((Object)(object)boomboxItem == (Object)null)
			{
				InitializePrefab(ref __instance);
			}
			Item val = Object.Instantiate<Item>(boomboxItem);
			GameObject prefab = data.prefab;
			PersonalBoomboxItem script = data.script;
			val.creditsWorth = data.price;
			val.spawnPrefab = prefab;
			val.itemName = data.boomboxName;
			data.item = val;
			prefab.tag = boomboxPrefab.tag;
			prefab.layer = boomboxPrefab.layer;
			MeshFilter component = prefab.GetComponent<MeshFilter>();
			component.mesh = boomboxMeshFilter.mesh;
			MeshRenderer component2 = prefab.GetComponent<MeshRenderer>();
			((Renderer)component2).materials = ((Renderer)boomboxMeshRenderer).materials;
			((Renderer)component2).materials[3].color = data.color;
			((Renderer)component2).materials[1].color = DarkenColor(data.color);
			AudioSource component3 = prefab.GetComponent<AudioSource>();
			component3.volume = data.volume;
			component3.outputAudioMixerGroup = boomboxAudioSource.outputAudioMixerGroup;
			component3.SetCustomCurve((AudioSourceCurveType)0, boomboxAudioSource.GetCustomCurve((AudioSourceCurveType)0));
			component3.SetCustomCurve((AudioSourceCurveType)1, boomboxAudioSource.GetCustomCurve((AudioSourceCurveType)1));
			component3.SetCustomCurve((AudioSourceCurveType)3, boomboxAudioSource.GetCustomCurve((AudioSourceCurveType)3));
			component3.SetCustomCurve((AudioSourceCurveType)2, boomboxAudioSource.GetCustomCurve((AudioSourceCurveType)2));
			((GrabbableObject)script).grabbable = true;
			((GrabbableObject)script).isInFactory = true;
			((GrabbableObject)script).grabbableToEnemies = true;
			((GrabbableObject)script).propColliders = ((Component)script).GetComponents<Collider>();
			((GrabbableObject)script).mainObjectRenderer = component2;
			script.boomboxAudio = component3;
			script.stopAudios = boomboxScript.stopAudios;
			((GrabbableObject)script).insertedBattery = new Battery(false, ((GrabbableObject)boomboxScript).insertedBattery.charge);
			((GrabbableObject)script).itemProperties = val;
			static Color DarkenColor(Color c)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_000d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0019: Unknown result type (might be due to invalid IL or missing references)
				//IL_002a: Unknown result type (might be due to invalid IL or missing references)
				//IL_002f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0032: Unknown result type (might be due to invalid IL or missing references)
				return new Color(c.r * 0.9f, c.g * 0.9f, c.b * 0.9f, 1f);
			}
		}

		private static void InitializePrefab(ref Terminal __instance)
		{
			PersonalBoomboxPlugin.Instance.logger.LogInfo((object)"First time setting up boombox prefab. Grabbing boombox prefab to copy from");
			List<Item> list = __instance.buyableItemsList.ToList();
			int num = -1;
			for (int i = 0; i < list.Count; i++)
			{
				Item val = list[i];
				if (val.itemName.ToLowerInvariant() == "boombox")
				{
					num = i;
					break;
				}
			}
			if (num == -1)
			{
				PersonalBoomboxPlugin.Instance.logger.LogError((object)"Items has no boomerbox item to copy from");
				return;
			}
			boomboxItem = list[num];
			boomboxPrefab = boomboxItem.spawnPrefab;
			boomboxMeshFilter = boomboxPrefab.GetComponent<MeshFilter>();
			boomboxMeshRenderer = boomboxPrefab.GetComponent<MeshRenderer>();
			boomboxAudioSource = boomboxPrefab.GetComponent<AudioSource>();
			boomboxScript = boomboxPrefab.GetComponent<BoomboxItem>();
		}

		private static void AddToTerminalKeywords(ref Terminal __instance, PersonalBoomboxPlugin.PBData data)
		{
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Expected O, but got Unknown
			PersonalBoomboxPlugin.Instance.logger.LogInfo((object)("Adding buy/info function to " + data.boomboxName));
			if ((Object)(object)buyKeyword == (Object)null)
			{
				InitializeKeyword(ref __instance);
			}
			string word = data.boomboxName.ToLowerInvariant();
			string boomboxName = data.boomboxName;
			CompatibleNoun val = CopyNoun(buyNoun);
			TerminalKeyword noun = val.noun;
			noun.word = word;
			TerminalNode result = val.result;
			result.buyItemIndex = data.itemIndex;
			result.displayText = result.displayText.Replace("boom boxes", boomboxName + "es");
			result.terminalOptions = CopyNouns(result.terminalOptions);
			TerminalNode val2 = FindNodeWithConfirm(result.terminalOptions);
			val2.buyItemIndex = data.itemIndex;
			val2.displayText = val2.displayText.Replace("boom boxes", boomboxName + "es");
			List<CompatibleNoun> list = buyKeyword.compatibleNouns.ToList();
			List<CompatibleNoun> list2 = infoKeyword.compatibleNouns.ToList();
			List<TerminalKeyword> list3 = __instance.terminalNodes.allKeywords.ToList();
			list.Add(val);
			buyKeyword.compatibleNouns = list.ToArray();
			CompatibleNoun val3 = new CompatibleNoun();
			val3.noun = val.noun;
			val3.result = CopyTerminalNode(infoNoun.result);
			val3.result.displayText = "\n" + data.description + "\n\n";
			list2.Add(val3);
			infoKeyword.compatibleNouns = list2.ToArray();
			list3.Add(noun);
			__instance.terminalNodes.allKeywords = list3.ToArray();
		}

		private static void InitializeKeyword(ref Terminal __instance)
		{
			PersonalBoomboxPlugin.Instance.logger.LogInfo((object)"First time adding keywords to terminal. Grabbing some values to copy from");
			TerminalKeyword[] allKeywords = __instance.terminalNodes.allKeywords;
			buyKeyword = ((IEnumerable<TerminalKeyword>)allKeywords).FirstOrDefault((Func<TerminalKeyword, bool>)((TerminalKeyword a) => a.word == "buy"));
			infoKeyword = ((IEnumerable<TerminalKeyword>)allKeywords).FirstOrDefault((Func<TerminalKeyword, bool>)((TerminalKeyword a) => a.word == "info"));
			buyNoun = buyKeyword.compatibleNouns.First((CompatibleNoun b) => b.noun.word == "boombox");
			infoNoun = infoKeyword.compatibleNouns.First((CompatibleNoun b) => b.noun.word == "boombox");
		}

		private static TerminalKeyword CopyTerminalKeyword(TerminalKeyword target)
		{
			return Object.Instantiate<TerminalKeyword>(target);
		}

		private static TerminalNode CopyTerminalNode(TerminalNode target)
		{
			return Object.Instantiate<TerminalNode>(target);
		}

		private static CompatibleNoun CopyNoun(CompatibleNoun target)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			CompatibleNoun val = new CompatibleNoun();
			val.noun = CopyTerminalKeyword(target.noun);
			val.result = CopyTerminalNode(target.result);
			return val;
		}

		private static CompatibleNoun[] CopyNouns(CompatibleNoun[] target)
		{
			CompatibleNoun[] array = (CompatibleNoun[])(object)new CompatibleNoun[target.Length];
			for (int i = 0; i < target.Length; i++)
			{
				array[i] = CopyNoun(target[i]);
			}
			return array;
		}

		private static TerminalNode FindNodeWithConfirm(CompatibleNoun[] nouns)
		{
			foreach (CompatibleNoun val in nouns)
			{
				if (val.noun.word.ToLowerInvariant() == "confirm")
				{
					return val.result;
				}
			}
			return null;
		}
	}
}