Decompiled source of Megaphone v1.1.0

plugins/OvrSlepr_Megaphone.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Peak;
using Photon.Pun;
using Photon.Voice;
using Photon.Voice.Unity;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("OvrSlepr_Megaphone")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("OvrSlepr_Megaphone")]
[assembly: AssemblyTitle("OvrSlepr_Megaphone")]
[assembly: AssemblyVersion("1.0.0.0")]
[BepInPlugin("OvrSlepr.Megaphone", "Megaphone", "1.1.0")]
public class MegaphonePlugin : BaseUnityPlugin
{
	public static ConfigEntry<bool> EnableVoiceIndicator;

	public static ConfigEntry<int> IndicatorBars;

	public static ConfigEntry<float> VoiceVolumeMultiplier;

	public static ConfigEntry<bool> EnableAudioEffects;

	public static ConfigEntry<bool> EnableEcho;

	public static ConfigEntry<float> LowPassFrequency;

	public static ConfigEntry<float> HighPassFrequency;

	public static ConfigEntry<int> RegularLuggageWeight;

	public static ConfigEntry<int> TravelerLuggageWeight;

	public static ConfigEntry<int> ClownLuggageWeight;

	public static ConfigEntry<bool> DisableLuggageSpawnInSingleplayer;

	private void Awake()
	{
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: Expected O, but got Unknown
		//IL_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_008a: Expected O, but got Unknown
		//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0107: Expected O, but got Unknown
		//IL_013a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0144: Expected O, but got Unknown
		//IL_017f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0189: Expected O, but got Unknown
		//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bc: Expected O, but got Unknown
		//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ef: Expected O, but got Unknown
		//IL_0219: Unknown result type (might be due to invalid IL or missing references)
		EnableVoiceIndicator = ((BaseUnityPlugin)this).Config.Bind<bool>("Voice Indicator", "EnableVoiceIndicator", true, "Enable or disable the voice indicator.");
		IndicatorBars = ((BaseUnityPlugin)this).Config.Bind<int>("Voice Indicator", "IndicatorBars", 5, new ConfigDescription("Number of bars in the voice indicator (5-8).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(5, 8), Array.Empty<object>()));
		VoiceVolumeMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Voice", "VoiceVolumeMultiplier", 2f, new ConfigDescription("Voice volume multiplier while using the megaphone.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 5f), Array.Empty<object>()));
		EnableAudioEffects = ((BaseUnityPlugin)this).Config.Bind<bool>("Audio Effects", "EnableAudioEffects", true, "Enable or disable the megaphone audio filters.");
		EnableEcho = ((BaseUnityPlugin)this).Config.Bind<bool>("Audio Effects", "EnableEcho", true, "Enable or disable the megaphone echo.");
		LowPassFrequency = ((BaseUnityPlugin)this).Config.Bind<float>("Audio Effects", "LowPassFrequency", 2800f, new ConfigDescription("Low-pass filter frequency in Hz.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(500f, 10000f), Array.Empty<object>()));
		HighPassFrequency = ((BaseUnityPlugin)this).Config.Bind<float>("Audio Effects", "HighPassFrequency", 450f, new ConfigDescription("High-pass filter frequency in Hz.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(50f, 2000f), Array.Empty<object>()));
		SceneManager.sceneLoaded += OnSceneLoaded;
		RegularLuggageWeight = ((BaseUnityPlugin)this).Config.Bind<int>("Luggage Loot", "RegularLuggageWeight", 13, new ConfigDescription("Spawn weight for regular luggage.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
		TravelerLuggageWeight = ((BaseUnityPlugin)this).Config.Bind<int>("Luggage Loot", "TravelerLuggageWeight", 10, new ConfigDescription("Spawn weight for traveler's luggage.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
		ClownLuggageWeight = ((BaseUnityPlugin)this).Config.Bind<int>("Luggage Loot", "ClownLuggageWeight", 15, new ConfigDescription("Spawn weight for clown luggage.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
		DisableLuggageSpawnInSingleplayer = ((BaseUnityPlugin)this).Config.Bind<bool>("Luggage Loot", "DisableLuggageSpawnInSingleplayer", true, "Prevent the megaphone from spawning in luggage during singleplayer runs.");
		new Harmony("OvrSlepr.Megaphone").PatchAll();
		((BaseUnityPlugin)this).Logger.LogInfo((object)"Megaphone mod loaded!");
		try
		{
			Item val = default(Item);
			bool flag = ItemDatabase.TryGetItem((ushort)78, ref val);
			((BaseUnityPlugin)this).Logger.LogInfo((object)("Megaphone ID 78 found: " + flag));
			Item val2 = default(Item);
			bool flag2 = ItemDatabase.TryGetItem("Megaphone", ref val2);
			((BaseUnityPlugin)this).Logger.LogInfo((object)("Megaphone name found: " + flag2));
			if (flag && (Object)(object)val != (Object)null)
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)("Megaphone object: " + ((Object)((Component)val).gameObject).name));
				((BaseUnityPlugin)this).Logger.LogInfo((object)("Megaphone active: " + ((Component)val).gameObject.activeSelf));
				((BaseUnityPlugin)this).Logger.LogInfo((object)("Megaphone prefab name: " + ((Object)((Component)val).gameObject).name));
				((BaseUnityPlugin)this).Logger.LogInfo((object)("Megaphone item ID: " + val.itemID));
			}
		}
		catch (Exception ex)
		{
			((BaseUnityPlugin)this).Logger.LogError((object)("Megaphone check failed: " + ex));
		}
		((Component)this).gameObject.AddComponent<MegaphoneVoiceIndicator>();
		try
		{
			Item val3 = default(Item);
			bool flag3 = ItemDatabase.TryGetItem("Dynamite", ref val3);
			((BaseUnityPlugin)this).Logger.LogInfo((object)("[Megaphone] Dynamite found: " + flag3));
			if (flag3 && (Object)(object)val3 != (Object)null)
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)("[Megaphone] Dynamite object: " + ((Object)((Component)val3).gameObject).name));
				Dynamite component = ((Component)val3).GetComponent<Dynamite>();
				((BaseUnityPlugin)this).Logger.LogInfo((object)("[Megaphone] Dynamite component found: " + ((Object)(object)component != (Object)null)));
				if ((Object)(object)component != (Object)null)
				{
					((BaseUnityPlugin)this).Logger.LogInfo((object)("[Megaphone] Explosion prefab: " + (((Object)(object)component.explosionPrefab != (Object)null) ? ((Object)component.explosionPrefab).name : "NULL")));
				}
			}
		}
		catch (Exception ex2)
		{
			((BaseUnityPlugin)this).Logger.LogError((object)("[Megaphone] Dynamite check failed: " + ex2));
		}
	}

	private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
	{
		MegaphonePlaneSpawnPatch.ResetSpawnFlag();
		((BaseUnityPlugin)this).Logger.LogInfo((object)("[Megaphone] Spawn flag reset: " + ((Scene)(ref scene)).name));
	}

	private void OnDestroy()
	{
		SceneManager.sceneLoaded -= OnSceneLoaded;
	}
}
public static class MegaphoneCookingAudio
{
	public static int GetCookedCount(GameObject target)
	{
		if ((Object)(object)target == (Object)null)
		{
			return 0;
		}
		ItemCooking val = target.GetComponent<ItemCooking>();
		if ((Object)(object)val == (Object)null)
		{
			val = target.GetComponentInChildren<ItemCooking>();
		}
		if ((Object)(object)val == (Object)null)
		{
			return 0;
		}
		return Mathf.Max(0, val.timesCookedLocal);
	}

	public static float GetVoicePitch(GameObject target)
	{
		int cookedCount = GetCookedCount(target);
		if (cookedCount >= 4)
		{
			return 0.47f;
		}
		return cookedCount switch
		{
			3 => 0.65f, 
			2 => 0.75f, 
			1 => 0.8f, 
			_ => 1f, 
		};
	}

	public static float GetDistortionAmount(GameObject target)
	{
		int cookedCount = GetCookedCount(target);
		return cookedCount switch
		{
			1 => 0.15f, 
			2 => 0.35f, 
			3 => 0.65f, 
			_ => (cookedCount >= 4) ? 0.9f : 0f, 
		};
	}

	public static float GetStutterChance(GameObject target)
	{
		int cookedCount = GetCookedCount(target);
		if (cookedCount >= 4)
		{
			return 0.45f;
		}
		if (cookedCount == 3)
		{
			return 0.2f;
		}
		return 0f;
	}
}
public class MegaphoneExplosionController : MonoBehaviour
{
	private Item item;

	private Coroutine holdCoroutine;

	private bool isHolding;

	private bool explosionTriggered;

	private bool damageApplied;

	private bool explosionHandled;

	private const float ExplosionDelay = 4.3f;

	private const float ExplosionRadius = 5f;

	private const float ExplosionInjury = 0.25f;

	private void Awake()
	{
		item = ((Component)this).GetComponent<Item>();
	}

	public void BeginHold()
	{
		if (!explosionTriggered && !isHolding)
		{
			isHolding = true;
			holdCoroutine = ((MonoBehaviour)this).StartCoroutine(CheckExplosionAfterDelay());
		}
	}

	public void CancelHold()
	{
		isHolding = false;
		if (holdCoroutine != null)
		{
			((MonoBehaviour)this).StopCoroutine(holdCoroutine);
			holdCoroutine = null;
		}
	}

	private IEnumerator CheckExplosionAfterDelay()
	{
		yield return (object)new WaitForSeconds(4.3f);
		holdCoroutine = null;
		if (!isHolding || explosionTriggered || (Object)(object)item == (Object)null || (Object)(object)((MonoBehaviourPun)item).photonView == (Object)null || !((MonoBehaviourPun)item).photonView.IsMine)
		{
			yield break;
		}
		int cookedCount = MegaphoneCookingAudio.GetCookedCount(((Component)this).gameObject);
		float chance = 0f;
		if (cookedCount >= 4)
		{
			chance = 0.45f;
		}
		else
		{
			switch (cookedCount)
			{
			case 3:
				chance = 0.2f;
				break;
			case 2:
				chance = 0.03f;
				break;
			}
		}
		Debug.Log((object)("[Megaphone] Held for " + 4.3f + " seconds. Stage: " + cookedCount + ", explosion chance: " + chance * 100f + "%"));
		if (!(chance <= 0f) && !(Random.value >= chance))
		{
			explosionTriggered = true;
			isHolding = false;
			MegaphoneNetworkController networkController = ((Component)this).GetComponent<MegaphoneNetworkController>();
			if ((Object)(object)networkController == (Object)null)
			{
				Debug.LogError((object)"[Megaphone] Network controller not found.");
				yield break;
			}
			networkController.StopMegaphoneVoice();
			networkController.RequestMegaphoneExplosion(((Component)this).transform.position, ((Component)this).transform.rotation);
		}
	}

	public void HandleNetworkExplosion(Vector3 explosionPosition, Quaternion explosionRotation)
	{
		//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_003d: 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)
		if (explosionHandled)
		{
			return;
		}
		explosionHandled = true;
		if ((Object)(object)item == (Object)null)
		{
			item = ((Component)this).GetComponent<Item>();
		}
		SpawnExplosionEffect(explosionPosition, explosionRotation);
		ApplyExplosionDamage(explosionPosition, 5f);
		if ((Object)(object)item != (Object)null && (Object)(object)((MonoBehaviourPun)item).photonView != (Object)null && ((MonoBehaviourPun)item).photonView.IsMine)
		{
			Character holderCharacter = item.holderCharacter;
			if ((Object)(object)holderCharacter != (Object)null && holderCharacter.IsLocal && (Object)(object)holderCharacter.data != (Object)null && (Object)(object)holderCharacter.data.currentItem == (Object)(object)item)
			{
				Player.localPlayer.EmptySlot(holderCharacter.refs.items.currentSelectedSlot, true);
			}
			item.ClearDataFromBackpack();
			PhotonNetwork.Destroy(((Component)this).gameObject);
		}
	}

	private unsafe void SpawnExplosionEffect(Vector3 position, Quaternion rotation)
	{
		//IL_0048: 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)
		Item val = default(Item);
		if (ItemDatabase.TryGetItem("Dynamite", ref val) && (Object)(object)val != (Object)null)
		{
			Dynamite component = ((Component)val).GetComponent<Dynamite>();
			if ((Object)(object)component != (Object)null && (Object)(object)component.explosionPrefab != (Object)null)
			{
				Object.Instantiate<GameObject>(component.explosionPrefab, position, rotation);
				Debug.Log((object)("[Megaphone] Explosion effect spawned at " + ((object)(*(Vector3*)(&position))/*cast due to .constrained prefix*/).ToString()));
				return;
			}
		}
		Debug.LogError((object)"[Megaphone] Could not find the Dynamite explosion prefab.");
	}

	private void ApplyExplosionDamage(Vector3 explosionPosition, float radius)
	{
		//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)
		if (damageApplied)
		{
			return;
		}
		damageApplied = true;
		List<Character> allPlayerCharacters = PlayerHandler.GetAllPlayerCharacters();
		if (allPlayerCharacters == null)
		{
			Debug.LogError((object)"[Megaphone] Character list is null.");
			return;
		}
		foreach (Character item in allPlayerCharacters)
		{
			if (!((Object)(object)item == (Object)null) && !((Object)(object)((MonoBehaviourPun)item).photonView == (Object)null) && ((MonoBehaviourPun)item).photonView.IsMine && !((Object)(object)item.data == (Object)null) && !item.data.dead && item.refs != null && !((Object)(object)item.refs.afflictions == (Object)null))
			{
				float num = Vector3.Distance(item.Center, explosionPosition);
				if (!(num > radius))
				{
					CharacterAfflictions afflictions = item.refs.afflictions;
					float currentStatus = afflictions.GetCurrentStatus((STATUSTYPE)0);
					bool flag = afflictions.AddStatus((STATUSTYPE)0, 0.25f, false, true, true, true, false);
					float currentStatus2 = afflictions.GetCurrentStatus((STATUSTYPE)0);
					Debug.Log((object)("[Megaphone] Injury result: distance=" + num + ", applied=" + flag + ", before=" + currentStatus + ", after=" + currentStatus2));
				}
			}
		}
	}
}
[HarmonyPatch(typeof(LootData), "PopulateLootData")]
public static class MegaphoneLuggageLootPatch
{
	private const ushort MegaphoneItemID = 78;

	private static readonly string[] RegularLuggagePools = new string[8] { "LuggageBeach", "LuggageJungle", "LuggageRoots", "LuggageTundra", "LuggageMesa", "LuggageCaldera", "LuggageGloom", "LuggageCitadel" };

	private static void Postfix()
	{
		if (!MegaphonePlugin.DisableLuggageSpawnInSingleplayer.Value || !PhotonNetwork.OfflineMode)
		{
			Dictionary<SpawnPool, Dictionary<ushort, int>> allSpawnWeightData = LootData.AllSpawnWeightData;
			if (allSpawnWeightData == null)
			{
				Debug.LogError((object)"[Megaphone] Loot tables are not available!");
				return;
			}
			SetWeight(allSpawnWeightData, RegularLuggagePools, MegaphonePlugin.RegularLuggageWeight.Value);
			SetWeight(allSpawnWeightData, new string[1] { "LuggageClimber" }, MegaphonePlugin.TravelerLuggageWeight.Value);
			SetWeight(allSpawnWeightData, new string[1] { "LuggageClown" }, MegaphonePlugin.ClownLuggageWeight.Value);
		}
	}

	private static void SetWeight(Dictionary<SpawnPool, Dictionary<ushort, int>> allPools, string[] poolNames, int weight)
	{
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		foreach (string text in poolNames)
		{
			if (!Enum.TryParse<SpawnPool>(text, out SpawnPool result))
			{
				Debug.LogWarning((object)("[Megaphone] Unknown loot pool: " + text));
				continue;
			}
			if (!allPools.TryGetValue(result, out var value) || value == null)
			{
				Debug.LogWarning((object)("[Megaphone] Loot pool not found: " + text));
				continue;
			}
			if (weight <= 0)
			{
				value.Remove(78);
			}
			else
			{
				value[78] = weight;
			}
			Debug.Log((object)("[Megaphone] " + text + ": megaphone weight = " + weight));
		}
	}
}
public class MegaphoneNetworkController : MonoBehaviour
{
	private Item item;

	private int activeCharacterViewID = -1;

	private bool isMegaphoneActive;

	private float nextToggleTime;

	private const float ToggleCooldown = 0.15f;

	private const float MegaphoneMaxDistance = 1000f;

	private Character overriddenCharacter;

	private VoiceObscuranceFilter voiceFilter;

	private AudioSource voiceSource;

	private Transform audioPoint;

	private Camera cachedListenerCamera;

	private float nextCameraCheckTime;

	private const float CameraCheckInterval = 1f;

	private bool originalFilterStateSaved;

	private bool originalEchoEnabled;

	private float originalEchoWetMix;

	private float originalEchoDryMix;

	private float originalEchoDecayRatio;

	private float originalEchoDelay;

	private bool originalLowPassEnabled;

	private bool originalHighPassEnabled;

	private float originalLowPassCutoff;

	private float originalHighPassCutoff;

	private bool originalAudioSourceStateSaved;

	private float originalMinDistance;

	private float originalMaxDistance;

	private AudioRolloffMode originalRolloffMode;

	private float originalVolume;

	private float originalPitch;

	public static MegaphoneNetworkController ActiveController { get; private set; }

	private void Awake()
	{
		item = ((Component)this).GetComponent<Item>();
		audioPoint = ((Component)this).transform.Find("MegaphoneAudioPoint");
		PhotonView component = ((Component)this).GetComponent<PhotonView>();
		if ((Object)(object)component != (Object)null)
		{
			component.RefreshRpcMonoBehaviourCache();
		}
	}

	private float GetVolumeMultiplier()
	{
		if (MegaphonePlugin.VoiceVolumeMultiplier == null)
		{
			return 2f;
		}
		return MegaphonePlugin.VoiceVolumeMultiplier.Value;
	}

	private bool AreAudioEffectsEnabled()
	{
		return MegaphonePlugin.EnableAudioEffects == null || MegaphonePlugin.EnableAudioEffects.Value;
	}

	private bool IsEchoEnabled()
	{
		return MegaphonePlugin.EnableEcho == null || MegaphonePlugin.EnableEcho.Value;
	}

	private float GetLowPassFrequency()
	{
		return (MegaphonePlugin.LowPassFrequency != null) ? MegaphonePlugin.LowPassFrequency.Value : 2800f;
	}

	private float GetHighPassFrequency()
	{
		return (MegaphonePlugin.HighPassFrequency != null) ? MegaphonePlugin.HighPassFrequency.Value : 450f;
	}

	private void SaveOriginalAudioSourceSettings()
	{
		//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)
		if (!((Object)(object)voiceSource == (Object)null) && !originalAudioSourceStateSaved)
		{
			originalMinDistance = voiceSource.minDistance;
			originalMaxDistance = voiceSource.maxDistance;
			originalRolloffMode = voiceSource.rolloffMode;
			originalVolume = voiceSource.volume;
			originalPitch = voiceSource.pitch;
			originalAudioSourceStateSaved = true;
		}
	}

	private void ApplyMegaphoneDistance()
	{
		if (!((Object)(object)voiceSource == (Object)null))
		{
			voiceSource.minDistance = 10f;
			voiceSource.maxDistance = 1000f;
			voiceSource.rolloffMode = (AudioRolloffMode)1;
			voiceSource.volume = originalVolume * GetVolumeMultiplier();
		}
	}

	private void RestoreOriginalAudioSourceSettings()
	{
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)voiceSource == (Object)null) && originalAudioSourceStateSaved)
		{
			voiceSource.minDistance = originalMinDistance;
			voiceSource.maxDistance = originalMaxDistance;
			voiceSource.rolloffMode = originalRolloffMode;
			voiceSource.volume = originalVolume;
			voiceSource.pitch = originalPitch;
			originalAudioSourceStateSaved = false;
			Debug.Log((object)"[Megaphone] Original AudioSource settings restored");
		}
	}

	private void SaveOriginalEchoSettings()
	{
		if (!((Object)(object)voiceFilter == (Object)null) && !((Object)(object)voiceFilter.echo == (Object)null) && !((Object)(object)voiceFilter.lowPass == (Object)null) && !((Object)(object)voiceFilter.highPass == (Object)null) && !originalFilterStateSaved)
		{
			originalEchoEnabled = ((Behaviour)voiceFilter.echo).enabled;
			originalEchoWetMix = voiceFilter.echo.wetMix;
			originalEchoDryMix = voiceFilter.echo.dryMix;
			originalEchoDecayRatio = voiceFilter.echo.decayRatio;
			originalEchoDelay = voiceFilter.echo.delay;
			originalLowPassEnabled = ((Behaviour)voiceFilter.lowPass).enabled;
			originalHighPassEnabled = ((Behaviour)voiceFilter.highPass).enabled;
			originalLowPassCutoff = voiceFilter.lowPass.cutoffFrequency;
			originalHighPassCutoff = voiceFilter.highPass.cutoffFrequency;
			originalFilterStateSaved = true;
		}
	}

	private void RestoreOriginalEchoSettings()
	{
		if (!((Object)(object)voiceFilter == (Object)null) && !((Object)(object)voiceFilter.echo == (Object)null) && !((Object)(object)voiceFilter.lowPass == (Object)null) && !((Object)(object)voiceFilter.highPass == (Object)null) && originalFilterStateSaved)
		{
			voiceFilter.echo.wetMix = originalEchoWetMix;
			voiceFilter.echo.dryMix = originalEchoDryMix;
			voiceFilter.echo.decayRatio = originalEchoDecayRatio;
			voiceFilter.echo.delay = originalEchoDelay;
			((Behaviour)voiceFilter.echo).enabled = originalEchoEnabled;
			((Behaviour)voiceFilter.lowPass).enabled = originalLowPassEnabled;
			((Behaviour)voiceFilter.highPass).enabled = originalHighPassEnabled;
			voiceFilter.lowPass.cutoffFrequency = originalLowPassCutoff;
			voiceFilter.highPass.cutoffFrequency = originalHighPassCutoff;
			originalFilterStateSaved = false;
			Debug.Log((object)"[Megaphone] Original audio filter settings restored");
		}
	}

	private void UpdateMegaphoneEcho(float distance)
	{
		if ((Object)(object)voiceFilter == (Object)null || (Object)(object)voiceFilter.echo == (Object)null || (Object)(object)voiceFilter.lowPass == (Object)null || (Object)(object)voiceFilter.highPass == (Object)null)
		{
			return;
		}
		if (!AreAudioEffectsEnabled())
		{
			((Behaviour)voiceFilter.echo).enabled = false;
			((Behaviour)voiceFilter.lowPass).enabled = false;
			((Behaviour)voiceFilter.highPass).enabled = false;
			return;
		}
		((Behaviour)voiceFilter.lowPass).enabled = true;
		voiceFilter.lowPass.cutoffFrequency = GetLowPassFrequency();
		((Behaviour)voiceFilter.highPass).enabled = true;
		voiceFilter.highPass.cutoffFrequency = GetHighPassFrequency();
		if (!IsEchoEnabled())
		{
			((Behaviour)voiceFilter.echo).enabled = false;
			return;
		}
		float num = Mathf.InverseLerp(10f, 1000f, distance);
		((Behaviour)voiceFilter.echo).enabled = true;
		voiceFilter.echo.wetMix = Mathf.Lerp(0.2f, 0.65f, num);
		voiceFilter.echo.dryMix = Mathf.Lerp(1f, 0.55f, num);
		voiceFilter.echo.decayRatio = Mathf.Lerp(0.3f, 0.65f, num);
		voiceFilter.echo.delay = Mathf.Lerp(150f, 450f, num);
	}

	public void ApplyMegaphoneAudio(VoiceObscuranceFilter sourceFilter)
	{
		//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)voiceFilter == (Object)null) && !((Object)(object)sourceFilter != (Object)(object)voiceFilter) && isMegaphoneActive && !((Object)(object)overriddenCharacter == (Object)null))
		{
			if ((Object)(object)voiceSource != (Object)null)
			{
				float voicePitch = MegaphoneCookingAudio.GetVoicePitch(((Component)this).gameObject);
				voiceSource.pitch = voicePitch;
			}
			if (Time.unscaledTime >= nextCameraCheckTime || (Object)(object)cachedListenerCamera == (Object)null)
			{
				cachedListenerCamera = Camera.main;
				nextCameraCheckTime = Time.unscaledTime + 1f;
			}
			if (!((Object)(object)cachedListenerCamera == (Object)null) && !((Object)(object)audioPoint == (Object)null))
			{
				float distance = Vector3.Distance(((Component)cachedListenerCamera).transform.position, audioPoint.position);
				UpdateMegaphoneEcho(distance);
			}
		}
	}

	public void SetMegaphoneVoice(bool enabled, int characterViewID)
	{
		if ((Object)(object)item == (Object)null || (Object)(object)((MonoBehaviourPun)item).photonView == (Object)null || enabled == isMegaphoneActive)
		{
			return;
		}
		if (enabled)
		{
			if (Time.unscaledTime < nextToggleTime)
			{
				return;
			}
			nextToggleTime = Time.unscaledTime + 0.15f;
			activeCharacterViewID = characterViewID;
		}
		else
		{
			if (activeCharacterViewID < 0)
			{
				return;
			}
			characterViewID = activeCharacterViewID;
			activeCharacterViewID = -1;
		}
		isMegaphoneActive = enabled;
		((MonoBehaviourPun)item).photonView.RPC("SetMegaphoneVoiceRPC", (RpcTarget)0, new object[2] { enabled, characterViewID });
	}

	public void RequestMegaphoneExplosion(Vector3 position, Quaternion rotation)
	{
		//IL_00a1: 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)
		if ((Object)(object)item == (Object)null)
		{
			item = ((Component)this).GetComponent<Item>();
		}
		if ((Object)(object)item == (Object)null || (Object)(object)((MonoBehaviourPun)item).photonView == (Object)null)
		{
			Debug.LogError((object)"[Megaphone] PhotonView not found.");
			return;
		}
		PhotonView photonView = ((MonoBehaviourPun)item).photonView;
		if (photonView.IsMine)
		{
			photonView.RefreshRpcMonoBehaviourCache();
			Debug.Log((object)("[Megaphone] Sending explosion RPC. ViewID=" + photonView.ViewID));
			photonView.RPC("RPC_MegaphoneExplosion", (RpcTarget)0, new object[2] { position, rotation });
		}
	}

	[PunRPC]
	private void RPC_MegaphoneExplosion(Vector3 position, Quaternion rotation)
	{
		//IL_0075: 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)
		PhotonView component = ((Component)this).GetComponent<PhotonView>();
		Debug.Log((object)("[Megaphone] Explosion RPC received. ViewID=" + (((Object)(object)component != (Object)null) ? component.ViewID : (-1)) + ", Actor=" + PhotonNetwork.LocalPlayer.ActorNumber));
		MegaphoneExplosionController megaphoneExplosionController = ((Component)this).GetComponent<MegaphoneExplosionController>();
		if ((Object)(object)megaphoneExplosionController == (Object)null)
		{
			megaphoneExplosionController = ((Component)this).gameObject.AddComponent<MegaphoneExplosionController>();
			Debug.Log((object)"[Megaphone] Explosion controller added on receiving client.");
		}
		megaphoneExplosionController.HandleNetworkExplosion(position, rotation);
	}

	public void StopMegaphoneVoice()
	{
		if (isMegaphoneActive && activeCharacterViewID >= 0)
		{
			SetMegaphoneVoice(enabled: false, activeCharacterViewID);
		}
	}

	[PunRPC]
	private void SetMegaphoneVoiceRPC(bool enabled, int characterViewID)
	{
		Debug.Log((object)$"[Megaphone] RPC: enabled={enabled}, characterViewID={characterViewID}");
		isMegaphoneActive = enabled;
		PhotonView val = PhotonView.Find(characterViewID);
		if ((Object)(object)val == (Object)null)
		{
			if (!enabled && (Object)(object)overriddenCharacter != (Object)null)
			{
				CharacterVoiceTransformProvider voicePositionProvider = overriddenCharacter.refs.voicePositionProvider;
				if ((Object)(object)voicePositionProvider != (Object)null && voicePositionProvider.HasOverride)
				{
					voicePositionProvider.SetOverride((Transform)null, false);
				}
				overriddenCharacter = null;
				if ((Object)(object)ActiveController == (Object)(object)this)
				{
					ActiveController = null;
				}
				RestoreOriginalAudioSourceSettings();
				RestoreOriginalEchoSettings();
			}
			return;
		}
		Character component = ((Component)val).GetComponent<Character>();
		if ((Object)(object)component == (Object)null || component.refs == null)
		{
			return;
		}
		CharacterVoiceTransformProvider voicePositionProvider2 = component.refs.voicePositionProvider;
		CharacterVoiceHandler voice = component.refs.voice;
		if ((Object)(object)voice != (Object)null)
		{
			voiceFilter = voice.voiceObscuranceFilter;
			voiceSource = ((Component)voice).GetComponent<AudioSource>();
			if ((Object)(object)voiceFilter == (Object)null || (Object)(object)voiceFilter.lowPass == (Object)null || (Object)(object)voiceFilter.highPass == (Object)null || (Object)(object)voiceFilter.echo == (Object)null || (Object)(object)voiceSource == (Object)null)
			{
				Debug.LogWarning((object)"[Megaphone] Voice source or audio filters are missing");
				return;
			}
			if (enabled)
			{
				SaveOriginalAudioSourceSettings();
				SaveOriginalEchoSettings();
				ApplyMegaphoneDistance();
			}
		}
		if ((Object)(object)voicePositionProvider2 == (Object)null)
		{
			return;
		}
		if (enabled)
		{
			overriddenCharacter = component;
			ActiveController = this;
			if ((Object)(object)audioPoint == (Object)null)
			{
				audioPoint = ((Component)this).transform.Find("MegaphoneAudioPoint");
			}
			if ((Object)(object)audioPoint != (Object)null)
			{
				voicePositionProvider2.SetOverride(audioPoint, true);
				Debug.Log((object)"[Megaphone] Voice position override set to megaphone");
			}
			else
			{
				Debug.LogWarning((object)"[Megaphone] Audio point not found");
			}
		}
		else if ((Object)(object)overriddenCharacter == (Object)(object)component)
		{
			if (voicePositionProvider2.HasOverride)
			{
				voicePositionProvider2.SetOverride((Transform)null, false);
				Debug.Log((object)"[Megaphone] Voice position override cleared");
			}
			overriddenCharacter = null;
			if ((Object)(object)ActiveController == (Object)(object)this)
			{
				ActiveController = null;
			}
			RestoreOriginalAudioSourceSettings();
			RestoreOriginalEchoSettings();
		}
	}
}
[HarmonyPatch(typeof(Item), "StartUsePrimary")]
public static class MegaphoneUsePatch
{
	private static void Postfix(Item __instance)
	{
		if ((Object)(object)__instance == (Object)null || __instance.itemID != 78)
		{
			return;
		}
		Character holderCharacter = __instance.holderCharacter;
		if ((Object)(object)holderCharacter == (Object)null || holderCharacter.refs == null || (Object)(object)((MonoBehaviourPun)__instance).photonView == (Object)null || !((MonoBehaviourPun)__instance).photonView.IsMine)
		{
			return;
		}
		MegaphoneExplosionController megaphoneExplosionController = ((Component)__instance).GetComponent<MegaphoneExplosionController>();
		if ((Object)(object)megaphoneExplosionController == (Object)null)
		{
			megaphoneExplosionController = ((Component)__instance).gameObject.AddComponent<MegaphoneExplosionController>();
		}
		megaphoneExplosionController.BeginHold();
		MegaphoneNetworkController component = ((Component)__instance).GetComponent<MegaphoneNetworkController>();
		if (!((Object)(object)component == (Object)null))
		{
			PhotonView component2 = ((Component)holderCharacter).GetComponent<PhotonView>();
			if (!((Object)(object)component2 == (Object)null))
			{
				component.SetMegaphoneVoice(enabled: true, component2.ViewID);
				Debug.Log((object)"[Megaphone] Voice activation requested");
			}
		}
	}
}
[HarmonyPatch(typeof(Item), "CancelUsePrimary")]
public static class MegaphoneReleasePatch
{
	private static void Postfix(Item __instance)
	{
		if (!((Object)(object)__instance == (Object)null) && __instance.itemID == 78)
		{
			MegaphoneExplosionController component = ((Component)__instance).GetComponent<MegaphoneExplosionController>();
			if ((Object)(object)component != (Object)null)
			{
				component.CancelHold();
			}
			MegaphoneNetworkController component2 = ((Component)__instance).GetComponent<MegaphoneNetworkController>();
			if (!((Object)(object)component2 == (Object)null))
			{
				component2.StopMegaphoneVoice();
			}
		}
	}
}
[HarmonyPatch(typeof(Item), "SetState")]
public static class MegaphoneAudioPointPatch
{
	private static void Postfix(Item __instance, ItemState setState)
	{
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Expected O, but got Unknown
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)__instance == (Object)null) && __instance.itemID == 78)
		{
			if ((Object)(object)__instance.transform.Find("MegaphoneAudioPoint") == (Object)null)
			{
				GameObject val = new GameObject("MegaphoneAudioPoint");
				val.transform.SetParent(__instance.transform, false);
				val.transform.localPosition = Vector3.zero;
				val.transform.localRotation = Quaternion.identity;
				Debug.Log((object)"[Megaphone] Visible audio point created - GREEN TEST");
			}
			if ((Object)(object)((Component)__instance).GetComponent<MegaphoneNetworkController>() == (Object)null)
			{
				((Component)__instance).gameObject.AddComponent<MegaphoneNetworkController>();
				Debug.Log((object)"[Megaphone] Network controller added");
			}
		}
	}
}
[HarmonyPatch(typeof(VoiceObscuranceFilter), "Update")]
public static class MegaphoneVoiceFilterPatch
{
	private static void Postfix(VoiceObscuranceFilter __instance)
	{
		MegaphoneNetworkController activeController = MegaphoneNetworkController.ActiveController;
		if (!((Object)(object)activeController == (Object)null))
		{
			activeController.ApplyMegaphoneAudio(__instance);
		}
	}
}
[HarmonyPatch(typeof(GUIManager), "UpdateItems")]
public static class MegaphoneTemporarySlotPositionPatch
{
	private static GUIManager trackedGui;

	private static Vector2 originalPosition;

	private static bool positionSaved;

	private static readonly Vector2 MegaphoneOffset = new Vector2(-124f, 0f);

	private static void Postfix(GUIManager __instance)
	{
		//IL_0064: Unknown result type (might be due to invalid IL or missing references)
		//IL_0069: 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_00ef: 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_00f4: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)__instance == (Object)null) && !((Object)(object)__instance.temporaryItem == (Object)null) && !((Object)(object)__instance.temporaryItem.rectTransform == (Object)null))
		{
			RectTransform rectTransform = __instance.temporaryItem.rectTransform;
			if (!positionSaved || (Object)(object)trackedGui != (Object)(object)__instance)
			{
				trackedGui = __instance;
				originalPosition = rectTransform.anchoredPosition;
				positionSaved = true;
			}
			bool flag = false;
			Character observedCharacter = Character.observedCharacter;
			if ((Object)(object)observedCharacter != (Object)null && (Object)(object)observedCharacter.player != (Object)null)
			{
				ItemSlot itemSlot = observedCharacter.player.GetItemSlot((byte)250);
				flag = itemSlot != null && !itemSlot.IsEmpty() && (Object)(object)itemSlot.prefab != (Object)null && itemSlot.prefab.itemID == 78;
			}
			rectTransform.anchoredPosition = originalPosition + (flag ? MegaphoneOffset : Vector2.zero);
		}
	}
}
[HarmonyPatch]
public static class MegaphonePlaneSpawnPatch
{
	private static bool spawned;

	public static void ResetSpawnFlag()
	{
		spawned = false;
	}

	[HarmonyTargetMethod]
	private static MethodBase TargetMethod()
	{
		return AccessTools.Method(AccessTools.TypeByName("SingleItemSpawner"), "TrySpawnItems", (Type[])null, (Type[])null);
	}

	private static void Postfix(object __instance)
	{
		//IL_00c1: 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)
		if (!PhotonNetwork.IsMasterClient)
		{
			return;
		}
		object? obj = AccessTools.Field(__instance.GetType(), "prefab")?.GetValue(__instance);
		GameObject val = (GameObject)((obj is GameObject) ? obj : null);
		if ((Object)(object)val == (Object)null || ((Object)val).name != "Bugle" || spawned)
		{
			return;
		}
		spawned = true;
		Vector3 val2 = default(Vector3);
		((Vector3)(ref val2))..ctor(27.5272f, 1.4505f, -374.124f);
		try
		{
			Item val3 = default(Item);
			if (!ItemDatabase.TryGetItem((ushort)78, ref val3) || (Object)(object)val3 == (Object)null)
			{
				spawned = false;
				Debug.LogError((object)"[Megaphone] Item ID 78 not found!");
			}
			else
			{
				PhotonNetwork.InstantiateItemRoom(((Object)val3).name, val2, Quaternion.identity, true);
				Debug.Log((object)"[Megaphone] Spawned near the crashed plane!");
			}
		}
		catch (Exception ex)
		{
			spawned = false;
			Debug.LogError((object)("[Megaphone] Spawn failed: " + ex));
		}
	}
}
[HarmonyPatch(typeof(GUIManager), "GetMainInteractPrompt")]
public static class MegaphonePromptPatch
{
	private static void Postfix(Item item, ref string __result)
	{
		if (!((Object)(object)item == (Object)null) && item.itemID == 78)
		{
			__result = GetMegaphonePrompt();
		}
	}

	private static string GetMegaphonePrompt()
	{
		//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_0007: 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_004b: Expected I4, but got Unknown
		Language cURRENT_LANGUAGE = LocalizedText.CURRENT_LANGUAGE;
		Language val = cURRENT_LANGUAGE;
		return (int)val switch
		{
			0 => "SPEAK (HOLD)", 
			1 => "PARLER (MAINTENIR)", 
			2 => "PARLARE (TENERE PREMUTO)", 
			3 => "SPRECHEN (GEDRÜCKT HALTEN)", 
			4 => "HABLAR (MANTENER PULSADO)", 
			5 => "HABLAR (MANTENER PULSADO)", 
			6 => "FALAR (MANTER PRESSIONADO)", 
			7 => "ГОВОРИТЬ (УДЕРЖИВАТЬ)", 
			8 => "ГОВОРИТИ (УТРИМУВАТИ)", 
			9 => "说话(持续按住)", 
			10 => "說話(持續按住)", 
			11 => "話す(押し続ける)", 
			12 => "말하기 (누르고 유지)", 
			13 => "MÓW (PRZYTRZYMAJ)", 
			14 => "KONUŞ (BASILI TUT)", 
			_ => "SPEAK (HOLD)", 
		};
	}
}
public class MegaphoneVoiceIndicator : MonoBehaviour
{
	private RectTransform indicator;

	private Image[] bars;

	private RectTransform[] barRects;

	private float[] baseHeights;

	private bool initialized;

	private Sprite roundedSprite;

	private int currentBarCount;

	private static readonly float[] AvailableHeights = new float[8] { 12f, 18f, 25f, 35f, 35f, 25f, 18f, 12f };

	private Sprite CreateRoundedSprite()
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Expected O, but got Unknown
		//IL_0108: Unknown result type (might be due to invalid IL or missing references)
		//IL_0117: 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)
		Texture2D val = new Texture2D(32, 32, (TextureFormat)4, false);
		((Texture)val).filterMode = (FilterMode)1;
		((Texture)val).wrapMode = (TextureWrapMode)1;
		for (int i = 0; i < 32; i++)
		{
			for (int j = 0; j < 32; j++)
			{
				float num = (float)j - 16f + 0.5f;
				float num2 = (float)i - 16f + 0.5f;
				float num3 = Mathf.Clamp(num, -1f, 1f);
				float num4 = Mathf.Clamp(num2, -1f, 1f);
				float num5 = num - num3;
				float num6 = num2 - num4;
				float num7 = Mathf.Sqrt(num5 * num5 + num6 * num6);
				float num8 = ((num7 <= 15f) ? 1f : 0f);
				val.SetPixel(j, i, new Color(1f, 1f, 1f, num8));
			}
		}
		val.Apply();
		return Sprite.Create(val, new Rect(0f, 0f, 32f, 32f), new Vector2(0.5f, 0.5f), 100f);
	}

	private void Update()
	{
		//IL_0330: 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_0339: Unknown result type (might be due to invalid IL or missing references)
		//IL_0360: Unknown result type (might be due to invalid IL or missing references)
		//IL_03a7: 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_03ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c2: 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)
		if ((Object)(object)GUIManager.instance == (Object)null || (Object)(object)GUIManager.instance.hudCanvas == (Object)null || GUIManager.instance.items == null || GUIManager.instance.items.Length == 0)
		{
			SetVisible(visible: false);
			return;
		}
		InventoryItemUI val = GUIManager.instance.items[0];
		if ((Object)(object)val == (Object)null || (Object)(object)val.rectTransform == (Object)null)
		{
			SetVisible(visible: false);
			return;
		}
		Transform parent = ((Transform)val.rectTransform).parent;
		if (initialized && ((Object)(object)indicator == (Object)null || (Object)(object)((Transform)indicator).parent != (Object)(object)parent))
		{
			if ((Object)(object)indicator != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)indicator).gameObject);
			}
			indicator = null;
			bars = null;
			barRects = null;
			baseHeights = null;
			currentBarCount = 0;
			initialized = false;
		}
		if (!initialized)
		{
			if ((Object)(object)roundedSprite == (Object)null)
			{
				roundedSprite = CreateRoundedSprite();
			}
			CreateIndicator();
			if (!initialized)
			{
				return;
			}
		}
		UpdateBarCount(force: false);
		if (MegaphonePlugin.EnableVoiceIndicator == null || !MegaphonePlugin.EnableVoiceIndicator.Value)
		{
			SetVisible(visible: false);
			return;
		}
		bool flag = false;
		if ((Object)(object)Character.localCharacter != (Object)null && (Object)(object)Character.localCharacter.data != (Object)null)
		{
			Item currentItem = Character.localCharacter.data.currentItem;
			flag = (Object)(object)currentItem != (Object)null && currentItem.itemID == 78;
		}
		SetVisible(flag);
		bool flag2 = flag && Input.GetMouseButton(0);
		float num = 0f;
		if (flag2 && (Object)(object)MegaphoneVoiceLevelPatch.LocalRecorder != (Object)null)
		{
			ILevelMeter levelMeter = MegaphoneVoiceLevelPatch.LocalRecorder.LevelMeter;
			if (levelMeter != null)
			{
				num = levelMeter.CurrentPeakAmp;
			}
		}
		num = Mathf.Clamp01(num * 10f);
		Color val2 = default(Color);
		Color val3 = default(Color);
		for (int i = 0; i < bars.Length; i++)
		{
			if (!((Object)(object)bars[i] == (Object)null) && !((Object)(object)barRects[i] == (Object)null))
			{
				float num2 = baseHeights[i];
				if (!flag2)
				{
					Vector2 sizeDelta = barRects[i].sizeDelta;
					sizeDelta.y = num2 * 0.2f;
					barRects[i].sizeDelta = sizeDelta;
					((Graphic)bars[i]).color = new Color(0.32f, 0.34f, 0.29f, 0.85f);
					continue;
				}
				float num3 = 1f + (float)i * 0.12f;
				float num4 = Mathf.Clamp01(num * num3);
				float num5 = Mathf.Lerp(num2 * 0.2f, num2, num4);
				Vector2 sizeDelta2 = barRects[i].sizeDelta;
				sizeDelta2.y = Mathf.Lerp(sizeDelta2.y, num5, Time.deltaTime * 12f);
				barRects[i].sizeDelta = sizeDelta2;
				((Color)(ref val2))..ctor(0.32f, 0.34f, 0.29f, 0.45f);
				((Color)(ref val3))..ctor(0.82f, 0.84f, 0.68f, 1f);
				((Graphic)bars[i]).color = Color.Lerp(val2, val3, num4);
			}
		}
	}

	private void CreateIndicator()
	{
		//IL_007b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0081: Expected O, but got Unknown
		//IL_00ae: 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_00db: 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_0108: Unknown result type (might be due to invalid IL or missing references)
		//IL_010e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0129: Unknown result type (might be due to invalid IL or missing references)
		//IL_012e: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)GUIManager.instance == (Object)null) && !((Object)(object)GUIManager.instance.hudCanvas == (Object)null) && GUIManager.instance.items != null && GUIManager.instance.items.Length != 0)
		{
			InventoryItemUI val = GUIManager.instance.items[0];
			if (!((Object)(object)val == (Object)null) && !((Object)(object)val.rectTransform == (Object)null))
			{
				GameObject val2 = new GameObject("MegaphoneVoiceIndicator");
				RectTransform rectTransform = val.rectTransform;
				val2.transform.SetParent(((Transform)rectTransform).parent, false);
				indicator = val2.AddComponent<RectTransform>();
				indicator.anchorMin = rectTransform.anchorMin;
				indicator.anchorMax = rectTransform.anchorMax;
				indicator.pivot = new Vector2(0.5f, 0f);
				indicator.sizeDelta = new Vector2(120f, 42f);
				indicator.anchoredPosition = rectTransform.anchoredPosition + new Vector2(rectTransform.sizeDelta.x * 0.5f + 55f, 70f);
				val2.SetActive(false);
				initialized = true;
				UpdateBarCount(force: true);
				Debug.Log((object)"[Megaphone] Voice indicator created.");
			}
		}
	}

	private void UpdateBarCount(bool force)
	{
		//IL_0126: Unknown result type (might be due to invalid IL or missing references)
		//IL_012d: Expected O, but got Unknown
		//IL_0156: Unknown result type (might be due to invalid IL or missing references)
		//IL_016d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0184: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d5: 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_0258: Unknown result type (might be due to invalid IL or missing references)
		int num = 5;
		if (MegaphonePlugin.IndicatorBars != null)
		{
			num = MegaphonePlugin.IndicatorBars.Value;
		}
		num = Mathf.Clamp(num, 5, 8);
		if (!force && num == currentBarCount)
		{
			return;
		}
		if (bars != null)
		{
			for (int i = 0; i < bars.Length; i++)
			{
				if ((Object)(object)bars[i] != (Object)null)
				{
					Object.Destroy((Object)(object)((Component)bars[i]).gameObject);
				}
			}
		}
		currentBarCount = num;
		bars = (Image[])(object)new Image[currentBarCount];
		barRects = (RectTransform[])(object)new RectTransform[currentBarCount];
		baseHeights = new float[currentBarCount];
		for (int j = 0; j < currentBarCount; j++)
		{
			float num2 = (float)j / (float)(currentBarCount - 1);
			baseHeights[j] = Mathf.Lerp(12f, 35f, 1f - Mathf.Abs(2f * num2 - 1f));
			GameObject val = new GameObject("Bar" + j);
			val.transform.SetParent((Transform)(object)indicator, false);
			RectTransform val2 = val.AddComponent<RectTransform>();
			val2.anchorMin = new Vector2(0f, 0f);
			val2.anchorMax = new Vector2(0f, 0f);
			val2.pivot = new Vector2(0f, 0f);
			float num3 = 12f;
			float num4 = (float)(currentBarCount - 1) * num3 + 10f;
			float num5 = (indicator.sizeDelta.x - num4) * 0.5f;
			val2.anchoredPosition = new Vector2(num5 + (float)j * num3, 0f);
			val2.sizeDelta = new Vector2(10f, baseHeights[j]);
			barRects[j] = val2;
			bars[j] = val.AddComponent<Image>();
			bars[j].sprite = roundedSprite;
			bars[j].type = (Type)0;
			((Graphic)bars[j]).color = new Color(0.32f, 0.34f, 0.29f, 0.85f);
		}
	}

	public void SetVisible(bool visible)
	{
		if ((Object)(object)indicator != (Object)null && ((Component)indicator).gameObject.activeSelf != visible)
		{
			((Component)indicator).gameObject.SetActive(visible);
		}
	}
}
[HarmonyPatch(typeof(CharacterVoiceHandler), "Start")]
public static class MegaphoneVoiceLevelPatch
{
	public static Recorder LocalRecorder;

	private static void Postfix(CharacterVoiceHandler __instance)
	{
		Character componentInParent = ((Component)__instance).GetComponentInParent<Character>();
		if (!((Object)(object)componentInParent == (Object)null) && componentInParent.IsLocal)
		{
			LocalRecorder = ((Component)__instance).GetComponent<Recorder>();
			if ((Object)(object)LocalRecorder != (Object)null)
			{
				Debug.Log((object)"[Megaphone] Local microphone recorder found.");
			}
		}
	}
}