Decompiled source of AmmoVariants v1.0.0

AmmoVariants.dll

Decompiled 13 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("AmmoVariants")]
[assembly: AssemblyProduct("AmmoVariants")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: ComVisible(false)]
[assembly: InternalsVisibleTo("AmmoVariantsCheck")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[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 AmmoVariants
{
	internal static class AmmoAssets
	{
		private static readonly Dictionary<string, Sprite> Icons = new Dictionary<string, Sprite>();

		private static readonly Dictionary<int, AudioClip> Sounds = new Dictionary<int, AudioClip>();

		private static readonly Dictionary<GameObject, GameObject> ReleaseSounds = new Dictionary<GameObject, GameObject>();

		private static readonly Dictionary<EffectList, EffectList> QuietEffects = new Dictionary<EffectList, EffectList>();

		private static readonly MethodInfo CloneEffect = typeof(object).GetMethod("MemberwiseClone", BindingFlags.Instance | BindingFlags.NonPublic);

		private static AssetBundle bundle;

		internal static Shader TrailShader;

		internal static byte[] Bytes(string suffix)
		{
			Assembly assembly = typeof(Plugin).Assembly;
			string name = assembly.GetManifestResourceNames().Single((string n) => n.EndsWith(suffix, StringComparison.Ordinal));
			using Stream stream = assembly.GetManifestResourceStream(name);
			using MemoryStream memoryStream = new MemoryStream();
			stream.CopyTo(memoryStream);
			return memoryStream.ToArray();
		}

		internal static void Load()
		{
			if ((Object)(object)TrailShader != (Object)null)
			{
				return;
			}
			bundle = AssetBundle.LoadFromMemory(Bytes("ammo_visuals"));
			TrailShader = bundle.LoadAsset<Shader>("Assets/AmmoTrail.shader");
			if ((Object)(object)TrailShader == (Object)null)
			{
				throw new InvalidOperationException("ammo trail shader unavailable");
			}
			string[] array;
			foreach (string item in Items.BoltBases.Concat(Items.ArrowBases))
			{
				array = new string[2] { "Scatter", "Piercing" };
				foreach (string text in array)
				{
					LoadIcon(item + text);
				}
			}
			array = Items.EnergyBases;
			for (int i = 0; i < array.Length; i++)
			{
				LoadIcon(array[i] + "Energy");
			}
			string[] array2 = new string[6] { "scatter_bow", "scatter_crossbow", "piercing_bow", "piercing_crossbow", "energy_bow", "energy_crossbow" };
			for (int j = 0; j < array2.Length; j++)
			{
				Sounds.Add(j + 2, LoadWave(array2[j]));
			}
			Plugin.Log.LogInfo((object)"loaded 42 ammo icons, six firing sounds and transparent trail shader");
		}

		private static void LoadIcon(string name)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Expected O, but got Unknown
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
			if (!(bool)Type.GetType("UnityEngine.ImageConversion, UnityEngine.ImageConversionModule", throwOnError: true).GetMethods().First(delegate(MethodInfo m)
			{
				try
				{
					ParameterInfo[] parameters = m.GetParameters();
					return m.Name == "LoadImage" && parameters.Length == 3 && parameters[1].ParameterType == typeof(byte[]);
				}
				catch (TypeLoadException)
				{
					return false;
				}
			})
				.Invoke(null, new object[3]
				{
					val,
					Bytes(name + ".png"),
					false
				}))
			{
				throw new InvalidOperationException("invalid icon " + name);
			}
			((Object)val).name = name;
			Sprite val2 = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f));
			((Object)val2).name = name;
			Icons.Add(name, val2);
		}

		internal static Sprite Icon(string name)
		{
			return Icons[name];
		}

		internal static void RegisterReleaseSounds()
		{
			string[] array = new string[2] { "sfx_bow_fire", "sfx_arbalest_fire" };
			foreach (string text in array)
			{
				GameObject prefab = PrefabManager.Instance.GetPrefab(text);
				if ((Object)(object)prefab == (Object)null)
				{
					Plugin.Log.LogWarning((object)("missing native release sound " + text));
				}
				else if (!ReleaseSounds.ContainsKey(prefab))
				{
					GameObject val = PrefabManager.Instance.CreateClonedPrefab("AmmoVariants_" + text, prefab);
					ZSFX[] componentsInChildren = val.GetComponentsInChildren<ZSFX>(true);
					foreach (ZSFX obj in componentsInChildren)
					{
						obj.m_minVol *= Plugin.NativeReleaseVolume.Value;
						obj.m_maxVol *= Plugin.NativeReleaseVolume.Value;
					}
					AudioSource[] componentsInChildren2 = val.GetComponentsInChildren<AudioSource>(true);
					foreach (AudioSource obj2 in componentsInChildren2)
					{
						obj2.volume *= Plugin.NativeReleaseVolume.Value;
					}
					PrefabManager.Instance.AddPrefab(val);
					ReleaseSounds.Add(prefab, val);
				}
			}
			if (Plugin.LogCounters.Value)
			{
				Plugin.Log.LogInfo((object)$"registered {ReleaseSounds.Count} native release sound copies at volume {Plugin.NativeReleaseVolume.Value:F2}, ammo accents {Plugin.FiringSoundVolume.Value:F2}");
			}
		}

		internal static EffectList ReleaseEffects(EffectList effects, bool variant)
		{
			//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_004e: Expected O, but got Unknown
			if (!variant || effects == null)
			{
				return effects;
			}
			if (QuietEffects.TryGetValue(effects, out var value))
			{
				return value;
			}
			int replaced = 0;
			EffectList val = new EffectList
			{
				m_effectPrefabs = ((IEnumerable<EffectData>)effects.m_effectPrefabs).Select((Func<EffectData, EffectData>)delegate(EffectData effect)
				{
					//IL_0033: 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_0050: Expected O, but got Unknown
					if (effect != null && !((Object)(object)effect.m_prefab == (Object)null) && ReleaseSounds.TryGetValue(effect.m_prefab, out var value2))
					{
						EffectData val2 = (EffectData)CloneEffect.Invoke(effect, null);
						val2.m_prefab = value2;
						replaced++;
						return val2;
					}
					return effect;
				}).ToArray()
			};
			QuietEffects.Add(effects, val);
			if (Plugin.LogCounters.Value && replaced > 0)
			{
				Plugin.Log.LogInfo((object)("variant native release effects replaced " + replaced));
			}
			return val;
		}

		internal static GameObject[] CreateRelease(EffectList effects, Vector3 basePos, Quaternion baseRot, Transform baseParent, float scale, int variant, ZDOID gamepadEffectsExclusiveToPlayer, Attack attack)
		{
			//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_0014: Unknown result type (might be due to invalid IL or missing references)
			return ReleaseEffects(effects, Shots.IsVariantAttack(attack)).Create(basePos, baseRot, baseParent, scale, variant, gamepadEffectsExclusiveToPlayer);
		}

		private static AudioClip LoadWave(string name)
		{
			using BinaryReader binaryReader = new BinaryReader(new MemoryStream(Bytes(name + ".wav")));
			if (new string(binaryReader.ReadChars(4)) != "RIFF")
			{
				throw new InvalidDataException(name);
			}
			binaryReader.ReadInt32();
			binaryReader.ReadChars(4);
			int num = 0;
			int num2 = 0;
			int num3 = 0;
			byte[] array = null;
			while (binaryReader.BaseStream.Position + 8 <= binaryReader.BaseStream.Length)
			{
				string text = new string(binaryReader.ReadChars(4));
				int num4 = binaryReader.ReadInt32();
				long position = binaryReader.BaseStream.Position + num4 + (num4 & 1);
				if (text == "fmt ")
				{
					if (binaryReader.ReadInt16() != 1)
					{
						throw new InvalidDataException(name);
					}
					num = binaryReader.ReadInt16();
					num2 = binaryReader.ReadInt32();
					binaryReader.ReadInt32();
					binaryReader.ReadInt16();
					num3 = binaryReader.ReadInt16();
				}
				else if (text == "data")
				{
					array = binaryReader.ReadBytes(num4);
				}
				binaryReader.BaseStream.Position = position;
			}
			if (array == null || num3 != 16 || num != 1)
			{
				throw new InvalidDataException(name);
			}
			float[] array2 = new float[array.Length / 2];
			for (int i = 0; i < array2.Length; i++)
			{
				array2[i] = (float)BitConverter.ToInt16(array, i * 2) / 32768f;
			}
			AudioClip val = AudioClip.Create(name, array2.Length, num, num2, false);
			if (!(bool)typeof(AudioClip).GetMethods().First(delegate(MethodInfo m)
			{
				try
				{
					ParameterInfo[] parameters = m.GetParameters();
					return m.Name == "SetData" && parameters.Length == 2 && parameters[0].ParameterType == typeof(float[]);
				}
				catch (TypeLoadException)
				{
					return false;
				}
			}).Invoke(val, new object[2] { array2, 0 }))
			{
				throw new InvalidDataException(name);
			}
			return val;
		}

		internal static void Play(int code, Vector3 position)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			//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_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Expected O, but got Unknown
			if ((int)SystemInfo.graphicsDeviceType == 4 || !Sounds.TryGetValue(code, out var value) || Plugin.FiringSoundVolume.Value <= 0f)
			{
				return;
			}
			string text = (((code & 1) == 0) ? "sfx_bow_fire" : "sfx_arbalest_fire");
			GameObject val = PrefabManager.Instance.GetPrefab(text) ?? PrefabManager.Instance.GetPrefab("sfx_bow_fire");
			AudioSource val2 = (((Object)(object)val != (Object)null) ? val.GetComponentInChildren<AudioSource>(true) : null);
			if ((Object)(object)val2 == (Object)null || (Object)(object)val2.outputAudioMixerGroup == (Object)null)
			{
				Plugin.Log.LogWarning((object)"ammo firing sound skipped because the game SFX mixer was unavailable");
				return;
			}
			GameObject val3 = new GameObject("AmmoFiringSound");
			val3.transform.position = position;
			AudioSource obj = val3.AddComponent<AudioSource>();
			obj.clip = value;
			obj.outputAudioMixerGroup = val2.outputAudioMixerGroup;
			obj.spatialBlend = 1f;
			obj.rolloffMode = (AudioRolloffMode)1;
			obj.minDistance = 2f;
			obj.maxDistance = 40f;
			obj.volume = Plugin.FiringSoundVolume.Value;
			obj.Play();
			Object.Destroy((Object)val3, value.length + 0.1f);
			if (Plugin.LogCounters.Value)
			{
				Plugin.Log.LogInfo((object)("ammo firing sound " + ((Object)value).name));
			}
		}
	}
	public sealed class AmmoFlight : MonoBehaviour
	{
		private ZNetView view;

		private float waited;

		internal void Played()
		{
			((Behaviour)this).enabled = false;
		}

		private void Awake()
		{
			view = ((Component)this).GetComponent<ZNetView>();
		}

		private void Update()
		{
			//IL_0086: 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)
			waited += Time.deltaTime;
			if (waited > 2f)
			{
				((Behaviour)this).enabled = false;
			}
			else
			{
				if ((Object)(object)view == (Object)null || !view.IsValid())
				{
					return;
				}
				int num = view.GetZDO().GetInt("AmmoVariants.Sound", 0);
				if (num != 0)
				{
					if (num >= 2 && waited < 0.5f)
					{
						AmmoAssets.Play(num, view.GetZDO().GetVec3("AmmoVariants.Sound.Origin", ((Component)this).transform.position));
					}
					((Behaviour)this).enabled = false;
				}
			}
		}
	}
	public sealed class AmmoBallistaTrail : MonoBehaviour
	{
		internal static readonly string[] AmmoNames = new string[5] { "TurretBoltWood", "TurretBoltBone", "TurretBolt", "TurretBoltFlametal", "TurretBoltBloodgold" };

		private static readonly Dictionary<string, string> Labels = new Dictionary<string, string>();

		private static readonly HashSet<string> Logged = new HashSet<string>();

		private static readonly int TintKey = StringExtensionMethods.GetStableHashCode("AmmoVariants_ballista_ammo");

		private const float WidthShare = 0.07f;

		private const float MinimumWidth = 0.12f;

		private const float MaximumWidth = 0.22f;

		private const float Opacity = 0.6f;

		private const float CleanupMargin = 0.1f;

		private string ammoName;

		private bool started;

		private bool finished;

		private bool receivedTint;

		private float elapsed;

		private TrailRenderer trail;

		private AmmoTrailDissolve path;

		private Projectile projectile;

		private ZNetView view;

		internal static void Register()
		{
			string[] ammoNames = AmmoNames;
			foreach (string text in ammoNames)
			{
				GameObject prefab = PrefabManager.Instance.GetPrefab(text);
				SharedData val = ((prefab != null) ? prefab.GetComponent<ItemDrop>() : null)?.m_itemData.m_shared;
				GameObject val2 = val?.m_attack?.m_attackProjectile;
				if (!((Object)(object)val2 == (Object)null))
				{
					Labels[val.m_name] = text;
					if (AmmoTrailSettings.Ballista && (Object)(object)val2.GetComponent<AmmoBallistaTrail>() == (Object)null)
					{
						val2.AddComponent<AmmoBallistaTrail>();
					}
				}
			}
		}

		internal static void Attach(Projectile projectile, ItemData ammo)
		{
			if (ammo?.m_shared?.m_ammoType != "$ammo_turretbolt")
			{
				return;
			}
			string value = (((Object)(object)ammo.m_dropPrefab != (Object)null) ? ((Object)ammo.m_dropPrefab).name : null);
			if ((value == null || Array.IndexOf(AmmoNames, value) < 0) && !Labels.TryGetValue(ammo.m_shared.m_name, out value))
			{
				return;
			}
			ZNetView component = ((Component)projectile).GetComponent<ZNetView>();
			if ((Object)(object)component != (Object)null && component.IsValid() && component.IsOwner())
			{
				component.GetZDO().Set(TintKey, value);
			}
			if (AmmoTrailSettings.Ballista)
			{
				AmmoBallistaTrail ammoBallistaTrail = ((Component)projectile).GetComponent<AmmoBallistaTrail>();
				if ((Object)(object)ammoBallistaTrail == (Object)null)
				{
					ammoBallistaTrail = ((Component)projectile).gameObject.AddComponent<AmmoBallistaTrail>();
				}
				ammoBallistaTrail.ammoName = value;
				ammoBallistaTrail.receivedTint = true;
				ammoBallistaTrail.view = component;
				ammoBallistaTrail.Begin();
			}
		}

		private Color ColorOf()
		{
			//IL_0020: 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_007b: Unknown result type (might be due to invalid IL or missing references)
			if (ammoName == "TurretBoltFlametal")
			{
				return Color32.op_Implicit(new Color32((byte)207, (byte)96, (byte)65, byte.MaxValue));
			}
			return AmmoPalette.MaterialColor((ammoName == "TurretBolt") ? "Blackmetal" : ((ammoName == "TurretBoltBloodgold") ? "BloodGold" : ((ammoName == "TurretBoltBone") ? "Bone" : "Wood")));
		}

		internal void Begin()
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected O, but got Unknown
			//IL_0066: 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)
			//IL_0087: 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_0090: 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_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: 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)
			//IL_00c3: 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_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: 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_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			if (started || finished || !receivedTint || !AmmoTrailSettings.Ballista)
			{
				return;
			}
			projectile = ((Component)this).GetComponent<Projectile>();
			if (!((Object)(object)projectile != (Object)null) || !Shots.FlightEnded(projectile))
			{
				started = true;
				GameObject val = new GameObject("AmmoBallistaPath");
				val.transform.position = ((Component)this).transform.position;
				trail = val.AddComponent<TrailRenderer>();
				Bounds val2 = AmmoModels.BoundsOf(((Component)this).gameObject);
				Vector3 size = ((Bounds)(ref val2)).size;
				Color val3 = ColorOf();
				val3.a = 0.6f;
				Color val4 = default(Color);
				((Color)(ref val4))..ctor(val3.r, val3.g, val3.b, 0f);
				Color middle = val3;
				middle.a *= 0.7f;
				trail.startWidth = Mathf.Clamp(Mathf.Max(size.x, Mathf.Max(size.y, size.z)) * 0.07f, 0.12f, 0.22f);
				trail.endWidth = 0f;
				trail.startColor = val3;
				trail.endColor = val4;
				trail.colorGradient = AmmoVisuals.Gradient(val3, middle, val4);
				((Renderer)trail).sharedMaterial = AmmoVisuals.TrailMaterial();
				trail.minVertexDistance = 0.02f;
				trail.alignment = (LineAlignment)0;
				((Renderer)trail).shadowCastingMode = (ShadowCastingMode)0;
				((Renderer)trail).receiveShadows = false;
				trail.emitting = false;
				((Renderer)trail).enabled = true;
				trail.Clear();
				trail.AddPosition(((Component)this).transform.position);
				path = val.AddComponent<AmmoTrailDissolve>();
				path.Prepare(trail, null);
				if (Plugin.LogCounters.Value && Logged.Add(ammoName ?? ((Object)this).name))
				{
					Plugin.Log.LogInfo((object)$"ballista visual trail started {ammoName ?? ((Object)this).name}, width {trail.startWidth:F3}, opacity {0.6f:F2}, hold {1f:F2}, impact fade {1f:F2}, mechanics unchanged");
				}
			}
		}

		private void LateUpdate()
		{
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			if (finished)
			{
				return;
			}
			if ((Object)(object)view == (Object)null)
			{
				view = ((Component)this).GetComponent<ZNetView>();
			}
			if (!receivedTint && (Object)(object)view != (Object)null && view.IsValid())
			{
				string value = view.GetZDO().GetString(TintKey, "");
				if (Array.IndexOf(AmmoNames, value) >= 0)
				{
					ammoName = value;
					receivedTint = true;
				}
			}
			if (!started)
			{
				if (receivedTint && (Object)(object)view != (Object)null && view.IsValid())
				{
					Begin();
				}
			}
			else
			{
				if ((Object)(object)trail == (Object)null)
				{
					return;
				}
				if ((Object)(object)projectile != (Object)null && Shots.FlightEnded(projectile))
				{
					Release();
					return;
				}
				((Component)trail).transform.position = ((Component)this).transform.position;
				elapsed += Time.deltaTime;
				trail.time = elapsed + 2f + 0.1f;
				if (trail.positionCount == 0 || Vector3.Distance(trail.GetPosition(trail.positionCount - 1), ((Component)this).transform.position) >= 0.02f)
				{
					path.RecordPoint(((Component)this).transform.position);
				}
			}
		}

		internal void Release()
		{
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: 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)
			if (finished)
			{
				return;
			}
			finished = true;
			if (!((Object)(object)trail == (Object)null) && !((Object)(object)path == (Object)null))
			{
				if (trail.positionCount == 0 || Vector3.Distance(trail.GetPosition(trail.positionCount - 1), ((Component)this).transform.position) >= 0.02f)
				{
					path.RecordPoint(((Component)this).transform.position);
				}
				trail.emitting = false;
				path.Release();
				Object.Destroy((Object)(object)((Component)trail).gameObject, 1.1f);
				trail = null;
			}
		}

		private void OnDisable()
		{
			//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)
			Scene scene = ((Component)this).gameObject.scene;
			if (((Scene)(ref scene)).isLoaded)
			{
				Release();
			}
		}
	}
	internal static class AmmoCompatibility
	{
		internal const string BetterArcheryGuid = "ishid4.mods.betterarchery";

		internal static void Init(Harmony harmony)
		{
			if (Chainloader.PluginInfos.TryGetValue("ishid4.mods.betterarchery", out var value))
			{
				Patch(harmony, ((object)value.Instance).GetType().Assembly);
			}
		}

		internal static void Patch(Harmony harmony, Assembly assembly)
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Expected O, but got Unknown
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Expected O, but got Unknown
			MethodInfo methodInfo = assembly.GetType("BetterArchery.NockedArrow")?.GetMethod("BuildVisual", BindingFlags.Static | BindingFlags.NonPublic);
			MethodInfo methodInfo2 = assembly.GetType("BetterArchery.RetrieveArrows")?.GetMethod("Prefix", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			if (methodInfo != null)
			{
				harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(AmmoCompatibility), "Nocked", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			if (methodInfo2 != null)
			{
				harmony.Patch((MethodBase)methodInfo2, new HarmonyMethod(typeof(AmmoCompatibility), "Recovery", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			Plugin.Log.LogInfo((object)$"BetterArchery variant compatibility, static held visual {methodInfo != null}, recovery bypass {methodInfo2 != null}, aim and draw retained");
		}

		private static bool Nocked(ItemData __0, ref GameObject __result)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			Items.AmmoKind ammoKind = Items.KindOf(__0);
			if (ammoKind == Items.AmmoKind.None)
			{
				return true;
			}
			__result = new GameObject("BA_NockedArrow");
			AmmoModels.Visual(__0.m_shared.m_attack.m_attackProjectile, ammoKind == Items.AmmoKind.Scatter, nocked: true).transform.SetParent(__result.transform, false);
			return false;
		}

		private static bool Recovery(ItemData ammo, ref bool __result)
		{
			if (Items.KindOf(ammo) == Items.AmmoKind.None)
			{
				return true;
			}
			__result = true;
			return false;
		}
	}
	internal static class AmmoDisplayEffects
	{
		private const float RadiusShare = 0.035f;

		private const float ScatterSizeShare = 0.42f;

		private const float MinimumRadius = 0.008f;

		private const float MaximumRadius = 0.045f;

		private const float ParticleLifetime = 0.22f;

		private const int ParticleLimit = 12;

		private const float ParticleRate = 14f;

		private const float TrailLifetime = 0.08f;

		private const int GlowTextureSize = 32;

		private const float GlowOpacity = 0.8f;

		private const float GlowSizeShare = 2.2f;

		private static Material auraMaterial;

		internal static void Add(GameObject projectile, Transform shaft, Vector3 tip, float length, bool scatter)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_027d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0282: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0301: Unknown result type (might be due to invalid IL or missing references)
			//IL_0303: Unknown result type (might be due to invalid IL or missing references)
			//IL_0314: Unknown result type (might be due to invalid IL or missing references)
			//IL_0328: 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_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			bool flag = Items.EnergyProjectiles.Contains(projectile);
			bool flag2 = ((Object)projectile).name.StartsWith("ArrowFrost");
			ParticleSystem[] componentsInChildren = projectile.GetComponentsInChildren<ParticleSystem>(true);
			if (!flag && componentsInChildren.Length == 0)
			{
				return;
			}
			GameObject val = new GameObject("AmmoTipEffects");
			val.SetActive(false);
			val.transform.SetParent(shaft, false);
			val.transform.localPosition = tip;
			val.transform.localScale = new Vector3(1f / shaft.localScale.x, 1f / shaft.localScale.y, 1f / shaft.localScale.z);
			float num = Mathf.Clamp(length * 0.035f * (scatter ? 0.42f : 1f), 0.008f, 0.045f);
			ParticleSystem[] array;
			if (flag)
			{
				AmmoVisuals.AddLightning(val);
			}
			else
			{
				array = componentsInChildren;
				foreach (ParticleSystem val2 in array)
				{
					GameObject val3 = Object.Instantiate<GameObject>(((Component)val2).gameObject, val.transform);
					((Object)val3).name = "AmmoTip_" + ((Object)val2).name;
					Transform[] array2 = ((IEnumerable)val3.transform).Cast<Transform>().ToArray();
					foreach (Transform obj in array2)
					{
						((Component)obj).gameObject.SetActive(false);
						Object.DestroyImmediate((Object)(object)((Component)obj).gameObject);
					}
					MonoBehaviour[] components = val3.GetComponents<MonoBehaviour>();
					for (int j = 0; j < components.Length; j++)
					{
						Object.DestroyImmediate((Object)(object)components[j]);
					}
					Collider[] components2 = val3.GetComponents<Collider>();
					for (int j = 0; j < components2.Length; j++)
					{
						Object.DestroyImmediate((Object)(object)components2[j]);
					}
					AudioSource[] components3 = val3.GetComponents<AudioSource>();
					for (int j = 0; j < components3.Length; j++)
					{
						Object.DestroyImmediate((Object)(object)components3[j]);
					}
					Light[] components4 = val3.GetComponents<Light>();
					for (int j = 0; j < components4.Length; j++)
					{
						Object.DestroyImmediate((Object)(object)components4[j]);
					}
					val3.transform.localPosition = Vector3.zero;
					val3.transform.localRotation = Quaternion.identity;
					val3.transform.localScale = Vector3.one;
					val3.SetActive(true);
				}
			}
			array = val.GetComponentsInChildren<ParticleSystem>(true);
			foreach (ParticleSystem val4 in array)
			{
				Configure(val4, num);
				if (flag2)
				{
					ParticleSystemRenderer component = ((Component)val4).GetComponent<ParticleSystemRenderer>();
					component.renderMode = (ParticleSystemRenderMode)0;
					((Renderer)component).sharedMaterial = AuraMaterial();
				}
			}
			Color val5 = AmmoPalette.ColorOf(projectile);
			val5.a = ((flag || flag2 || ((Object)projectile).name.StartsWith("ArrowPoison") || ((Object)projectile).name.StartsWith("ArrowFire")) ? 0.8f : 0f);
			if (val5.a > 0f)
			{
				GameObject val6 = new GameObject("AmmoTipAura");
				val6.transform.SetParent(val.transform, false);
				ParticleSystem obj2 = val6.AddComponent<ParticleSystem>();
				Configure(obj2, num);
				MainModule main = obj2.main;
				((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(val5);
				((MainModule)(ref main)).startSpeed = MinMaxCurve.op_Implicit(0f);
				((MainModule)(ref main)).startSize = MinMaxCurve.op_Implicit(num * 2.2f);
				((Renderer)((Component)obj2).GetComponent<ParticleSystemRenderer>()).sharedMaterial = AuraMaterial();
			}
			val.AddComponent<AmmoTipPlayback>().Ammo = ((Object)projectile).name;
			val.SetActive(true);
			if (Plugin.LogCounters.Value)
			{
				Plugin.Log.LogInfo((object)$"display tip effects {((Object)projectile).name}, local particles {val.GetComponentsInChildren<ParticleSystem>(true).Length}, radius {num:F3}, energy {flag}");
			}
		}

		private static Material AuraMaterial()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: 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_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Expected O, but got Unknown
			//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)
			if ((Object)(object)auraMaterial != (Object)null)
			{
				return auraMaterial;
			}
			Texture2D val = new Texture2D(32, 32, (TextureFormat)4, false);
			((Object)val).name = "AmmoVariants_tip_glow";
			((Texture)val).wrapMode = (TextureWrapMode)1;
			Color[] array = (Color[])(object)new Color[1024];
			for (int i = 0; i < 32; i++)
			{
				for (int j = 0; j < 32; j++)
				{
					float num = ((float)j + 0.5f) * 2f / 32f - 1f;
					float num2 = ((float)i + 0.5f) * 2f / 32f - 1f;
					float num3 = Mathf.Clamp01(1f - num * num - num2 * num2);
					num3 *= num3;
					array[i * 32 + j] = new Color(1f, 1f, 1f, num3);
				}
			}
			val.SetPixels(array);
			val.Apply(false, true);
			auraMaterial = new Material(AmmoAssets.TrailShader)
			{
				name = "AmmoVariants_tip_aura",
				mainTexture = (Texture)(object)val,
				color = Color.white
			};
			return auraMaterial;
		}

		private static void Configure(ParticleSystem system, float radius)
		{
			//IL_0009: 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_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: 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_00b1: 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_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: 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_00f4: 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_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: 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_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: 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_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: 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_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			system.Stop(false, (ParticleSystemStopBehavior)0);
			MainModule main = system.main;
			((MainModule)(ref main)).playOnAwake = true;
			((MainModule)(ref main)).startDelay = MinMaxCurve.op_Implicit(0f);
			((MainModule)(ref main)).loop = true;
			((MainModule)(ref main)).simulationSpace = (ParticleSystemSimulationSpace)0;
			((MainModule)(ref main)).scalingMode = (ParticleSystemScalingMode)0;
			((MainModule)(ref main)).startLifetime = MinMaxCurve.op_Implicit(0.22f);
			((MainModule)(ref main)).startSpeed = MinMaxCurve.op_Implicit(radius * 0.3f);
			((MainModule)(ref main)).startSize3D = false;
			((MainModule)(ref main)).startSize = new MinMaxCurve(radius * 0.35f, radius * 0.7f);
			((MainModule)(ref main)).gravityModifier = MinMaxCurve.op_Implicit(0f);
			((MainModule)(ref main)).maxParticles = 12;
			((MainModule)(ref main)).stopAction = (ParticleSystemStopAction)0;
			((MainModule)(ref main)).cullingMode = (ParticleSystemCullingMode)3;
			EmissionModule emission = system.emission;
			((EmissionModule)(ref emission)).enabled = true;
			((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(14f);
			((EmissionModule)(ref emission)).rateOverDistance = MinMaxCurve.op_Implicit(0f);
			((EmissionModule)(ref emission)).SetBursts((Burst[])(object)new Burst[0]);
			ShapeModule shape = system.shape;
			((ShapeModule)(ref shape)).enabled = false;
			VelocityOverLifetimeModule velocityOverLifetime = system.velocityOverLifetime;
			((VelocityOverLifetimeModule)(ref velocityOverLifetime)).enabled = false;
			ForceOverLifetimeModule forceOverLifetime = system.forceOverLifetime;
			((ForceOverLifetimeModule)(ref forceOverLifetime)).enabled = false;
			InheritVelocityModule inheritVelocity = system.inheritVelocity;
			((InheritVelocityModule)(ref inheritVelocity)).enabled = false;
			ExternalForcesModule externalForces = system.externalForces;
			((ExternalForcesModule)(ref externalForces)).enabled = false;
			SubEmittersModule subEmitters = system.subEmitters;
			((SubEmittersModule)(ref subEmitters)).enabled = false;
			LightsModule lights = system.lights;
			((LightsModule)(ref lights)).enabled = false;
			CollisionModule collision = system.collision;
			((CollisionModule)(ref collision)).enabled = false;
			TriggerModule trigger = system.trigger;
			((TriggerModule)(ref trigger)).enabled = false;
			SizeOverLifetimeModule sizeOverLifetime = system.sizeOverLifetime;
			((SizeOverLifetimeModule)(ref sizeOverLifetime)).enabled = false;
			SizeBySpeedModule sizeBySpeed = system.sizeBySpeed;
			((SizeBySpeedModule)(ref sizeBySpeed)).enabled = false;
			NoiseModule noise = system.noise;
			if (((NoiseModule)(ref noise)).enabled)
			{
				((NoiseModule)(ref noise)).separateAxes = false;
				((NoiseModule)(ref noise)).strength = MinMaxCurve.op_Implicit(radius * 0.35f);
			}
			TrailModule trails = system.trails;
			((TrailModule)(ref trails)).worldSpace = false;
			((TrailModule)(ref trails)).lifetime = MinMaxCurve.op_Implicit(0.08f);
			((TrailModule)(ref trails)).dieWithParticles = true;
			ParticleSystemRenderer component = ((Component)system).GetComponent<ParticleSystemRenderer>();
			((Renderer)component).enabled = true;
			((Renderer)component).shadowCastingMode = (ShadowCastingMode)0;
			((Renderer)component).receiveShadows = false;
		}
	}
	public sealed class AmmoTipPlayback : MonoBehaviour
	{
		[SerializeField]
		internal string Ammo;

		private static readonly HashSet<string> Logged = new HashSet<string>();

		private void OnEnable()
		{
			ParticleSystem[] componentsInChildren = ((Component)this).GetComponentsInChildren<ParticleSystem>(true);
			ParticleSystem[] array = componentsInChildren;
			foreach (ParticleSystem val in array)
			{
				if (((Component)val).gameObject.activeInHierarchy)
				{
					val.Play(false);
				}
			}
			if (Plugin.LogCounters.Value && Logged.Add(Ammo ?? ((Object)this).name))
			{
				Plugin.Log.LogInfo((object)$"display tip playback {Ammo}, active systems {componentsInChildren.Length}");
			}
		}

		private void OnDisable()
		{
			ParticleSystem[] componentsInChildren = ((Component)this).GetComponentsInChildren<ParticleSystem>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				componentsInChildren[i].Stop(false, (ParticleSystemStopBehavior)0);
			}
		}
	}
	public sealed class AmmoLoadedVisual : MonoBehaviour
	{
		private GameObject visual;

		private GameObject prefab;

		private Renderer original;

		private bool originalEnabled;

		internal void Refresh(WeaponLoadState state, ItemData ammo)
		{
			Items.AmmoKind ammoKind = Items.KindOf(ammo);
			if (ammoKind == Items.AmmoKind.None)
			{
				if ((Object)(object)visual != (Object)null)
				{
					visual.SetActive(false);
					Object.Destroy((Object)(object)visual);
				}
				if ((Object)(object)original != (Object)null)
				{
					original.enabled = originalEnabled;
				}
				prefab = null;
				return;
			}
			GameObject attackProjectile = ammo.m_shared.m_attack.m_attackProjectile;
			if (!((Object)(object)attackProjectile == (Object)(object)prefab) || !((Object)(object)visual != (Object)null))
			{
				if ((Object)(object)visual != (Object)null)
				{
					visual.SetActive(false);
					Object.Destroy((Object)(object)visual);
				}
				prefab = attackProjectile;
				visual = AmmoModels.Visual(attackProjectile, ammoKind == Items.AmmoKind.Scatter);
				((Object)visual).name = "AmmoLoadedVariant";
				visual.transform.SetParent(state.m_loaded.transform, false);
				Position(state.m_loaded.transform, visual.transform);
				if (Plugin.LogCounters.Value)
				{
					Plugin.Log.LogInfo((object)("loaded crossbow variant model " + ((Object)attackProjectile).name));
				}
			}
		}

		private void Position(Transform loaded, Transform model)
		{
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: 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_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dd: 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_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: 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_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: 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_00c2: 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_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: 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_0211: Unknown result type (might be due to invalid IL or missing references)
			//IL_0216: Unknown result type (might be due to invalid IL or missing references)
			//IL_021a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0224: Unknown result type (might be due to invalid IL or missing references)
			//IL_0229: Unknown result type (might be due to invalid IL or missing references)
			//IL_022e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0242: Unknown result type (might be due to invalid IL or missing references)
			//IL_0246: Unknown result type (might be due to invalid IL or missing references)
			//IL_0250: Unknown result type (might be due to invalid IL or missing references)
			//IL_0255: Unknown result type (might be due to invalid IL or missing references)
			//IL_025a: Unknown result type (might be due to invalid IL or missing references)
			//IL_025f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0262: Unknown result type (might be due to invalid IL or missing references)
			//IL_0264: Unknown result type (might be due to invalid IL or missing references)
			//IL_0269: Unknown result type (might be due to invalid IL or missing references)
			//IL_026c: Unknown result type (might be due to invalid IL or missing references)
			//IL_026e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0273: Unknown result type (might be due to invalid IL or missing references)
			//IL_0275: Unknown result type (might be due to invalid IL or missing references)
			//IL_0277: Unknown result type (might be due to invalid IL or missing references)
			//IL_0279: Unknown result type (might be due to invalid IL or missing references)
			//IL_027e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0282: Unknown result type (might be due to invalid IL or missing references)
			//IL_0287: Unknown result type (might be due to invalid IL or missing references)
			//IL_028f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0294: Unknown result type (might be due to invalid IL or missing references)
			//IL_0298: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0392: Unknown result type (might be due to invalid IL or missing references)
			//IL_0399: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_03dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_03de: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0440: Unknown result type (might be due to invalid IL or missing references)
			//IL_0457: Unknown result type (might be due to invalid IL or missing references)
			//IL_0463: Unknown result type (might be due to invalid IL or missing references)
			//IL_034e: Unknown result type (might be due to invalid IL or missing references)
			//IL_035a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0303: Unknown result type (might be due to invalid IL or missing references)
			//IL_0308: Unknown result type (might be due to invalid IL or missing references)
			//IL_0325: Unknown result type (might be due to invalid IL or missing references)
			//IL_0327: Unknown result type (might be due to invalid IL or missing references)
			//IL_032c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0331: Unknown result type (might be due to invalid IL or missing references)
			MeshFilter val = null;
			float num = 0f;
			MeshFilter[] componentsInChildren = ((Component)loaded).GetComponentsInChildren<MeshFilter>(true);
			foreach (MeshFilter val2 in componentsInChildren)
			{
				if ((Object)(object)((Component)val2).transform == (Object)(object)loaded || ((Component)val2).transform.IsChildOf(model) || (Object)(object)val2.sharedMesh == (Object)null)
				{
					continue;
				}
				bool flag = false;
				Transform val3 = ((Component)val2).transform;
				while ((Object)(object)val3 != (Object)null && (Object)(object)val3 != (Object)(object)loaded)
				{
					if (((Object)val3).name == "AmmoLoadedVariant")
					{
						flag = true;
						break;
					}
					val3 = val3.parent;
				}
				if (!flag)
				{
					Bounds bounds = val2.sharedMesh.bounds;
					Vector3 size = ((Bounds)(ref bounds)).size;
					float num2 = Mathf.Max(size.x, Mathf.Max(size.y, size.z));
					float num3 = Mathf.Max(0.0001f, size.x * size.y * size.z);
					float num4 = num2 * num2 * num2 / num3;
					if (num4 > num)
					{
						num = num4;
						val = val2;
					}
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				model.localPosition = Vector3.zero;
				Plugin.Log.LogWarning((object)"crossbow loaded ammo anchor unavailable, using loaded origin");
				return;
			}
			if ((Object)(object)original == (Object)null)
			{
				original = ((Component)val).GetComponent<Renderer>();
				if ((Object)(object)original != (Object)null)
				{
					originalEnabled = original.enabled;
				}
			}
			if ((Object)(object)original != (Object)null)
			{
				original.enabled = false;
			}
			Bounds bounds2 = val.sharedMesh.bounds;
			Vector3 size2 = ((Bounds)(ref bounds2)).size;
			Vector3 val4 = ((size2.y >= size2.x && size2.y >= size2.z) ? Vector3.up : ((size2.z >= size2.x) ? Vector3.forward : Vector3.right));
			float num5 = Mathf.Max(size2.x, Mathf.Max(size2.y, size2.z));
			Vector3 val5 = ((Component)val).transform.TransformPoint(((Bounds)(ref bounds2)).center - val4 * num5 * 0.5f);
			Vector3 val6 = ((Component)val).transform.TransformPoint(((Bounds)(ref bounds2)).center + val4 * num5 * 0.5f);
			Vector3 val7 = loaded.InverseTransformPoint(val5);
			Vector3 val8 = loaded.InverseTransformPoint(val6);
			Vector3 val9 = val8 - val7;
			Vector3 normalized = ((Vector3)(ref val9)).normalized;
			Bounds val10 = AmmoModels.BoundsOf(((Component)model).gameObject);
			float num6 = ((((Bounds)(ref val10)).size.z > 0f) ? (Vector3.Distance(val8, val7) / ((Bounds)(ref val10)).size.z) : 1f);
			if (Items.ScatterProjectiles.Contains(prefab))
			{
				num6 *= 0.5f;
				float num7 = 0f;
				for (int j = 0; j < 3; j++)
				{
					if (((Vector3)(ref val4))[j] == 0f)
					{
						Vector3 zero = Vector3.zero;
						((Vector3)(ref zero))[j] = ((Vector3)(ref size2))[j];
						float num8 = num7;
						val9 = loaded.InverseTransformVector(((Component)val).transform.TransformVector(zero));
						num7 = Mathf.Max(num8, ((Vector3)(ref val9)).magnitude);
					}
				}
				float num9 = Mathf.Max(((Bounds)(ref val10)).size.x, ((Bounds)(ref val10)).size.y);
				if (num7 > 0f && num9 > 0f)
				{
					num6 = Mathf.Min(num6, num7 * 0.8f / num9);
				}
			}
			model.localScale = Vector3.one * num6;
			model.localRotation = Quaternion.LookRotation(normalized);
			model.localPosition = (val8 + val7) * 0.5f;
			if (Items.ScatterProjectiles.Contains(prefab))
			{
				model.localPosition = val7 + normalized * (((Bounds)(ref val10)).size.z * num6 * 0.5f);
			}
			if (Plugin.LogCounters.Value)
			{
				Plugin.Log.LogInfo((object)$"loaded ammo footprint {((Object)prefab).name}, shafts {model.childCount}, length {((Bounds)(ref val10)).size.z * num6:F3}, width {Mathf.Max(((Bounds)(ref val10)).size.x, ((Bounds)(ref val10)).size.y) * num6:F3}");
			}
		}
	}
	[HarmonyPatch(typeof(WeaponLoadState), "Update")]
	internal static class AmmoWeaponLoadPatch
	{
		private static readonly FieldRef<WeaponLoadState, Player> Owner = AccessTools.FieldRefAccess<WeaponLoadState, Player>("m_owner");

		private static void Postfix(WeaponLoadState __instance)
		{
			Player val = Owner.Invoke(__instance);
			if ((Object)(object)val == (Object)null || (Object)(object)__instance.m_loaded == (Object)null)
			{
				return;
			}
			ItemData ammoItem = ((Humanoid)val).GetAmmoItem();
			AmmoLoadedVisual ammoLoadedVisual = ((Component)__instance).GetComponent<AmmoLoadedVisual>();
			if (!((Object)(object)ammoLoadedVisual == (Object)null) || Items.KindOf(ammoItem) != Items.AmmoKind.None)
			{
				if ((Object)(object)ammoLoadedVisual == (Object)null)
				{
					ammoLoadedVisual = ((Component)__instance).gameObject.AddComponent<AmmoLoadedVisual>();
				}
				ammoLoadedVisual.Refresh(__instance, ammoItem);
			}
		}
	}
	internal static class AmmoModels
	{
		internal const int BundleCount = 3;

		private const float BundleSpacing = 0.045f;

		private const float ScatterBodyLength = 0.42f;

		private const float ScatterArrowBodyLength = 1f;

		private const float ScatterBundleSpacing = 0.01f;

		internal const float LoadedScatterLengthShare = 0.5f;

		internal const float LoadedScatterWidthShare = 0.8f;

		private const float HeadLengthShare = 0.08f;

		private const float HeadRadiusShare = 0.014f;

		private static readonly Dictionary<GameObject, float> Lengths = new Dictionary<GameObject, float>();

		internal static Bounds BoundsOf(GameObject root)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: 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_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: 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_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: 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)
			Bounds result = default(Bounds);
			bool flag = false;
			MeshFilter[] componentsInChildren = root.GetComponentsInChildren<MeshFilter>(true);
			foreach (MeshFilter val in componentsInChildren)
			{
				if ((Object)(object)val.sharedMesh == (Object)null || ((Object)val).name == "AmmoDot" || ((Object)val).name == "AmmoTipGlow")
				{
					continue;
				}
				Bounds bounds = val.sharedMesh.bounds;
				Matrix4x4 val2 = root.transform.worldToLocalMatrix * ((Component)val).transform.localToWorldMatrix;
				for (int j = 0; j < 8; j++)
				{
					Vector3 val3 = ((Matrix4x4)(ref val2)).MultiplyPoint3x4(new Vector3(((j & 1) == 0) ? ((Bounds)(ref bounds)).min.x : ((Bounds)(ref bounds)).max.x, ((j & 2) == 0) ? ((Bounds)(ref bounds)).min.y : ((Bounds)(ref bounds)).max.y, ((j & 4) == 0) ? ((Bounds)(ref bounds)).min.z : ((Bounds)(ref bounds)).max.z));
					if (!flag)
					{
						((Bounds)(ref result))..ctor(val3, Vector3.zero);
						flag = true;
					}
					else
					{
						((Bounds)(ref result)).Encapsulate(val3);
					}
				}
			}
			return result;
		}

		internal static void Decorate(GameObject projectile, string kind, float originalLength)
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: 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_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Expected O, but got Unknown
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Expected O, but got Unknown
			//IL_00b8: 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)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: 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_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: 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_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_021e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_0236: 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_023c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0248: Expected O, but got Unknown
			Lengths[projectile] = originalLength * ((kind == "Piercing") ? Plugin.PierceBodyLength.Value : ((!(kind == "Scatter")) ? 1f : (((Object)projectile).name.StartsWith("Arrow") ? 1f : 0.42f)));
			Bounds val = BoundsOf(projectile);
			float num = Mathf.Max(((Bounds)(ref val)).size.z, 0.1f);
			GameObject val2 = new GameObject("AmmoHead");
			val2.transform.SetParent(projectile.transform, false);
			Mesh val3 = new Mesh
			{
				name = "AmmoVariants_head"
			};
			Vector3[] array = (Vector3[])(object)new Vector3[10];
			int[] array2 = new int[48];
			float num2 = ((Bounds)(ref val)).max.z - num * 0.08f;
			array[0] = new Vector3(((Bounds)(ref val)).center.x, ((Bounds)(ref val)).center.y, ((Bounds)(ref val)).max.z + num * 0.01f);
			array[1] = new Vector3(((Bounds)(ref val)).center.x, ((Bounds)(ref val)).center.y, num2);
			for (int i = 0; i < 8; i++)
			{
				float num3 = (float)i * (float)Math.PI * 2f / 8f;
				array[i + 2] = new Vector3(((Bounds)(ref val)).center.x + Mathf.Cos(num3) * num * 0.014f, ((Bounds)(ref val)).center.y + Mathf.Sin(num3) * num * 0.014f, num2);
				int num4 = (i + 1) % 8 + 2;
				array2[i * 6] = 0;
				array2[i * 6 + 1] = i + 2;
				array2[i * 6 + 2] = num4;
				array2[i * 6 + 3] = 1;
				array2[i * 6 + 4] = num4;
				array2[i * 6 + 5] = i + 2;
			}
			val3.vertices = array;
			val3.triangles = array2;
			val3.RecalculateNormals();
			val3.RecalculateBounds();
			val2.AddComponent<MeshFilter>().sharedMesh = val3;
			MeshRenderer obj = val2.AddComponent<MeshRenderer>();
			Color color = AmmoPalette.ColorOf(projectile);
			color.a = 0.9f;
			((Renderer)obj).sharedMaterial = new Material(AmmoAssets.TrailShader)
			{
				color = color
			};
		}

		internal static GameObject Visual(GameObject projectile, bool bundle, bool nocked = false)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: 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_003e: 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_0082: Expected O, but got Unknown
			//IL_02c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_0243: Unknown result type (might be due to invalid IL or missing references)
			//IL_024f: Unknown result type (might be due to invalid IL or missing references)
			//IL_025b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0272: Unknown result type (might be due to invalid IL or missing references)
			//IL_0276: Unknown result type (might be due to invalid IL or missing references)
			//IL_027b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0281: 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_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: 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_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("AmmoVariantVisual");
			Bounds val2 = BoundsOf(projectile);
			float value;
			float num = ((Lengths.TryGetValue(projectile, out value) && ((Bounds)(ref val2)).size.z > 0f) ? (value / ((Bounds)(ref val2)).size.z) : 1f);
			int num2 = ((!bundle) ? 1 : 3);
			float num3 = (Items.ScatterProjectiles.Contains(projectile) ? 0.01f : 0.045f);
			Vector3 val7 = default(Vector3);
			for (int i = 0; i < num2; i++)
			{
				GameObject val3 = new GameObject("AmmoShaft");
				val3.transform.SetParent(val.transform, false);
				if (Items.ScatterProjectiles.Contains(projectile) && ((Object)projectile).name.StartsWith("Arrow"))
				{
					val3.transform.localScale = new Vector3(0.42f, 0.42f, 1f);
				}
				val3.transform.localPosition = new Vector3(((float)i - (float)(num2 - 1) * 0.5f) * num3, 0f, (i == 1) ? (num3 / 3f) : 0f);
				MeshFilter[] componentsInChildren = projectile.GetComponentsInChildren<MeshFilter>(true);
				foreach (MeshFilter val4 in componentsInChildren)
				{
					MeshRenderer component = ((Component)val4).GetComponent<MeshRenderer>();
					if (!((Object)(object)val4.sharedMesh == (Object)null) && !((Object)(object)component == (Object)null) && !(((Object)val4).name == "AmmoDot"))
					{
						GameObject val5 = new GameObject(((Object)val4).name);
						val5.transform.SetParent(val3.transform, false);
						Matrix4x4 val6 = projectile.transform.worldToLocalMatrix * ((Component)val4).transform.localToWorldMatrix;
						val5.transform.localPosition = (new Vector3(val6.m03, val6.m13, val6.m23) - ((Bounds)(ref val2)).center) * num;
						val5.transform.localRotation = ((Matrix4x4)(ref val6)).rotation;
						val5.transform.localScale = ((Matrix4x4)(ref val6)).lossyScale * num;
						val5.AddComponent<MeshFilter>().sharedMesh = val4.sharedMesh;
						MeshRenderer obj = val5.AddComponent<MeshRenderer>();
						((Renderer)obj).sharedMaterials = ((Renderer)component).sharedMaterials;
						((Renderer)obj).shadowCastingMode = (ShadowCastingMode)0;
					}
				}
				((Vector3)(ref val7))..ctor(((Bounds)(ref val2)).center.x, ((Bounds)(ref val2)).center.y, ((Bounds)(ref val2)).max.z);
				AmmoDisplayEffects.Add(projectile, val3.transform, (val7 - ((Bounds)(ref val2)).center) * num, value, Items.ScatterProjectiles.Contains(projectile));
			}
			if (nocked)
			{
				val.transform.localPosition = new Vector3(0f, 0f, value * 0.5f);
			}
			return val;
		}

		internal static void DropModel(GameObject item, GameObject projectile)
		{
			//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_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			item.GetComponent<ItemDrop>().m_itemData.m_dropPrefab = item;
			LODGroup[] componentsInChildren = item.GetComponentsInChildren<LODGroup>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				componentsInChildren[i].enabled = false;
			}
			Renderer[] componentsInChildren2 = item.GetComponentsInChildren<Renderer>(true);
			for (int i = 0; i < componentsInChildren2.Length; i++)
			{
				componentsInChildren2[i].enabled = false;
			}
			ParticleSystem[] componentsInChildren3 = item.GetComponentsInChildren<ParticleSystem>(true);
			foreach (ParticleSystem obj in componentsInChildren3)
			{
				MainModule main = obj.main;
				((MainModule)(ref main)).playOnAwake = false;
				obj.Stop(false, (ParticleSystemStopBehavior)0);
			}
			Light[] componentsInChildren4 = item.GetComponentsInChildren<Light>(true);
			for (int i = 0; i < componentsInChildren4.Length; i++)
			{
				((Behaviour)componentsInChildren4[i]).enabled = false;
			}
			GameObject val = Visual(projectile, !Items.PiercingProjectiles.Contains(projectile));
			((Object)val).name = "AmmoBundle";
			val.transform.SetParent(item.transform, false);
			val.transform.localRotation = Quaternion.identity;
			if (Plugin.LogCounters.Value)
			{
				ManualLogSource log = Plugin.Log;
				string[] obj2 = new string[6]
				{
					"variant drop model ",
					((Object)item).name,
					", shafts ",
					val.transform.childCount.ToString(),
					", bounds ",
					null
				};
				Bounds val2 = BoundsOf(val);
				Vector3 size = ((Bounds)(ref val2)).size;
				obj2[5] = ((Vector3)(ref size)).ToString("F3");
				log.LogInfo((object)string.Concat(obj2));
			}
		}
	}
	public sealed class AmmoNativeEffects : MonoBehaviour
	{
		[SerializeField]
		private ParticleSystem[] systems;

		[SerializeField]
		private bool[] play;

		[SerializeField]
		private TrailRenderer[] trails;

		[SerializeField]
		private bool[] emit;

		[SerializeField]
		private Light[] lights;

		[SerializeField]
		private bool[] illuminate;

		private bool started;

		private bool stopped;

		private Projectile projectile;

		internal void Prepare(float scale)
		{
			//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_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			systems = ((Component)this).GetComponentsInChildren<ParticleSystem>(true);
			play = new bool[systems.Length];
			for (int i = 0; i < systems.Length; i++)
			{
				MainModule main = systems[i].main;
				play[i] = ((MainModule)(ref main)).playOnAwake;
				((MainModule)(ref main)).playOnAwake = false;
				if (scale < 1f)
				{
					((MainModule)(ref main)).scalingMode = (ParticleSystemScalingMode)0;
					((MainModule)(ref main)).maxParticles = Mathf.Max(1, Mathf.CeilToInt((float)((MainModule)(ref main)).maxParticles * scale));
					EmissionModule emission = systems[i].emission;
					((EmissionModule)(ref emission)).rateOverTimeMultiplier = ((EmissionModule)(ref emission)).rateOverTimeMultiplier * scale;
					((EmissionModule)(ref emission)).rateOverDistanceMultiplier = ((EmissionModule)(ref emission)).rateOverDistanceMultiplier * scale;
				}
				systems[i].Stop(false, (ParticleSystemStopBehavior)0);
			}
			trails = ((Component)this).GetComponentsInChildren<TrailRenderer>(true);
			emit = new bool[trails.Length];
			for (int j = 0; j < trails.Length; j++)
			{
				emit[j] = ((Renderer)trails[j]).enabled && trails[j].emitting;
				trails[j].emitting = false;
				((Renderer)trails[j]).enabled = false;
				TrailRenderer obj = trails[j];
				obj.widthMultiplier *= scale;
				TrailRenderer obj2 = trails[j];
				obj2.minVertexDistance *= scale;
			}
			lights = ((Component)this).GetComponentsInChildren<Light>(true);
			illuminate = new bool[lights.Length];
			for (int k = 0; k < lights.Length; k++)
			{
				illuminate[k] = ((Behaviour)lights[k]).enabled;
				((Behaviour)lights[k]).enabled = false;
				Light obj3 = lights[k];
				obj3.range *= scale;
				Light obj4 = lights[k];
				obj4.intensity *= scale;
			}
			if (Plugin.LogCounters.Value)
			{
				Plugin.Log.LogInfo((object)$"native ammo effects prepared {((Object)this).name}, particles {systems.Length}, trails {trails.Length}, lights {lights.Length}, size {scale:F2}, density {scale:F2}");
			}
		}

		internal void Begin()
		{
			if (started || stopped || systems == null)
			{
				return;
			}
			projectile = ((Component)this).GetComponent<Projectile>();
			if ((Object)(object)projectile != (Object)null && Shots.FlightEnded(projectile))
			{
				return;
			}
			started = true;
			for (int i = 0; i < systems.Length; i++)
			{
				if (play[i] && ((Component)systems[i]).gameObject.activeInHierarchy)
				{
					systems[i].Play(false);
				}
			}
			for (int j = 0; j < trails.Length; j++)
			{
				trails[j].Clear();
				((Renderer)trails[j]).enabled = emit[j];
				trails[j].emitting = emit[j];
			}
			for (int k = 0; k < lights.Length; k++)
			{
				((Behaviour)lights[k]).enabled = illuminate[k];
			}
			if (Plugin.LogCounters.Value && (systems.Length != 0 || trails.Length != 0))
			{
				Plugin.Log.LogInfo((object)$"native ammo effects launched {((Object)this).name}, particles {systems.Length}, trails {trails.Length}");
			}
		}

		private void Update()
		{
			if (!started)
			{
				ZNetView component = ((Component)this).GetComponent<ZNetView>();
				if ((Object)(object)component != (Object)null && component.IsValid())
				{
					Begin();
				}
			}
			else if (!stopped && !((Object)(object)projectile == (Object)null) && Shots.FlightEnded(projectile))
			{
				stopped = true;
				ParticleSystem[] array = systems;
				for (int i = 0; i < array.Length; i++)
				{
					array[i].Stop(false, (ParticleSystemStopBehavior)1);
				}
				TrailRenderer[] array2 = trails;
				for (int i = 0; i < array2.Length; i++)
				{
					array2[i].emitting = false;
				}
				Light[] array3 = lights;
				for (int i = 0; i < array3.Length; i++)
				{
					((Behaviour)array3[i]).enabled = false;
				}
			}
		}
	}
	internal static class AmmoPalette
	{
		internal const float PiercingOpacity = 0.65f;

		internal const float ScatterTrailSeconds = 1f;

		internal const float DarkThreshold = 0.45f;

		internal const float EdgeOpacity = 0.18f;

		internal const float EdgeWidthShare = 1.5f;

		internal static readonly Color Energy = new Color(0.33f, 0.62f, 1f, 1f);

		internal static readonly Color EdgeColor = new Color(0.9f, 0.95f, 0.96f, 1f);

		private static Material darkMaterial;

		private static readonly Dictionary<string, Color> Materials = new Dictionary<string, Color>
		{
			{
				"Wood",
				Color32.op_Implicit(new Color32((byte)201, (byte)205, (byte)208, byte.MaxValue))
			},
			{
				"Flint",
				Color32.op_Implicit(new Color32((byte)146, (byte)154, (byte)159, byte.MaxValue))
			},
			{
				"Iron",
				Color.white
			},
			{
				"Bronze",
				Color32.op_Implicit(new Color32((byte)197, (byte)140, (byte)82, byte.MaxValue))
			},
			{
				"Blackmetal",
				Color32.op_Implicit(new Color32((byte)51, (byte)72, (byte)62, byte.MaxValue))
			},
			{
				"Carapace",
				Color32.op_Implicit(new Color32((byte)216, (byte)201, (byte)157, byte.MaxValue))
			},
			{
				"Obsidian",
				Color32.op_Implicit(new Color32((byte)78, (byte)80, (byte)91, byte.MaxValue))
			},
			{
				"Bone",
				Color32.op_Implicit(new Color32((byte)222, (byte)213, (byte)186, byte.MaxValue))
			},
			{
				"Silver",
				Color32.op_Implicit(new Color32((byte)205, (byte)224, (byte)235, byte.MaxValue))
			},
			{
				"Needle",
				Color32.op_Implicit(new Color32((byte)99, (byte)179, (byte)166, byte.MaxValue))
			},
			{
				"Charred",
				Color32.op_Implicit(new Color32((byte)88, (byte)100, (byte)111, byte.MaxValue))
			},
			{
				"BloodGold",
				Color32.op_Implicit(new Color32((byte)232, (byte)171, (byte)56, byte.MaxValue))
			},
			{
				"Fire",
				Color32.op_Implicit(new Color32(byte.MaxValue, (byte)122, (byte)50, byte.MaxValue))
			},
			{
				"Frost",
				Color32.op_Implicit(new Color32((byte)142, (byte)235, byte.MaxValue, byte.MaxValue))
			},
			{
				"Poison",
				Color32.op_Implicit(new Color32((byte)120, (byte)224, (byte)68, byte.MaxValue))
			}
		};

		internal static Color ColorOf(GameObject projectile)
		{
			//IL_000d: 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_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: 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)
			if (Items.EnergyProjectiles.Contains(projectile))
			{
				return Energy;
			}
			foreach (KeyValuePair<string, Color> material in Materials)
			{
				if (((Object)projectile).name.StartsWith("Arrow" + material.Key) || ((Object)projectile).name.StartsWith("Bolt" + material.Key))
				{
					return material.Value;
				}
			}
			return Color.white;
		}

		internal static Color MaterialColor(string tier)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			if (!Materials.TryGetValue(tier, out var value))
			{
				return Color.white;
			}
			return value;
		}

		internal static Color Lifted(Color tint)
		{
			//IL_0000: 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_000c: 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_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: 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)
			if (Mathf.Max(tint.r, Mathf.Max(tint.g, tint.b)) >= 0.45f)
			{
				return tint;
			}
			return Color.Lerp(tint, EdgeColor, 0.85f);
		}

		internal static Material DarkMaterial()
		{
			//IL_0012: 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_0027: Expected O, but got Unknown
			if ((Object)(object)darkMaterial == (Object)null)
			{
				darkMaterial = new Material(AmmoAssets.TrailShader)
				{
					color = Color.white
				};
			}
			return darkMaterial;
		}
	}
	public sealed class AmmoScatterBody : MonoBehaviour
	{
		private const float ReportDelay = 0.1f;

		private static readonly HashSet<string> Observed = new HashSet<string>();

		private TrailRenderer trail;

		private float age;

		private void Awake()
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Expected O, but got Unknown
			//IL_00ef: 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)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: 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_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: 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_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: 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_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			Transform obj = ((Component)this).transform.Find("AmmoTrail");
			trail = ((obj != null) ? ((Component)obj).GetComponent<TrailRenderer>() : null);
			Vector3 val3 = default(Vector3);
			foreach (Transform item in ((Component)this).transform)
			{
				Transform val = item;
				if (((Object)val).name == "AmmoTrail" || ((Object)val).name == "AmmoDot" || (Object)(object)((Component)val).GetComponentInChildren<MeshRenderer>(true) == (Object)null)
				{
					continue;
				}
				Collider[] componentsInChildren = ((Component)val).GetComponentsInChildren<Collider>(true);
				if (!componentsInChildren.Any((Collider c) => !(c is BoxCollider)))
				{
					Vector3[] array = componentsInChildren.Select((Collider c) => ((Component)c).transform.lossyScale).ToArray();
					Widen(val, 1.5f);
					for (int num = 0; num < componentsInChildren.Length; num++)
					{
						BoxCollider val2 = (BoxCollider)componentsInChildren[num];
						Vector3 lossyScale = ((Component)val2).transform.lossyScale;
						((Vector3)(ref val3))..ctor(Ratio(array[num].x, lossyScale.x), Ratio(array[num].y, lossyScale.y), Ratio(array[num].z, lossyScale.z));
						val2.size = Vector3.Scale(val2.size, val3);
						val2.center = Vector3.Scale(val2.center, val3);
					}
				}
			}
		}

		private static float Ratio(float old, float now)
		{
			if (!(Mathf.Abs(now) > 1E-06f))
			{
				return 1f;
			}
			return old / now;
		}

		private static void Widen(Transform child, float factor)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: 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_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_0073: 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_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: 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_0095: 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_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)
			Vector3 one = Vector3.one;
			for (int i = 0; i < 3; i++)
			{
				if (Mathf.Abs((child.localRotation * new Vector3((i == 0) ? 1f : 0f, (i == 1) ? 1f : 0f, (i == 2) ? 1f : 0f)).z) < 0.5f)
				{
					((Vector3)(ref one))[i] = factor;
				}
			}
			child.localScale = Vector3.Scale(child.localScale, one);
			Vector3 localPosition = child.localPosition;
			child.localPosition = new Vector3(localPosition.x * factor, localPosition.y * factor, localPosition.z);
		}

		private void Update()
		{
			age += Time.deltaTime;
			if (!(age < 0.1f))
			{
				((Behaviour)this).enabled = false;
				if (!((Object)(object)trail == (Object)null) && Plugin.LogCounters.Value && Observed.Add(((Object)this).name))
				{
					Camera main = Camera.main;
					bool flag = (Object)(object)main != (Object)null && (main.cullingMask & (1 << ((Component)trail).gameObject.layer)) != 0;
					Plugin.Log.LogInfo((object)$"scatter trail flight {((Object)this).name}, points {trail.positionCount}, enabled {((Renderer)trail).enabled}, emitting {trail.emitting}, visible {((Renderer)trail).isVisible}, camera layer {flag}, width {trail.startWidth:F3}, seconds {trail.time:F2}");
				}
			}
		}
	}
	public sealed class AmmoTrailDissolve : MonoBehaviour
	{
		private TrailRenderer trail;

		private LineRenderer glow;

		private LineRenderer edge;

		private LineRenderer lightning;

		private Vector3[] points;

		private Vector3[] sparks;

		private float[] distances;

		private float began = -1f;

		private bool energy;

		private Mesh mesh;

		private Transform meshTransform;

		private MeshRenderer meshRenderer;

		private readonly List<Vector3> samples = new List<Vector3>();

		private readonly List<float> times = new List<float>();

		private readonly List<Vector3> vertices = new List<Vector3>();

		private readonly List<Color> colors = new List<Color>();

		private readonly List<int> coreTriangles = new List<int>();

		private readonly List<int> sparkTriangles = new List<int>();

		private const float EnergyWidth = 0.055f;

		private const float EnergyOpacity = 0.45f;

		private readonly Vector3[] buffer = (Vector3[])(object)new Vector3[2048];

		private const float LightningWidth = 0.025f;

		private const float LightningWobble = 0.035f;

		private readonly float[] lengths = new float[2048];

		private readonly float[] stamps = new float[2048];

		private GradientAlphaKey[] alphas;

		private float opacity;

		private const int GoldFadeKeys = 8;

		internal void Prepare(TrailRenderer source, ParticleSystem particles, bool ageEnergy = false)
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: 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_00c5: 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: Expected O, but got Unknown
			//IL_01ba: 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_01cb: 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_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d4: Expected O, but got Unknown
			//IL_02f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_030a: Expected O, but got Unknown
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			//IL_0219: Expected O, but got Unknown
			//IL_03be: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c5: Expected O, but got Unknown
			if ((Object)(object)trail != (Object)null)
			{
				return;
			}
			trail = source;
			energy = ageEnergy;
			int positions = trail.GetPositions(buffer);
			for (int i = 0; i < positions; i++)
			{
				samples.Add(buffer[i]);
				times.Add(Time.time);
			}
			Gradient colorGradient = trail.colorGradient;
			opacity = trail.startColor.a;
			colorGradient.SetKeys(colorGradient.colorKeys, (GradientAlphaKey[])(object)new GradientAlphaKey[2]
			{
				new GradientAlphaKey(opacity, 0f),
				new GradientAlphaKey(opacity * 0.75f, 1f)
			});
			trail.colorGradient = colorGradient;
			trail.endWidth = trail.startWidth * 0.5f;
			((Renderer)trail).enabled = false;
			GameObject val = new GameObject("AmmoGlowPath");
			val.transform.SetParent(((Component)this).transform, false);
			glow = val.AddComponent<LineRenderer>();
			glow.useWorldSpace = true;
			glow.alignment = (LineAlignment)0;
			glow.startWidth = trail.startWidth;
			glow.endWidth = trail.endWidth;
			((Renderer)glow).sharedMaterial = (energy ? ((Renderer)trail).sharedMaterial : AmmoPalette.DarkMaterial());
			glow.colorGradient = colorGradient;
			((Renderer)glow).shadowCastingMode = (ShadowCastingMode)0;
			((Renderer)glow).receiveShadows = false;
			Color startColor = source.startColor;
			if (!energy && Mathf.Max(startColor.r, Mathf.Max(startColor.g, startColor.b)) < 0.45f)
			{
				((Renderer)glow).sharedMaterial = AmmoPalette.DarkMaterial();
				((Renderer)glow).sortingOrder = 1;
				GameObject val2 = new GameObject("AmmoMaterialEdge");
				val2.transform.SetParent(((Component)this).transform, false);
				edge = val2.AddComponent<LineRenderer>();
				edge.useWorldSpace = true;
				edge.alignment = (LineAlignment)0;
				edge.startWidth = glow.startWidth * 1.5f;
				edge.endWidth = glow.endWidth * 1.5f;
				((Renderer)edge).sharedMaterial = AmmoPalette.DarkMaterial();
				((Renderer)edge).shadowCastingMode = (ShadowCastingMode)0;
				((Renderer)edge).receiveShadows = false;
			}
			if (energy)
			{
				((Renderer)glow).enabled = false;
				GameObject val3 = new GameObject("AmmoEnergyPath");
				val3.transform.SetParent(((Component)this).transform, false);
				meshTransform = val3.transform;
				mesh = new Mesh
				{
					name = "AmmoVariants_energy_path"
				};
				mesh.MarkDynamic();
				val3.AddComponent<MeshFilter>().sharedMesh = mesh;
				meshRenderer = val3.AddComponent<MeshRenderer>();
				Material val4 = (((Object)(object)particles != (Object)null) ? ((Component)particles).GetComponent<ParticleSystemRenderer>().trailMaterial : null);
				((Renderer)meshRenderer).sharedMaterials = (Material[])(object)new Material[2]
				{
					((Renderer)source).sharedMaterial,
					((Object)(object)val4 != (Object)null) ? val4 : ((Renderer)source).sharedMaterial
				};
				((Renderer)meshRenderer).shadowCastingMode = (ShadowCastingMode)0;
				((Renderer)meshRenderer).receiveShadows = false;
			}
			else if (!((Object)(object)particles == (Object)null))
			{
				Material trailMaterial = ((Component)particles).GetComponent<ParticleSystemRenderer>().trailMaterial;
				if (!((Object)(object)trailMaterial == (Object)null))
				{
					GameObject val5 = new GameObject("AmmoLightningPath");
					val5.transform.SetParent(((Component)this).transform, false);
					lightning = val5.AddComponent<LineRenderer>();
					lightning.useWorldSpace = true;
					lightning.alignment = (LineAlignment)0;
					lightning.startWidth = 0.025f;
					lightning.endWidth = 0.025f;
					((Renderer)lightning).sharedMaterial = trailMaterial;
					lightning.colorGradient = colorGradient;
					((Renderer)lightning).shadowCastingMode = (ShadowCastingMode)0;
					((Renderer)lightning).receiveShadows = false;
				}
			}
		}

		internal void Release()
		{
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: 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)
			if (began >= 0f || (Object)(object)trail == (Object)null)
			{
				return;
			}
			if (!energy)
			{
				RenderGold();
			}
			began = Time.time;
			int num = (energy ? trail.positionCount : glow.positionCount);
			points = (Vector3[])(object)new Vector3[num];
			distances = new float[num];
			if (energy)
			{
				trail.GetPositions(points);
			}
			else
			{
				glow.GetPositions(points);
				alphas = glow.colorGradient.alphaKeys;
			}
			for (int i = 1; i < num; i++)
			{
				distances[i] = distances[i - 1] + Vector3.Distance(points[i - 1], points[i]);
			}
			if ((Object)(object)lightning != (Object)null)
			{
				sparks = (Vector3[])(object)new Vector3[num];
				for (int j = 0; j < num; j++)
				{
					sparks[j] = Spark(points[j], j);
				}
			}
			if (Plugin.LogCounters.Value)
			{
				Plugin.Log.LogInfo((object)$"ammo path released, points {num}, length {((num > 0) ? distances[num - 1] : 0f):F1}, segment aging true, energy {energy}, fade {(energy ? 2f : 1f):F1}");
			}
		}

		internal void RecordPoint(Vector3 point)
		{
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: 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_0073: 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_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			if (samples.Count >= 2048)
			{
				int count = samples.Count;
				int num = 0;
				for (int i = 0; i < count; i += 2)
				{
					samples[num] = samples[i];
					times[num] = times[i];
					num++;
				}
				samples[num] = samples[count - 1];
				times[num] = times[count - 1];
				num++;
				samples.RemoveRange(num, count - num);
				times.RemoveRange(num, count - num);
				trail.Clear();
				foreach (Vector3 sample in samples)
				{
					trail.AddPosition(sample);
				}
			}
			samples.Add(point);
			times.Add(Time.time);
			trail.AddPosition(point);
		}

		internal static float EnergyAlpha(float age)
		{
			float num = (float)Math.Max(0.0, Math.Min(1.0, (age - 1f) / 2f));
			return 1f - num * num * (3f - 2f * num);
		}

		private void RenderGold()
		{
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: 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_00d3: 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_00fe: 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_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			//IL_0238: Unknown result type (might be due to invalid IL or missing references)
			if (samples.Count < 2)
			{
				return;
			}
			float num = Time.time - 1f - 2f;
			int i;
			for (i = 0; i < samples.Count - 2 && times[i + 1] <= num; i++)
			{
			}
			int num2 = samples.Count - i;
			for (int j = 0; j < num2; j++)
			{
				buffer[j] = samples[i + j];
				stamps[j] = times[i + j];
			}
			if (num > stamps[0] && stamps[1] > stamps[0])
			{
				buffer[0] = Vector3.Lerp(buffer[0], buffer[1], Mathf.Clamp01((num - stamps[0]) / (stamps[1] - stamps[0])));
				stamps[0] = Mathf.Min(num, stamps[1]);
			}
			lengths[0] = 0f;
			for (int k = 1; k < num2; k++)
			{
				lengths[k] = lengths[k - 1] + Vector3.Distance(buffer[k - 1], buffer[k]);
			}
			GradientAlphaKey[] array = (GradientAlphaKey[])(object)new GradientAlphaKey[8];
			int l = 1;
			for (int m = 0; m < array.Length; m++)
			{
				float num3 = (float)m / (float)(array.Length - 1);
				float num4;
				for (num4 = num3 * lengths[num2 - 1]; l < num2 - 1 && lengths[l] < num4; l++)
				{
				}
				float num5 = lengths[l] - lengths[l - 1];
				float num6 = Mathf.Lerp(stamps[l - 1], stamps[l], (num5 > 0f) ? ((num4 - lengths[l - 1]) / num5) : 1f);
				array[m] = new GradientAlphaKey(opacity * EnergyAlpha(Time.time - num6) * Mathf.Lerp(1f, 0.75f, num3), num3);
			}
			Gradient colorGradient = glow.colorGradient;
			colorGradient.SetKeys(trail.colorGradient.colorKeys, array);
			glow.colorGradient = colorGradient;
			glow.positionCount = num2;
			glow.SetPositions(buffer);
			RenderEdge(buffer);
		}

		private void RenderEdge(Vector3[] positions)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			//IL_001e: 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_0034: 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_0043: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)edge == (Object)null))
			{
				Gradient val = new Gradient();
				val.SetKeys((GradientColorKey[])(object)new GradientColorKey[2]
				{
					new GradientColorKey(AmmoPalette.EdgeColor, 0f),
					new GradientColorKey(AmmoPalette.EdgeColor, 1f)
				}, Array.ConvertAll(glow.colorGradient.alphaKeys, (Converter<GradientAlphaKey, GradientAlphaKey>)((GradientAlphaKey key) => new GradientAlphaKey(key.alpha * 0.18f, key.time))));
				edge.colorGradient = val;
				edge.positionCount = glow.positionCount;
				edge.SetPositions(positions);
			}
		}

		private void RenderEnergy()
		{
			//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)
			//IL_006f: 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_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: 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_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: 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_00c0: 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_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: 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_0178: 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_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: 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_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			if (samples.Count < 2)
			{
				return;
			}
			vertices.Clear();
			colors.Clear();
			coreTriangles.Clear();
			sparkTriangles.Clear();
			Camera main = Camera.main;
			Matrix4x4 worldToLocalMatrix = meshTransform.worldToLocalMatrix;
			for (int i = 0; i < samples.Count; i++)
			{
				Vector3 val = samples[Math.Min(i + 1, samples.Count - 1)] - samples[Math.Max(i - 1, 0)];
				Vector3 val2 = (((Object)(object)main != (Object)null) ? (((Component)main).transform.position - samples[i]) : Vector3.forward);
				Vector3 val3 = Vector3.Cross(val, val2);
				Vector3 val4 = ((Vector3)(ref val3)).normalized;
				if (((Vector3)(ref val4)).sqrMagnitude < 0.001f)
				{
					val4 = Vector3.up;
				}
				float num = EnergyAlpha(Time.time - times[i]);
				for (int j = 0; j < 2; j++)
				{
					Vector3 val5 = ((j == 0) ? samples[i] : Spark(samples[i], i));
					float num2 = ((j == 0) ? 0.055f : 0.025f) * 0.5f;
					Color val6 = ((j == 0) ? new Color(0.35f, 0.65f, 1f, num * 0.45f) : new Color(0.45f, 0.75f, 1f, num * 0.75f));
					for (int k = 0; k < 3; k++)
					{
						vertices.Add(((Matrix4x4)(ref worldToLocalMatrix)).MultiplyPoint3x4(val5 + val4 * ((float)(k - 1) * num2)));
						Color item = val6;
						if (k != 1)
						{
							item.a = 0f;
						}
						colors.Add(item);
					}
					if (i > 0)
					{
						int num3 = (i - 1) * 6 + j * 3;
						List<int> list = ((j == 0) ? coreTriangles : sparkTriangles);
						for (int l = 0; l < 2; l++)
						{
							list.Add(num3 + l);
							list.Add(num3 + l + 6);
							list.Add(num3 + l + 1);
							list.Add(num3 + l + 1);
							list.Add(num3 + l + 6);
							list.Add(num3 + l + 7);
						}
					}
				}
			}
			mesh.Clear();
			mesh.SetVertices(vertices);
			mesh.SetColors(colors);
			mesh.subMeshCount = 2;
			mesh.SetTriangles(coreTriangles, 0);
			mesh.SetTriangles(sparkTriangles, 1);
			mesh.RecalculateBounds();
		}

		private static Vector3 Spark(Vector3 point, int index)
		{
			//IL_0028: 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_002f: Unknown result type (might be du