Decompiled source of ArrowBlowgun v0.1.1

plugins/com.github.jie65535.ArrowBlowgun.dll

Decompiled 2 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Cryptography;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using ExitGames.Client.Photon;
using Microsoft.CodeAnalysis;
using Peak;
using Photon.Pun;
using Photon.Realtime;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.SceneManagement;
using Zorro.Core;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("com.github.jie65535.ArrowBlowgun")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.1.0")]
[assembly: AssemblyInformationalVersion("0.1.1+7732990abb2f2fbf6f22cced1a72bd7a6da98dc7")]
[assembly: AssemblyProduct("com.github.jie65535.ArrowBlowgun")]
[assembly: AssemblyTitle("ArrowBlowgun")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/jie65535/ArrowBlowgun")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace ArrowBlowgun
{
	internal sealed class Action_FireArrow : ItemAction
	{
		private const float ArrowShooterRange = 80f;

		private const float DefaultAimCorrectionDegrees = 35f;

		private const float Knockback = 30f;

		private const float KnockbackRadius = 400f;

		[SerializeField]
		private float maxDistance = 80f;

		[SerializeField]
		private Transform spawnTransform;

		[SerializeField]
		private float maxAimCorrectionDegrees = 35f;

		internal Transform SpawnTransform => spawnTransform;

		internal void CopyFrom(Action_RaycastDart source, float aimCorrectionDegrees)
		{
			maxDistance = ((source.maxDistance > 0f) ? source.maxDistance : 80f);
			spawnTransform = source.spawnTransform;
			maxAimCorrectionDegrees = Mathf.Clamp(aimCorrectionDegrees, 0f, 90f);
			ArrowTrapFeedback.ConfigureFallback(source.shotSFX, ((Component)source).GetComponentsInChildren<ParticleSystem>(true));
			base.OnPressed = ((ItemAction)source).OnPressed;
			base.OnHeld = ((ItemAction)source).OnHeld;
			base.OnReleased = ((ItemAction)source).OnReleased;
			base.OnCastFinished = ((ItemAction)source).OnCastFinished;
			base.OnCancelled = ((ItemAction)source).OnCancelled;
			base.OnSecondaryCastFinished = ((ItemAction)source).OnSecondaryCastFinished;
			base.OnSecondaryPressed = ((ItemAction)source).OnSecondaryPressed;
			base.OnSecondaryHeld = ((ItemAction)source).OnSecondaryHeld;
			base.OnSecondaryCancelled = ((ItemAction)source).OnSecondaryCancelled;
			base.OnConsumed = ((ItemAction)source).OnConsumed;
		}

		public override void RunAction()
		{
			//IL_004a: 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_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: 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_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_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: 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_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: 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_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_023b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: Unknown result type (might be due to invalid IL or missing references)
			//IL_024e: 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)
			if (!((Object)(object)((ItemActionBase)this).character == (Object)null) && ((ItemActionBase)this).character.IsLocal && !((Object)(object)MainCamera.instance == (Object)null))
			{
				Vector3 val = (((Object)(object)spawnTransform != (Object)null) ? spawnTransform.position : ((Component)this).transform.position);
				Transform transform = ((Component)MainCamera.instance).transform;
				Vector3 val2 = transform.forward;
				Vector3 normalized = ((Vector3)(ref val2)).normalized;
				RaycastHit val3 = FindFirstValidHit(transform.position, normalized, maxDistance);
				Vector3 val4 = (((Object)(object)((RaycastHit)(ref val3)).collider != (Object)null) ? ((RaycastHit)(ref val3)).point : (transform.position + normalized * maxDistance));
				Vector3 normalized2;
				if (!((Object)(object)spawnTransform != (Object)null))
				{
					val2 = ((Component)this).transform.forward;
					normalized2 = ((Vector3)(ref val2)).normalized;
				}
				else
				{
					val2 = spawnTransform.forward;
					normalized2 = ((Vector3)(ref val2)).normalized;
				}
				Vector3 val5 = normalized2;
				if (((Vector3)(ref val5)).sqrMagnitude < Mathf.Epsilon)
				{
					val5 = normalized;
				}
				Vector3 val6 = val4 - val;
				Vector3 val7 = val5;
				if (Vector3.Dot(val6, val5) > 0f)
				{
					Vector3 val8 = ((((Vector3)(ref val6)).sqrMagnitude > Mathf.Epsilon) ? ((Vector3)(ref val6)).normalized : normalized);
					val2 = Vector3.RotateTowards(val5, val8, maxAimCorrectionDegrees * (MathF.PI / 180f), 0f);
					val7 = ((Vector3)(ref val2)).normalized;
				}
				RaycastHit val9 = FindFirstValidHit(val, val7, maxDistance);
				bool flag = (Object)(object)((RaycastHit)(ref val9)).collider != (Object)null;
				Vector3 val10 = (flag ? ((RaycastHit)(ref val9)).point : (val + val7 * maxDistance));
				Collider collider = ((RaycastHit)(ref val9)).collider;
				Character val11 = ((collider != null) ? ((Component)collider).GetComponentInParent<Character>() : null);
				Vector3 val12 = (((Object)(object)val11 != (Object)null) ? (-val7) : (flag ? ((RaycastHit)(ref val9)).normal : (-val7)));
				int num = -1;
				if ((Object)(object)val11 != (Object)null)
				{
					num = ((MonoBehaviourPun)val11).photonView.ViewID;
				}
				ApplyArrowShot(num, val, val10, val7, val12, flag, 30f);
				if (PhotonNetwork.InRoom && ((MonoBehaviourPun)this).photonView.ViewID != 0)
				{
					((MonoBehaviourPun)this).photonView.RPC("RPCA_ArrowShot", (RpcTarget)1, new object[7] { num, val, val10, val7, val12, flag, 30f });
				}
			}
		}

		private RaycastHit FindFirstValidHit(Vector3 origin, Vector3 direction, float distance)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			return ((IEnumerable<RaycastHit>)(from hit in Physics.RaycastAll(origin, direction, distance, LayerMask.op_Implicit(HelperFunctions.AllPhysical), (QueryTriggerInteraction)1)
				orderby ((RaycastHit)(ref hit)).distance
				select hit)).FirstOrDefault((Func<RaycastHit, bool>)delegate(RaycastHit hit)
			{
				if ((Object)(object)((RaycastHit)(ref hit)).collider == (Object)null || (Object)(object)((Component)((RaycastHit)(ref hit)).collider).GetComponentInParent<Item>() != (Object)null)
				{
					return false;
				}
				Character componentInParent = ((Component)((RaycastHit)(ref hit)).collider).GetComponentInParent<Character>();
				return (Object)(object)componentInParent == (Object)null || (Object)(object)componentInParent != (Object)(object)((ItemActionBase)this).character;
			});
		}

		[PunRPC]
		private void RPCA_ArrowShot(int targetViewId, Vector3 origin, Vector3 endpoint, Vector3 direction, Vector3 surfaceNormal, bool hasImpact, float knockback)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: 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)
			ApplyArrowShot(targetViewId, origin, endpoint, direction, surfaceNormal, hasImpact, knockback);
		}

		private void ApplyArrowShot(int targetViewId, Vector3 origin, Vector3 endpoint, Vector3 direction, Vector3 surfaceNormal, bool hasImpact, float knockback)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: 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_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			ArrowTrapFeedback.Play(origin, endpoint, direction);
			if (!hasImpact)
			{
				return;
			}
			GamefeelHandler instance = GamefeelHandler.instance;
			if (instance != null)
			{
				instance.AddPerlinShakeProximity(endpoint, 5f, 0.2f, 15f, 10f);
			}
			if (targetViewId < 0)
			{
				GameObject arrow = ArrowVisualFactory.Create(endpoint, direction);
				ArrowVisualFactory.Embed(arrow, endpoint, direction, surfaceNormal);
				return;
			}
			PhotonView photonView = PhotonNetwork.GetPhotonView(targetViewId);
			Character val = (((Object)(object)photonView != (Object)null) ? ((Component)photonView).GetComponent<Character>() : null);
			if (!((Object)(object)val == (Object)null) && ((MonoBehaviourPun)val).photonView.IsMine)
			{
				val.refs.afflictions.AddArrow(endpoint, -direction);
				val.AddForceAtPosition(direction * knockback, endpoint, 400f);
			}
		}
	}
	internal sealed class ArrowBlowgunPrefabPool : IPunPrefabPool
	{
		private readonly IPunPrefabPool fallback;

		private readonly string prefabId;

		private readonly GameObject prefab;

		internal ArrowBlowgunPrefabPool(IPunPrefabPool fallback, string prefabId, GameObject prefab)
		{
			this.fallback = fallback;
			this.prefabId = prefabId;
			this.prefab = prefab;
		}

		public GameObject Instantiate(string requestedPrefabId, Vector3 position, Quaternion rotation)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			if (requestedPrefabId != prefabId)
			{
				return fallback.Instantiate(requestedPrefabId, position, rotation);
			}
			bool activeSelf = prefab.activeSelf;
			if (activeSelf)
			{
				prefab.SetActive(false);
			}
			GameObject result = Object.Instantiate<GameObject>(prefab, position, rotation);
			if (activeSelf)
			{
				prefab.SetActive(true);
			}
			return result;
		}

		public void Destroy(GameObject gameObject)
		{
			fallback.Destroy(gameObject);
		}
	}
	internal static class ArrowTrapFeedback
	{
		private sealed class SoundResource
		{
			internal string InstanceName { get; }

			internal string ClipName { get; }

			internal string FileName { get; }

			internal SoundResource(string instanceName, string clipName, string fileName)
			{
				InstanceName = instanceName;
				ClipName = clipName;
				FileName = fileName;
			}
		}

		private const string TrapSmokeMaterialName = "M_VFX_Smoke Light";

		private static readonly SoundResource[] SoundResources = new SoundResource[4]
		{
			new SoundResource("SFXI Arrow Shot 1", "Au_Hookshot_Shoot", "Au_Hookshot_Shoot.ogg"),
			new SoundResource("SFXI Arrow Shot 2", "Au_Bow_Hit2", "Au_Bow_Hit2.ogg"),
			new SoundResource("SFXI Arrow Shot 3", "Au_Bow_Release", "Au_Bow_Release.ogg"),
			new SoundResource("SFXI Arrow Shot 4", "Au_Door5", "Au_Door5.ogg")
		};

		private static readonly List<SFX_Instance> embeddedShotSounds = new List<SFX_Instance>();

		private static SFX_Instance? fallbackShotSound;

		private static Material? fallbackSmokeMaterial;

		private static Material? trapSmokeMaterial;

		private static bool initialized;

		private static bool warnedAboutMissingSound;

		internal static void ConfigureFallback(SFX_Instance? shotSound, IEnumerable<ParticleSystem> particles)
		{
			fallbackShotSound = shotSound;
			fallbackSmokeMaterial = particles.Where((ParticleSystem particle) => (Object)(object)particle != (Object)null).Select(delegate(ParticleSystem particle)
			{
				ParticleSystemRenderer component = ((Component)particle).GetComponent<ParticleSystemRenderer>();
				return (component == null) ? null : ((Renderer)component).sharedMaterial;
			}).FirstOrDefault((Func<Material, bool>)((Material material) => (Object)(object)material != (Object)null));
		}

		internal static IEnumerator Initialize()
		{
			if (initialized)
			{
				yield break;
			}
			initialized = true;
			Assembly assembly = typeof(ArrowTrapFeedback).Assembly;
			SoundResource[] soundResources = SoundResources;
			foreach (SoundResource soundResource in soundResources)
			{
				string text = "ArrowBlowgun.Assets.Audio." + soundResource.FileName;
				using Stream stream = assembly.GetManifestResourceStream(text);
				if (stream == null)
				{
					Plugin.Log.LogError((object)("Embedded arrow-trap sound is missing: " + text));
					continue;
				}
				byte[] bytes;
				using (MemoryStream memoryStream = new MemoryStream())
				{
					stream.CopyTo(memoryStream);
					bytes = memoryStream.ToArray();
				}
				string temporaryPath = Path.Combine(Path.GetTempPath(), string.Format("{0}.{1:N}.ogg", "com.github.jie65535.ArrowBlowgun", Guid.NewGuid()));
				try
				{
					File.WriteAllBytes(temporaryPath, bytes);
				}
				catch (Exception ex)
				{
					Plugin.Log.LogError((object)("Could not stage arrow-trap sound '" + soundResource.ClipName + "': " + ex.Message));
					goto end_IL_009d;
				}
				UnityWebRequest request = UnityWebRequestMultimedia.GetAudioClip(new Uri(temporaryPath), (AudioType)14);
				try
				{
					DownloadHandlerAudioClip val = (DownloadHandlerAudioClip)request.downloadHandler;
					val.streamAudio = false;
					val.compressed = false;
					yield return request.SendWebRequest();
					if ((int)request.result == 1)
					{
						AudioClip content = DownloadHandlerAudioClip.GetContent(request);
						((Object)content).name = soundResource.ClipName;
						embeddedShotSounds.Add(CreateSoundInstance(soundResource.InstanceName, content));
					}
					else
					{
						Plugin.Log.LogError((object)("Could not load arrow-trap sound '" + soundResource.ClipName + "': " + request.error));
					}
					try
					{
						File.Delete(temporaryPath);
					}
					catch (Exception ex2)
					{
						Plugin.Log.LogDebug((object)("Could not delete temporary arrow-trap audio '" + temporaryPath + "': " + ex2.Message));
					}
				}
				finally
				{
					((IDisposable)request)?.Dispose();
				}
				end_IL_009d:;
			}
			Plugin.Log.LogInfo((object)$"Loaded {embeddedShotSounds.Count}/{SoundResources.Length} arrow-trap sound layers.");
		}

		internal static void Play(Vector3 origin, Vector3 endpoint, Vector3 direction)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: 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_0019: Unknown result type (might be due to invalid IL or missing references)
			ArrowShooter val = FindLoadedArrowShooter();
			PlaySounds(origin, val);
			if ((Object)(object)val != (Object)null)
			{
				PlayLoadedTrapParticles(val, origin, endpoint, direction);
				return;
			}
			PlayRecreatedMuzzlePuff(origin, direction);
			PlayRecreatedSmokeTrail(origin, endpoint);
		}

		private static SFX_Instance CreateSoundInstance(string instanceName, AudioClip clip)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Expected O, but got Unknown
			SFX_Instance val = ScriptableObject.CreateInstance<SFX_Instance>();
			((Object)val).name = instanceName;
			((Object)val).hideFlags = (HideFlags)61;
			val.clips = (AudioClip[])(object)new AudioClip[1] { clip };
			val.settings = new SFX_Settings
			{
				volume = 0.5f,
				volume_Variation = 0.1f,
				pitch = 1f,
				pitch_Variation = 0.2f,
				spatialBlend = 1f,
				dopplerLevel = 1f,
				range = 100f,
				cooldown = 0.02f,
				maxInstances_NOT_IMPLEMENTED = 5
			};
			return val;
		}

		private static void PlaySounds(Vector3 origin, ArrowShooter? loadedShooter)
		{
			//IL_003e: 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)
			SFX_Instance[] array = loadedShooter?.shotSFX;
			IEnumerable<SFX_Instance> enumerable2;
			if (array == null)
			{
				IEnumerable<SFX_Instance> enumerable = embeddedShotSounds;
				enumerable2 = enumerable;
			}
			else
			{
				IEnumerable<SFX_Instance> enumerable = array;
				enumerable2 = enumerable;
			}
			IEnumerable<SFX_Instance> enumerable3 = enumerable2;
			bool flag = false;
			foreach (SFX_Instance item in enumerable3)
			{
				if ((Object)(object)item != (Object)null)
				{
					item.Play(origin);
					flag = true;
				}
			}
			if (!flag)
			{
				if ((Object)(object)fallbackShotSound != (Object)null)
				{
					fallbackShotSound.Play(origin);
				}
				else if (!warnedAboutMissingSound)
				{
					warnedAboutMissingSound = true;
					Plugin.Log.LogWarning((object)"No arrow-trap shot sound is available.");
				}
			}
		}

		private static ArrowShooter? FindLoadedArrowShooter()
		{
			return ((IEnumerable<ArrowShooter>)Resources.FindObjectsOfTypeAll<ArrowShooter>()).FirstOrDefault((Func<ArrowShooter, bool>)((ArrowShooter shooter) => (Object)(object)shooter != (Object)null && (Object)(object)shooter.firedParticles != (Object)null && (Object)(object)shooter.trailParticles != (Object)null));
		}

		private static void PlayLoadedTrapParticles(ArrowShooter shooter, Vector3 origin, Vector3 endpoint, Vector3 direction)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: 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_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: 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)
			Quaternion val = Quaternion.LookRotation(direction, Vector3.up);
			ParticleSystem val2 = Object.Instantiate<ParticleSystem>(shooter.firedParticles, origin, val);
			((Component)val2).gameObject.SetActive(true);
			val2.Play(true);
			Object.Destroy((Object)(object)((Component)val2).gameObject, 6f);
			Vector3 val3 = endpoint - origin;
			ParticleSystem val4 = Object.Instantiate<ParticleSystem>(shooter.trailParticles, origin + val3 * 0.5f, Quaternion.LookRotation(val3, Vector3.up));
			ShapeModule shape = val4.shape;
			((ShapeModule)(ref shape)).radius = ((Vector3)(ref val3)).magnitude * 0.5f;
			((Component)val4).gameObject.SetActive(true);
			val4.Play(true);
			Object.Destroy((Object)(object)((Component)val4).gameObject, 6f);
		}

		private static void PlayRecreatedMuzzlePuff(Vector3 origin, Vector3 direction)
		{
			//IL_0005: 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_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_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			ParticleSystem val = CreateParticleSystem("ArrowBlowgun.ArrowTrapMuzzle", origin, Quaternion.LookRotation(direction, Vector3.up));
			MainModule main = val.main;
			((MainModule)(ref main)).duration = 0.1f;
			((MainModule)(ref main)).startLifetime = new MinMaxCurve(0.25f, 0.6f);
			((MainModule)(ref main)).startSpeed = new MinMaxCurve(0.5f, 1.2f);
			((MainModule)(ref main)).startSize = new MinMaxCurve(0.12f, 0.35f);
			((MainModule)(ref main)).maxParticles = 32;
			EmissionModule emission = val.emission;
			((EmissionModule)(ref emission)).SetBursts((Burst[])(object)new Burst[1]
			{
				new Burst(0f, (short)14)
			});
			ShapeModule shape = val.shape;
			((ShapeModule)(ref shape)).enabled = true;
			((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)4;
			((ShapeModule)(ref shape)).angle = 18f;
			((ShapeModule)(ref shape)).radius = 0.04f;
			ConfigureFade(val);
			val.Play();
		}

		private static void PlayRecreatedSmokeTrail(Vector3 origin, Vector3 endpoint)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: 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_001c: 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_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: 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)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = endpoint - origin;
			if (!(((Vector3)(ref val)).sqrMagnitude < 0.0001f))
			{
				ParticleSystem val2 = CreateParticleSystem("ArrowBlowgun.ArrowTrapSmokeTrail", origin + val * 0.5f, Quaternion.LookRotation(val, Vector3.up));
				MainModule main = val2.main;
				((MainModule)(ref main)).duration = 0.1f;
				((MainModule)(ref main)).startLifetime = new MinMaxCurve(2f, 5f);
				((MainModule)(ref main)).startSpeed = new MinMaxCurve(0.1f, 0.2f);
				((MainModule)(ref main)).startSize = new MinMaxCurve(0.3f, 0.5f);
				((MainModule)(ref main)).startRotation = new MinMaxCurve(0f, MathF.PI * 2f);
				((MainModule)(ref main)).maxParticles = 1000;
				EmissionModule emission = val2.emission;
				((EmissionModule)(ref emission)).SetBursts((Burst[])(object)new Burst[1]
				{
					new Burst(0f, (short)30)
				});
				ShapeModule shape = val2.shape;
				((ShapeModule)(ref shape)).enabled = true;
				((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)12;
				((ShapeModule)(ref shape)).radius = ((Vector3)(ref val)).magnitude * 0.5f;
				((ShapeModule)(ref shape)).rotation = new Vector3(0f, 90f, 0f);
				NoiseModule noise = val2.noise;
				((NoiseModule)(ref noise)).enabled = true;
				((NoiseModule)(ref noise)).strength = MinMaxCurve.op_Implicit(0.05f);
				ConfigureFade(val2);
				val2.Play();
			}
		}

		private static ParticleSystem CreateParticleSystem(string name, Vector3 position, Quaternion rotation)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name);
			val.transform.SetPositionAndRotation(position, rotation);
			ParticleSystem val2 = val.AddComponent<ParticleSystem>();
			val2.Stop(true, (ParticleSystemStopBehavior)0);
			MainModule main = val2.main;
			((MainModule)(ref main)).loop = false;
			((MainModule)(ref main)).playOnAwake = false;
			((MainModule)(ref main)).simulationSpace = (ParticleSystemSimulationSpace)1;
			((MainModule)(ref main)).stopAction = (ParticleSystemStopAction)2;
			EmissionModule emission = val2.emission;
			((EmissionModule)(ref emission)).enabled = true;
			((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(0f);
			((EmissionModule)(ref emission)).rateOverDistance = MinMaxCurve.op_Implicit(0f);
			ParticleSystemRenderer component = val.GetComponent<ParticleSystemRenderer>();
			((Renderer)component).sharedMaterial = GetSmokeMaterial();
			component.renderMode = (ParticleSystemRenderMode)0;
			component.maxParticleSize = 0.5f;
			return val2;
		}

		private static void ConfigureFade(ParticleSystem particles)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: 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_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			Gradient val = new Gradient();
			val.SetKeys((GradientColorKey[])(object)new GradientColorKey[2]
			{
				new GradientColorKey(Color.white, 0f),
				new GradientColorKey(Color.white, 1f)
			}, (GradientAlphaKey[])(object)new GradientAlphaKey[2]
			{
				new GradientAlphaKey(0.8f, 0f),
				new GradientAlphaKey(0f, 1f)
			});
			ColorOverLifetimeModule colorOverLifetime = particles.colorOverLifetime;
			((ColorOverLifetimeModule)(ref colorOverLifetime)).enabled = true;
			((ColorOverLifetimeModule)(ref colorOverLifetime)).color = new MinMaxGradient(val);
		}

		private static Material? GetSmokeMaterial()
		{
			if ((Object)(object)trapSmokeMaterial == (Object)null)
			{
				trapSmokeMaterial = ((IEnumerable<Material>)Resources.FindObjectsOfTypeAll<Material>()).FirstOrDefault((Func<Material, bool>)((Material material) => (Object)(object)material != (Object)null && ((Object)material).name == "M_VFX_Smoke Light"));
			}
			if (!((Object)(object)trapSmokeMaterial != (Object)null))
			{
				return fallbackSmokeMaterial;
			}
			return trapSmokeMaterial;
		}
	}
	internal static class ArrowVisualFactory
	{
		private enum ArrowAxis
		{
			Forward,
			NegativeUp
		}

		private const string LoadedArrowName = "ArrowBlowgun.LoadedArrow";

		private const float LoadedArrowScale = 0.85f;

		private const float LoadedArrowRetraction = 0.35f;

		private static GameObject? cacheRoot;

		private static GameObject? template;

		private static ArrowAxis templateAxis;

		private static Material? fallbackMaterial;

		internal static void WarmUp()
		{
			EnsureTemplate();
		}

		internal static int AttachLoadedArrowVisuals(Item registeredItem)
		{
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Expected O, but got Unknown
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			EnsureTemplate();
			int num = 0;
			Item[] array = Resources.FindObjectsOfTypeAll<Item>();
			foreach (Item val in array)
			{
				if (!((Object)(object)val == (Object)null) && val.itemID == registeredItem.itemID)
				{
					Transform val2 = ((Component)val).GetComponent<Action_FireArrow>()?.SpawnTransform;
					if (!((Object)(object)val2 == (Object)null) && !((Object)(object)val2.Find("ArrowBlowgun.LoadedArrow") != (Object)null))
					{
						GameObject val3 = (GameObject)Object.Instantiate((Object)(object)template, val2, false);
						((Object)val3).name = "ArrowBlowgun.LoadedArrow";
						val3.transform.localPosition = Vector3.back * 0.35f;
						val3.transform.localRotation = GetRotation(Vector3.forward);
						Transform transform = val3.transform;
						transform.localScale *= 0.85f;
						val3.SetActive(true);
						num++;
					}
				}
			}
			return num;
		}

		internal static GameObject Create(Vector3 position, Vector3 direction)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			EnsureTemplate();
			GameObject val = Object.Instantiate<GameObject>(template);
			((Object)val).name = "ArrowBlowgun.ArrowVisual";
			val.transform.SetParent((Transform)null, false);
			SceneManager.MoveGameObjectToScene(val, SceneManager.GetActiveScene());
			val.transform.position = position;
			SetDirection(val, direction);
			val.SetActive(true);
			return val;
		}

		internal static void SetDirection(GameObject arrow, Vector3 direction)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			if (!(((Vector3)(ref direction)).sqrMagnitude < 0.0001f))
			{
				arrow.transform.rotation = GetRotation(direction);
			}
		}

		internal static void Embed(GameObject arrow, Vector3 position, Vector3 direction, Vector3 surfaceNormal)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: 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_0036: 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_0041: 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)
			Vector3 val = ((((Vector3)(ref surfaceNormal)).sqrMagnitude > 0.0001f) ? ((Vector3)(ref surfaceNormal)).normalized : (-((Vector3)(ref direction)).normalized));
			((Object)arrow).name = "ArrowBlowgun.StuckArrow";
			arrow.transform.position = position + val * 0.01f;
			SetDirection(arrow, direction);
		}

		private static void EnsureTemplate()
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Expected O, but got Unknown
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)template != (Object)null))
			{
				EnsureCacheRoot();
				ArrowAxis axis;
				string sourceKind;
				GameObject val = FindVanillaArrowSource(out axis, out sourceKind);
				if ((Object)(object)val != (Object)null)
				{
					Vector3 localScale = val.transform.localScale;
					Vector3 val2 = Abs(val.transform.lossyScale);
					template = (GameObject)Object.Instantiate((Object)(object)val, cacheRoot.transform, true);
					((Object)template).name = "VanillaArrowVisual.Template";
					template.transform.localScale = val2;
					template.SetActive(false);
					templateAxis = axis;
					Sanitize(template);
					Plugin.Log.LogInfo((object)("Using vanilla arrow visual from " + sourceKind + " '" + ((Object)val).name + "' " + $"with local scale {localScale} and world scale {val2}."));
				}
				else
				{
					template = CreateFallbackTemplate();
					templateAxis = ArrowAxis.Forward;
					Plugin.Log.LogWarning((object)"No loaded vanilla arrow visual was found; using the built-in fallback visual.");
				}
			}
		}

		private static void EnsureCacheRoot()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			if (!((Object)(object)cacheRoot != (Object)null))
			{
				cacheRoot = new GameObject("com.github.jie65535.ArrowBlowgun.ArrowVisualCache");
				cacheRoot.SetActive(false);
				Object.DontDestroyOnLoad((Object)(object)cacheRoot);
			}
		}

		private static GameObject? FindVanillaArrowSource(out ArrowAxis axis, out string sourceKind)
		{
			ArrowShooter[] array = Resources.FindObjectsOfTypeAll<ArrowShooter>();
			foreach (ArrowShooter val in array)
			{
				if ((Object)(object)val != (Object)null && (Object)(object)val.arrowPrefab != (Object)null)
				{
					axis = ArrowAxis.Forward;
					sourceKind = "ArrowShooter";
					return val.arrowPrefab;
				}
			}
			GenerateCharacterArrows[] array2 = Resources.FindObjectsOfTypeAll<GenerateCharacterArrows>();
			foreach (GenerateCharacterArrows val2 in array2)
			{
				if ((Object)(object)val2 != (Object)null && (Object)(object)val2.arrowPrefab != (Object)null)
				{
					axis = ArrowAxis.NegativeUp;
					sourceKind = "GenerateCharacterArrows";
					return val2.arrowPrefab;
				}
			}
			GameObject val3 = FindPhysicalCharacterArrow();
			if ((Object)(object)val3 != (Object)null)
			{
				axis = ArrowAxis.NegativeUp;
				sourceKind = "ThornOnMe";
				return val3;
			}
			axis = ArrowAxis.Forward;
			sourceKind = "fallback";
			return null;
		}

		private static GameObject? FindPhysicalCharacterArrow()
		{
			GameObject val = FindPhysicalCharacterArrow(Character.localCharacter);
			if ((Object)(object)val != (Object)null)
			{
				return val;
			}
			foreach (Character allCharacter in Character.AllCharacters)
			{
				GameObject val2 = FindPhysicalCharacterArrow(allCharacter);
				if ((Object)(object)val2 != (Object)null)
				{
					return val2;
				}
			}
			return null;
		}

		private static GameObject? FindPhysicalCharacterArrow(Character? character)
		{
			if ((Object)(object)character == (Object)null || character.refs?.afflictions?.physicalThorns == null)
			{
				return null;
			}
			foreach (ThornOnMe physicalThorn in character.refs.afflictions.physicalThorns)
			{
				if ((Object)(object)physicalThorn != (Object)null && physicalThorn.isArrow)
				{
					return ((Component)physicalThorn).gameObject;
				}
			}
			return null;
		}

		private static void Sanitize(GameObject root)
		{
			MonoBehaviour[] componentsInChildren = root.GetComponentsInChildren<MonoBehaviour>(true);
			foreach (MonoBehaviour val in componentsInChildren)
			{
				((Behaviour)val).enabled = false;
				Object.Destroy((Object)(object)val);
			}
			Collider[] componentsInChildren2 = root.GetComponentsInChildren<Collider>(true);
			foreach (Collider val2 in componentsInChildren2)
			{
				val2.enabled = false;
				Object.Destroy((Object)(object)val2);
			}
			Rigidbody[] componentsInChildren3 = root.GetComponentsInChildren<Rigidbody>(true);
			foreach (Rigidbody val3 in componentsInChildren3)
			{
				val3.detectCollisions = false;
				val3.isKinematic = true;
				Object.Destroy((Object)(object)val3);
			}
			Renderer[] componentsInChildren4 = root.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val4 in componentsInChildren4)
			{
				val4.enabled = true;
			}
		}

		private static GameObject CreateFallbackTemplate()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("FallbackArrowVisual.Template");
			val.transform.SetParent(cacheRoot.transform, false);
			val.SetActive(false);
			GameObject val2 = GameObject.CreatePrimitive((PrimitiveType)2);
			((Object)val2).name = "Shaft";
			val2.transform.SetParent(val.transform, false);
			val2.transform.localPosition = new Vector3(0f, 0f, -0.18f);
			val2.transform.localRotation = Quaternion.Euler(90f, 0f, 0f);
			val2.transform.localScale = new Vector3(0.012f, 0.28f, 0.012f);
			GameObject val3 = GameObject.CreatePrimitive((PrimitiveType)0);
			((Object)val3).name = "Tip";
			val3.transform.SetParent(val.transform, false);
			val3.transform.localPosition = new Vector3(0f, 0f, 0.11f);
			val3.transform.localScale = new Vector3(0.035f, 0.035f, 0.07f);
			Material val4 = GetFallbackMaterial();
			if ((Object)(object)val4 != (Object)null)
			{
				val2.GetComponent<Renderer>().sharedMaterial = val4;
				val3.GetComponent<Renderer>().sharedMaterial = val4;
			}
			Sanitize(val);
			return val;
		}

		private static Material? GetFallbackMaterial()
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: 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_0077: Expected O, but got Unknown
			if ((Object)(object)fallbackMaterial != (Object)null)
			{
				return fallbackMaterial;
			}
			Shader val = Shader.Find("Universal Render Pipeline/Lit") ?? Shader.Find("Universal Render Pipeline/Unlit") ?? Shader.Find("Standard");
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			fallbackMaterial = new Material(val)
			{
				color = new Color(0.32f, 0.22f, 0.12f, 1f),
				hideFlags = (HideFlags)61
			};
			return fallbackMaterial;
		}

		private static Vector3 Abs(Vector3 value)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			return new Vector3(Mathf.Abs(value.x), Mathf.Abs(value.y), Mathf.Abs(value.z));
		}

		private static Quaternion GetRotation(Vector3 direction)
		{
			//IL_000e: 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_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = ((templateAxis == ArrowAxis.Forward) ? Vector3.forward : Vector3.down);
			return Quaternion.FromToRotation(val, ((Vector3)(ref direction)).normalized);
		}
	}
	[BepInPlugin("com.github.jie65535.ArrowBlowgun", "ArrowBlowgun", "0.1.1")]
	public sealed class Plugin : BaseUnityPlugin
	{
		internal const string PluginGuid = "com.github.jie65535.ArrowBlowgun";

		internal const string PluginName = "ArrowBlowgun";

		internal const string PluginVersion = "0.1.1";

		private const string PrefabName = "ArrowBlowgun";

		private const string ItemNameKey = "ARROW_BLOWGUN";

		private const string ItemPrefabFolder = "0_Items/";

		private const int DefaultUses = 3;

		private const int MinimumUses = 1;

		private const float DefaultShotUseTime = 1f;

		private const float MinimumShotUseTime = 0f;

		private const float MaximumShotUseTime = 10f;

		private const float DefaultAimCorrectionDegrees = 35f;

		private const float MinimumAimCorrectionDegrees = 0f;

		private const float MaximumAimCorrectionDegrees = 90f;

		private const bool DefaultAddToLootPool = true;

		private ConfigEntry<int> usesConfig;

		private ConfigEntry<float> shotUseTimeConfig;

		private ConfigEntry<float> aimCorrectionDegreesConfig;

		private ConfigEntry<bool> addToLootPoolConfig;

		private int effectiveUses = 3;

		private bool effectiveAddToLootPool = true;

		private SpawnPool originalLootSpawnLocations;

		private GameObject prefabContainer;

		internal static ManualLogSource Log { get; private set; }

		internal static Item? RegisteredItem { get; private set; }

		internal int ConfiguredUses => usesConfig.Value;

		internal bool ConfiguredAddToLootPool => addToLootPoolConfig.Value;

		private void Awake()
		{
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			usesConfig = ((BaseUnityPlugin)this).Config.Bind<int>("Balance", "Uses", 3, "Number of shots before the Arrow Blowgun is consumed. Minimum: 1. In multiplayer, the room creator's value is used for everyone.");
			shotUseTimeConfig = ((BaseUnityPlugin)this).Config.Bind<float>("Balance", "ShotUseTime", 1f, "Seconds the primary action must be held before firing. Set to 0 for an instant semi-automatic shot. This is a per-player setting and is not " + $"synchronized. Range: {0f}-{10f}.");
			aimCorrectionDegreesConfig = ((BaseUnityPlugin)this).Config.Bind<float>("Balance", "AimCorrectionDegrees", 35f, "Maximum angle in degrees that a shot may turn from the muzzle toward the center-screen aim point. Set to 0 to disable correction. This is a " + $"per-player setting and is not synchronized. Range: {0f}-{90f}.");
			addToLootPoolConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("Spawning", "AddToLootPool", true, "Whether the Arrow Blowgun is included in the vanilla blowgun's random loot pools. In multiplayer, the room creator's value is used for everyone.");
			if (usesConfig.Value < 1)
			{
				Log.LogWarning((object)$"Configured Uses value {usesConfig.Value} is invalid; using {1}.");
				usesConfig.Value = 1;
			}
			ValidateFloatConfig(shotUseTimeConfig, 1f, 0f, 10f);
			ValidateFloatConfig(aimCorrectionDegreesConfig, 35f, 0f, 90f);
			effectiveUses = usesConfig.Value;
			effectiveAddToLootPool = addToLootPoolConfig.Value;
			((Component)this).gameObject.AddComponent<RoomConfigSynchronizer>().Initialize(this);
			prefabContainer = new GameObject("com.github.jie65535.ArrowBlowgun.Prefabs");
			prefabContainer.SetActive(false);
			Object.DontDestroyOnLoad((Object)(object)prefabContainer);
			((MonoBehaviour)this).StartCoroutine(ArrowTrapFeedback.Initialize());
			((MonoBehaviour)this).StartCoroutine(RegisterArrowBlowgun());
			((MonoBehaviour)this).StartCoroutine(WarmUpArrowVisual());
			Log.LogInfo((object)"Plugin ArrowBlowgun is loaded!");
		}

		private static IEnumerator WarmUpArrowVisual()
		{
			while ((Object)(object)Character.localCharacter == (Object)null)
			{
				yield return null;
			}
			yield return null;
			ArrowVisualFactory.WarmUp();
			Item registeredItem = RegisteredItem;
			if ((Object)(object)registeredItem != (Object)null)
			{
				int num = ArrowVisualFactory.AttachLoadedArrowVisuals(registeredItem);
				Log.LogInfo((object)$"Attached loaded arrow visuals to {num} Arrow Blowgun objects.");
			}
		}

		private IEnumerator RegisterArrowBlowgun()
		{
			yield return null;
			yield return null;
			ItemDatabase instance = SingletonAsset<ItemDatabase>.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				Log.LogError((object)"ItemDatabase could not be loaded.");
				yield break;
			}
			Item val = ((IEnumerable<Item>)((DatabaseAsset<ItemDatabase, Item>)(object)instance).Objects).FirstOrDefault((Func<Item, bool>)((Item item) => (Object)(object)item != (Object)null && (Object)(object)((Component)item).GetComponent<Action_RaycastDart>() != (Object)null));
			if ((Object)(object)val == (Object)null)
			{
				Log.LogError((object)"Could not find the vanilla blowgun item with Action_RaycastDart.");
				yield break;
			}
			GameObject val2 = Object.Instantiate<GameObject>(((Component)val).gameObject, prefabContainer.transform);
			((Object)val2).name = "ArrowBlowgun";
			Item component = val2.GetComponent<Item>();
			Action_RaycastDart component2 = val2.GetComponent<Action_RaycastDart>();
			if ((Object)(object)component == (Object)null || (Object)(object)component2 == (Object)null)
			{
				Log.LogError((object)"The cloned blowgun is missing Item or Action_RaycastDart.");
				Object.Destroy((Object)(object)val2);
				yield break;
			}
			((Behaviour)component2).enabled = false;
			Action_FireArrow action_FireArrow = val2.AddComponent<Action_FireArrow>();
			action_FireArrow.CopyFrom(component2, aimCorrectionDegreesConfig.Value);
			component.UIData.itemName = "ARROW_BLOWGUN";
			component.UIData.isShootable = true;
			component.UIData.hideFuel = effectiveUses <= 1;
			component.usingTimePrimary = shotUseTimeConfig.Value;
			component.totalUses = effectiveUses;
			LootData component3 = ((Component)component).GetComponent<LootData>();
			if ((Object)(object)component3 != (Object)null)
			{
				originalLootSpawnLocations = component3.spawnLocations;
				ApplyLootPoolSetting(component);
			}
			else
			{
				Log.LogWarning((object)"The cloned Arrow Blowgun has no LootData component.");
			}
			RegisterItemName();
			RegisterItem(instance, component);
			LootData.AllSpawnWeightData = null;
			RegisteredItem = component;
			Log.LogInfo((object)("Registered " + ((Object)((Component)component).gameObject).name + " from vanilla source " + ((Object)((Component)val).gameObject).name + " " + $"with item ID {component.itemID}, {component.totalUses} uses, " + $"{component.usingTimePrimary:0.###} second use time, and " + $"{aimCorrectionDegreesConfig.Value:0.###} degree aim correction."));
		}

		internal void ApplyEffectiveUses(int uses, string source)
		{
			if (uses < 1)
			{
				Log.LogWarning((object)$"Ignoring invalid synchronized Uses value {uses} from {source}.");
				return;
			}
			bool flag = effectiveUses != uses;
			effectiveUses = uses;
			Item registeredItem = RegisteredItem;
			if ((Object)(object)registeredItem != (Object)null)
			{
				Item[] array = Resources.FindObjectsOfTypeAll<Item>();
				foreach (Item val in array)
				{
					if ((Object)(object)val == (Object)null || val.itemID != registeredItem.itemID)
					{
						continue;
					}
					int totalUses = val.totalUses;
					val.UIData.hideFuel = uses <= 1;
					val.totalUses = uses;
					if ((Object)(object)val != (Object)(object)registeredItem && val.HasData((DataEntryKey)2))
					{
						OptionableIntItemData data = val.GetData<OptionableIntItemData>((DataEntryKey)2);
						if (data.HasData && data.Value == totalUses)
						{
							data.Value = uses;
							val.SetUseRemainingPercentage(1f);
						}
					}
				}
			}
			if (flag)
			{
				Log.LogInfo((object)$"Arrow Blowgun uses set to {uses} from {source}.");
			}
		}

		internal void ApplyEffectiveAddToLootPool(bool addToLootPool, string source)
		{
			bool flag = effectiveAddToLootPool != addToLootPool;
			effectiveAddToLootPool = addToLootPool;
			Item registeredItem = RegisteredItem;
			if ((Object)(object)registeredItem != (Object)null)
			{
				Item[] array = Resources.FindObjectsOfTypeAll<Item>();
				foreach (Item val in array)
				{
					if ((Object)(object)val != (Object)null && val.itemID == registeredItem.itemID)
					{
						ApplyLootPoolSetting(val);
					}
				}
				LootData.AllSpawnWeightData = null;
			}
			if (flag)
			{
				Log.LogInfo((object)("Arrow Blowgun random loot spawning " + (addToLootPool ? "enabled" : "disabled") + " from " + source + "."));
			}
		}

		private void ApplyLootPoolSetting(Item item)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			LootData component = ((Component)item).GetComponent<LootData>();
			if ((Object)(object)component != (Object)null)
			{
				component.spawnLocations = (SpawnPool)(effectiveAddToLootPool ? ((int)originalLootSpawnLocations) : 0);
			}
		}

		private void ValidateFloatConfig(ConfigEntry<float> config, float defaultValue, float minimum, float maximum)
		{
			float value = config.Value;
			if (float.IsNaN(value) || float.IsInfinity(value))
			{
				Log.LogWarning((object)($"Configured {((ConfigEntryBase)config).Definition.Key} value {value} is invalid; " + $"using {defaultValue}."));
				config.Value = defaultValue;
				return;
			}
			float num = Mathf.Clamp(value, minimum, maximum);
			if (!Mathf.Approximately(value, num))
			{
				Log.LogWarning((object)($"Configured {((ConfigEntryBase)config).Definition.Key} value {value} is outside the " + $"supported range {minimum}-{maximum}; using {num}."));
				config.Value = num;
			}
		}

		private static void RegisterItem(ItemDatabase database, Item item)
		{
			((Object)((Component)item).gameObject).name = "com.github.jie65535.ArrowBlowgun:ArrowBlowgun";
			item.itemID = GetStableItemId(database, ((Object)((Component)item).gameObject).name);
			string prefabId = "0_Items/" + ((Object)((Component)item).gameObject).name;
			PhotonNetwork.PrefabPool = (IPunPrefabPool)(object)new ArrowBlowgunPrefabPool(PhotonNetwork.PrefabPool, prefabId, ((Component)item).gameObject);
			((DatabaseAsset<ItemDatabase, Item>)(object)database).Objects.Add(item);
			database.itemLookup.Add(item.itemID, item);
		}

		private static ushort GetStableItemId(ItemDatabase database, string uniqueName)
		{
			using MD5 mD = MD5.Create();
			byte[] value = mD.ComputeHash(Encoding.UTF8.GetBytes(uniqueName));
			ushort num = BitConverter.ToUInt16(value, 0);
			ushort num2 = num;
			do
			{
				if (!database.itemLookup.ContainsKey(num2))
				{
					return num2;
				}
				num2++;
			}
			while (num2 != num);
			throw new InvalidOperationException("No free item ID is available for ArrowBlowgun.");
		}

		private static void RegisterItemName()
		{
			string key = LocalizedText.GetNameIndex("ARROW_BLOWGUN").ToUpperInvariant();
			int count = LocalizedText.mainTable.Values.FirstOrDefault()?.Count ?? Enum.GetValues(typeof(Language)).Length;
			List<string> list = Enumerable.Repeat("Arrow Blowgun", count).ToList();
			SetLocalizedName(list, (Language)9, "箭矢吹箭筒");
			SetLocalizedName(list, (Language)10, "箭矢吹箭筒");
			LocalizedText.mainTable[key] = list;
		}

		private static void SetLocalizedName(List<string> names, Language language, string value)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Expected I4, but got Unknown
			int num = (int)language;
			if (num < names.Count)
			{
				names[num] = value;
			}
		}
	}
	internal sealed class RoomConfigSynchronizer : MonoBehaviourPunCallbacks
	{
		private const string UsesPropertyKey = "com.github.jie65535.ArrowBlowgun.Uses";

		private const string AddToLootPoolPropertyKey = "com.github.jie65535.ArrowBlowgun.AddToLootPool";

		private Plugin plugin;

		internal void Initialize(Plugin owner)
		{
			plugin = owner;
			if (PhotonNetwork.InRoom)
			{
				SynchronizeRoomConfig();
			}
		}

		public override void OnJoinedRoom()
		{
			((MonoBehaviourPunCallbacks)this).OnJoinedRoom();
			SynchronizeRoomConfig();
		}

		public override void OnLeftRoom()
		{
			((MonoBehaviourPunCallbacks)this).OnLeftRoom();
			plugin.ApplyEffectiveUses(plugin.ConfiguredUses, "local config");
			plugin.ApplyEffectiveAddToLootPool(plugin.ConfiguredAddToLootPool, "local config");
		}

		public override void OnRoomPropertiesUpdate(Hashtable propertiesThatChanged)
		{
			((MonoBehaviourPunCallbacks)this).OnRoomPropertiesUpdate(propertiesThatChanged);
			if (((Dictionary<object, object>)(object)propertiesThatChanged).ContainsKey((object)"com.github.jie65535.ArrowBlowgun.Uses"))
			{
				TryApplyRoomUses();
			}
			if (((Dictionary<object, object>)(object)propertiesThatChanged).ContainsKey((object)"com.github.jie65535.ArrowBlowgun.AddToLootPool"))
			{
				TryApplyRoomLootPoolSetting();
			}
		}

		public override void OnMasterClientSwitched(Player newMasterClient)
		{
			((MonoBehaviourPunCallbacks)this).OnMasterClientSwitched(newMasterClient);
			SynchronizeRoomConfig();
		}

		private void SynchronizeRoomConfig()
		{
			bool hasRoomUses = TryApplyRoomUses();
			bool hasRoomLootPoolSetting = TryApplyRoomLootPoolSetting();
			if (PhotonNetwork.IsMasterClient)
			{
				PublishMissingRoomConfig(hasRoomUses, hasRoomLootPoolSetting);
			}
		}

		private bool TryApplyRoomUses()
		{
			if (PhotonNetwork.CurrentRoom == null || !((Dictionary<object, object>)(object)((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties).TryGetValue((object)"com.github.jie65535.ArrowBlowgun.Uses", out object value) || !(value is int uses))
			{
				return false;
			}
			plugin.ApplyEffectiveUses(uses, "room config");
			return true;
		}

		private bool TryApplyRoomLootPoolSetting()
		{
			if (PhotonNetwork.CurrentRoom == null || !((Dictionary<object, object>)(object)((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties).TryGetValue((object)"com.github.jie65535.ArrowBlowgun.AddToLootPool", out object value) || !(value is bool addToLootPool))
			{
				return false;
			}
			plugin.ApplyEffectiveAddToLootPool(addToLootPool, "room config");
			return true;
		}

		private void PublishMissingRoomConfig(bool hasRoomUses, bool hasRoomLootPoolSetting)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Expected O, but got Unknown
			if (PhotonNetwork.CurrentRoom != null)
			{
				Hashtable val = new Hashtable();
				if (!hasRoomUses)
				{
					int configuredUses = plugin.ConfiguredUses;
					plugin.ApplyEffectiveUses(configuredUses, "host config");
					val[(object)"com.github.jie65535.ArrowBlowgun.Uses"] = configuredUses;
				}
				if (!hasRoomLootPoolSetting)
				{
					bool configuredAddToLootPool = plugin.ConfiguredAddToLootPool;
					plugin.ApplyEffectiveAddToLootPool(configuredAddToLootPool, "host config");
					val[(object)"com.github.jie65535.ArrowBlowgun.AddToLootPool"] = configuredAddToLootPool;
				}
				if (((Dictionary<object, object>)(object)val).Count > 0)
				{
					PhotonNetwork.CurrentRoom.SetCustomProperties(val, (Hashtable)null, (WebFlags)null);
				}
			}
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}