Decompiled source of StaffsOfFracturing v1.0.0

plugins/StaffsOfFracturing.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Extensions;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using StaffsOfFracturing.Blood;
using StaffsOfFracturing.Configuration;
using StaffsOfFracturing.Items;
using StaffsOfFracturing.Lightning;
using StaffsOfFracturing.Localization;
using StaffsOfFracturing.Networking;
using StaffsOfFracturing.Plugin;
using StaffsOfFracturing.Poison;
using StaffsOfFracturing.Projectiles;
using StaffsOfFracturing.Utilities;
using StaffsOfFracturing.VFX;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("StaffsOfFracturing")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("StaffsOfFracturing")]
[assembly: AssemblyTitle("StaffsOfFracturing")]
[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 StaffsOfFracturing.VFX
{
	internal enum ElementTheme
	{
		Lightning,
		Poison,
		Blood
	}
	internal static class VfxFactory
	{
		internal static GameObject LightningArcPrefab { get; private set; }

		internal static GameObject PoisonZonePrefab { get; private set; }

		internal static GameObject BloodShrapnelPrefab { get; private set; }

		internal static GameObject LightningHitPrefab { get; private set; }

		internal static GameObject PoisonHitPrefab { get; private set; }

		internal static GameObject BloodHitPrefab { get; private set; }

		internal static void BuildSharedPrefabs()
		{
			//IL_0049: 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_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			LightningArcPrefab = Clone("SOF_LightningArc", "fx_chainlightning_spread");
			TimedDestruction component = LightningArcPrefab.GetComponent<TimedDestruction>();
			if (Object.op_Implicit((Object)(object)component))
			{
				component.m_timeout = 0.9f;
				component.m_triggerOnAwake = true;
			}
			LightningArcPrefab.AddComponent<NetworkArcBehaviour>();
			VfxStyler.StyleHierarchy(LightningArcPrefab, VfxStyler.Lightning, 2.4f);
			Register(LightningArcPrefab);
			PoisonZonePrefab = BuildPoisonZone();
			Register(PoisonZonePrefab);
			LightningHitPrefab = Clone("SOF_LightningHit", "fx_chainlightning_hit");
			VfxStyler.StyleHierarchy(LightningHitPrefab, VfxStyler.Lightning, 2.2f);
			Register(LightningHitPrefab);
			PoisonHitPrefab = Clone("SOF_PoisonHit", "fx_clusterbombstaff_hit");
			VfxStyler.StyleHierarchy(PoisonHitPrefab, VfxStyler.Poison, 1.7f);
			VfxStyler.TuneParticles(PoisonHitPrefab, 1.35f, 0.8f, 1.1f);
			Register(PoisonHitPrefab);
			BloodHitPrefab = Clone("SOF_BloodHit", "fx_clusterbombstaff_hit");
			VfxStyler.StyleHierarchy(BloodHitPrefab, VfxStyler.Blood, 2.1f);
			Register(BloodHitPrefab);
			BloodShrapnelPrefab = BuildBloodShrapnel();
			Register(BloodShrapnelPrefab);
		}

		internal static void SpawnLightningArc(Vector3 start, Vector3 end)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_002a: 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_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)LightningArcPrefab))
			{
				Vector3 val = end - start;
				if (!(((Vector3)(ref val)).sqrMagnitude < 0.01f))
				{
					Object.Instantiate<GameObject>(LightningArcPrefab, start, Quaternion.LookRotation(end - start)).GetComponent<NetworkArcBehaviour>()?.Initialize(start, end);
				}
			}
		}

		internal static void StyleProjectile(GameObject projectile, ElementTheme theme, bool secondary)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: 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_009d: Unknown result type (might be due to invalid IL or missing references)
			Color color = GetColor(theme);
			VfxStyler.StyleHierarchy(projectile, color, (theme == ElementTheme.Lightning) ? 2.4f : 1.9f);
			if (secondary)
			{
				switch (theme)
				{
				case ElementTheme.Lightning:
					AttachVisual(projectile.transform, "StaffLightning", "attach/Loaded/Lightning", "SOF_BallLightning", Vector3.zero, Quaternion.identity, Vector3.one * 0.18f, color, 0.7f, 0.55f, 0.7f);
					break;
				case ElementTheme.Poison:
					AttachVisual(projectile.transform, "poisoncloud", string.Empty, "SOF_BallPoison", Vector3.zero, Quaternion.identity, Vector3.one * 0.22f, color, 0.42f, 0.35f, 0.65f);
					break;
				}
			}
		}

		internal static void StyleStaff(GameObject itemPrefab, ElementTheme theme)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0237: 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_0090: 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_009f: 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_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: 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_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: 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_0206: 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)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			Color color = GetColor(theme);
			Transform val = itemPrefab.transform.Find("attach/equiped");
			if (Object.op_Implicit((Object)(object)val))
			{
				for (int i = 0; i < val.childCount; i++)
				{
					((Component)val.GetChild(i)).gameObject.SetActive(false);
				}
				switch (theme)
				{
				case ElementTheme.Lightning:
					AttachVisual(val, "StaffLightning", "attach/Loaded/Lightning", "SOF_EquippedLightning", new Vector3(-0.1f, 0.01f, 0.87f), Quaternion.Euler(270f, 0f, 0f), Vector3.one * 0.55f, color, 0.65f, 0.45f, 0.8f);
					break;
				case ElementTheme.Poison:
					AttachVisual(val, "poisoncloud", string.Empty, "SOF_EquippedPoisonHaze", new Vector3(-0.1f, 0.01f, 0.84f), Quaternion.identity, Vector3.one * 0.14f, color, 0.18f, 0.18f, 0.65f);
					break;
				case ElementTheme.Blood:
				{
					GameObject obj = AttachVisual(val, "vfx_Poison", string.Empty, "SOF_EquippedBloodDrips", new Vector3(-0.1f, 0.01f, 0.85f), Quaternion.identity, Vector3.one * 0.18f, color, 0.18f, 0.22f, 0.75f);
					StripNetworkComponents(obj);
					RemoveChildren(obj.transform);
					ParticleSystem[] components = obj.GetComponents<ParticleSystem>();
					for (int j = 0; j < components.Length; j++)
					{
						MainModule main = components[j].main;
						((MainModule)(ref main)).startSpeedMultiplier = 0.035f;
						((MainModule)(ref main)).gravityModifierMultiplier = 0.24f;
						((MainModule)(ref main)).startSizeMultiplier = 0.045f;
						((MainModule)(ref main)).startLifetimeMultiplier = 1.2f;
					}
					break;
				}
				}
				AddSubtleLight(val, color, (theme == ElementTheme.Lightning) ? 1.25f : 0.75f);
			}
			Transform val2 = itemPrefab.transform.Find("attach/default/effects");
			if (Object.op_Implicit((Object)(object)val2))
			{
				foreach (Transform item in val2)
				{
					((Component)item).gameObject.SetActive(true);
				}
			}
			VfxStyler.StyleHierarchy(itemPrefab, color, (theme == ElementTheme.Lightning) ? 2.2f : 1.8f);
		}

		private static GameObject BuildPoisonZone()
		{
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: 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)
			GameObject val = Clone("SOF_PoisonZone", "fx_chainlightning_spread");
			RemoveChildren(val.transform);
			TimedDestruction component = val.GetComponent<TimedDestruction>();
			if (Object.op_Implicit((Object)(object)component))
			{
				component.m_timeout = 12.5f;
				component.m_triggerOnAwake = true;
			}
			GameObject obj = CloneUnregistered("poisoncloud");
			((Object)obj).name = "SOF_PoisonHaze";
			obj.transform.SetParent(val.transform, false);
			obj.transform.localPosition = Vector3.zero;
			obj.transform.localRotation = Quaternion.identity;
			obj.transform.localScale = Vector3.one;
			StripNetworkComponents(obj);
			VfxStyler.StyleHierarchy(obj, VfxStyler.Poison, 1.6f);
			VfxStyler.TuneParticles(obj, 0.8f, 0.65f, 1f);
			val.AddComponent<NetworkPoisonZone>();
			return val;
		}

		private static GameObject BuildBloodShrapnel()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			GameObject obj = Clone("SOF_BloodShrapnel", "projectile_splitner_lightning");
			Projectile component = obj.GetComponent<Projectile>();
			component.m_type = (ProjectileType)10;
			component.m_aoe = 0f;
			component.m_bounce = false;
			component.m_canHitWater = false;
			component.m_gravity = 4f;
			component.m_drag = 0.015f;
			component.m_rayRadius = 0.06f;
			component.m_ttl = 4f;
			component.m_respawnItemOnHit = false;
			component.m_showBreakMessage = false;
			component.m_spawnOnHit = null;
			component.m_spawnOnTtl = false;
			component.m_randomSpawnOnHit.Clear();
			component.m_randomSpawnOnHitCount = 0;
			component.m_projectilesInheritHitData = false;
			component.m_onlySpawnedProjectilesDealDamage = false;
			VfxStyler.StyleHierarchy(obj, VfxStyler.Blood, 3f);
			VfxStyler.TuneParticles(obj, 0.72f, 0.8f, 0.7f);
			return obj;
		}

		private static GameObject AttachVisual(Transform parent, string sourcePrefabName, string sourcePath, string name, Vector3 localPosition, Quaternion localRotation, Vector3 localScale, Color color, float sizeMultiplier, float emissionMultiplier, float lifetimeMultiplier)
		{
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: 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_00a6: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = RequiredPrefab(sourcePrefabName);
			Transform val2 = (string.IsNullOrEmpty(sourcePath) ? val.transform : val.transform.Find(sourcePath));
			if (!Object.op_Implicit((Object)(object)val2))
			{
				throw new InvalidOperationException("Required visual path '" + sourcePrefabName + "/" + sourcePath + "' was not found.");
			}
			GameObject obj = Object.Instantiate<GameObject>(((Component)val2).gameObject, parent, false);
			((Object)obj).name = name;
			obj.transform.localPosition = localPosition;
			obj.transform.localRotation = localRotation;
			obj.transform.localScale = localScale;
			obj.SetActive(true);
			StripNetworkComponents(obj);
			VfxStyler.StyleHierarchy(obj, color, 2f);
			VfxStyler.TuneParticles(obj, sizeMultiplier, emissionMultiplier, lifetimeMultiplier);
			return obj;
		}

		private static void AddSubtleLight(Transform parent, Color color, float intensity)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: 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_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("SOF_ElementLight");
			val.transform.SetParent(parent, false);
			val.transform.localPosition = new Vector3(-0.1f, 0.01f, 0.86f);
			val.layer = ((Component)parent).gameObject.layer;
			Light obj = val.AddComponent<Light>();
			obj.type = (LightType)2;
			obj.color = color;
			obj.intensity = intensity;
			obj.range = 3.2f;
			obj.shadows = (LightShadows)0;
		}

		private static void StripNetworkComponents(GameObject root)
		{
			ZSyncTransform[] componentsInChildren = root.GetComponentsInChildren<ZSyncTransform>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren[i]);
			}
			ZNetView[] componentsInChildren2 = root.GetComponentsInChildren<ZNetView>(true);
			for (int i = 0; i < componentsInChildren2.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren2[i]);
			}
			TimedDestruction[] componentsInChildren3 = root.GetComponentsInChildren<TimedDestruction>(true);
			for (int i = 0; i < componentsInChildren3.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren3[i]);
			}
		}

		private static void RemoveChildren(Transform root)
		{
			for (int num = root.childCount - 1; num >= 0; num--)
			{
				Object.DestroyImmediate((Object)(object)((Component)root.GetChild(num)).gameObject);
			}
		}

		private static EffectList CreateHitEffects(GameObject prefab)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: 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_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Expected O, but got Unknown
			EffectList val = new EffectList();
			val.m_effectPrefabs = (EffectData[])(object)new EffectData[1]
			{
				new EffectData
				{
					m_prefab = prefab,
					m_enabled = true,
					m_variant = -1,
					m_attach = false,
					m_follow = false,
					m_randomRotation = true
				}
			};
			return val;
		}

		internal static EffectList GetHitEffects(ElementTheme theme)
		{
			return (EffectList)(theme switch
			{
				ElementTheme.Lightning => CreateHitEffects(LightningHitPrefab), 
				ElementTheme.Poison => CreateHitEffects(PoisonHitPrefab), 
				_ => CreateHitEffects(BloodHitPrefab), 
			});
		}

		private static Color GetColor(ElementTheme theme)
		{
			//IL_0009: 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)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			return (Color)(theme switch
			{
				ElementTheme.Lightning => VfxStyler.Lightning, 
				ElementTheme.Poison => VfxStyler.Poison, 
				_ => VfxStyler.Blood, 
			});
		}

		private static GameObject Clone(string name, string baseName)
		{
			GameObject val = PrefabManager.Instance.CreateClonedPrefab(name, baseName);
			if (!Object.op_Implicit((Object)(object)val))
			{
				throw new InvalidOperationException("Could not clone required prefab '" + baseName + "' as '" + name + "'.");
			}
			return val;
		}

		private static GameObject CloneUnregistered(string baseName)
		{
			return Object.Instantiate<GameObject>(RequiredPrefab(baseName));
		}

		private static GameObject RequiredPrefab(string name)
		{
			GameObject prefab = PrefabManager.Instance.GetPrefab(name);
			if (!Object.op_Implicit((Object)(object)prefab))
			{
				throw new InvalidOperationException("Required vanilla prefab '" + name + "' was not found.");
			}
			return prefab;
		}

		private static void Register(GameObject prefab)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			PrefabManager.Instance.AddPrefab(new CustomPrefab(prefab, false));
		}
	}
	internal static class VfxStyler
	{
		internal static readonly Color Lightning = new Color(0.24f, 0.62f, 1f, 1f);

		internal static readonly Color Poison = new Color(0.24f, 0.95f, 0.3f, 1f);

		internal static readonly Color Blood = new Color(1f, 0.045f, 0.075f, 1f);

		private static readonly int ColorProperty = Shader.PropertyToID("_Color");

		private static readonly int BaseColorProperty = Shader.PropertyToID("_BaseColor");

		private static readonly int TintColorProperty = Shader.PropertyToID("_TintColor");

		private static readonly int EmissionColorProperty = Shader.PropertyToID("_EmissionColor");

		internal static void StyleHierarchy(GameObject root, Color color, float emissionStrength, bool tintParticles = true)
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Invalid comparison between Unknown and I4
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Expected O, but got Unknown
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)root))
			{
				return;
			}
			if (tintParticles)
			{
				ParticleSystem[] componentsInChildren = root.GetComponentsInChildren<ParticleSystem>(true);
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					MainModule main = componentsInChildren[i].main;
					((MainModule)(ref main)).startColor = new MinMaxGradient(color);
				}
			}
			Light[] componentsInChildren2 = root.GetComponentsInChildren<Light>(true);
			for (int i = 0; i < componentsInChildren2.Length; i++)
			{
				componentsInChildren2[i].color = color;
			}
			if ((int)SystemInfo.graphicsDeviceType == 4)
			{
				return;
			}
			Renderer[] componentsInChildren3 = root.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren3)
			{
				Material[] sharedMaterials = val.sharedMaterials;
				Material[] array = (Material[])(object)new Material[sharedMaterials.Length];
				for (int j = 0; j < sharedMaterials.Length; j++)
				{
					Material val2 = sharedMaterials[j];
					if (!Object.op_Implicit((Object)(object)val2) || !Object.op_Implicit((Object)(object)val2.shader))
					{
						array[j] = val2;
						continue;
					}
					try
					{
						Material val3 = new Material(val2)
						{
							name = ((Object)val2).name + "_SOF_" + ColorUtility.ToHtmlStringRGB(color)
						};
						ApplySupportedColors(val3, color, emissionStrength);
						array[j] = val3;
					}
					catch (Exception ex)
					{
						Logger.LogWarning((object)("Could not style material '" + ((Object)val2).name + "': " + ex.Message));
						array[j] = val2;
					}
				}
				val.sharedMaterials = array;
			}
		}

		internal static Sprite CreateTintedIcon(Sprite source, Color tint)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Invalid comparison between Unknown and I4
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: 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_0085: 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_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: 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_0101: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)source) || (int)SystemInfo.graphicsDeviceType == 4)
			{
				return source;
			}
			try
			{
				Texture2D val = AssetUtils.DuplicateTexture(source);
				if (!Object.op_Implicit((Object)(object)val))
				{
					return source;
				}
				Color[] pixels = val.GetPixels();
				for (int i = 0; i < pixels.Length; i++)
				{
					Color val2 = pixels[i];
					float num = val2.r * 0.3f + val2.g * 0.59f + val2.b * 0.11f;
					Color val3 = tint * Mathf.Clamp01(num * 1.55f + 0.12f);
					pixels[i] = Color.Lerp(val2, val3, 0.72f).WithAlpha(val2.a);
				}
				val.SetPixels(pixels);
				val.Apply(false, false);
				((Object)val).name = ((Object)source).name + "_SOF_" + ColorUtility.ToHtmlStringRGB(tint);
				return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), source.pixelsPerUnit);
			}
			catch (Exception ex)
			{
				Logger.LogWarning((object)("Could not create a tinted inventory icon: " + ex.Message));
				return source;
			}
		}

		internal static void TuneParticles(GameObject root, float sizeMultiplier, float emissionMultiplier, float lifetimeMultiplier)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			ParticleSystem[] componentsInChildren = root.GetComponentsInChildren<ParticleSystem>(true);
			foreach (ParticleSystem obj in componentsInChildren)
			{
				MainModule main = obj.main;
				((MainModule)(ref main)).startSizeMultiplier = ((MainModule)(ref main)).startSizeMultiplier * sizeMultiplier;
				((MainModule)(ref main)).startLifetimeMultiplier = ((MainModule)(ref main)).startLifetimeMultiplier * lifetimeMultiplier;
				EmissionModule emission = obj.emission;
				((EmissionModule)(ref emission)).rateOverTimeMultiplier = ((EmissionModule)(ref emission)).rateOverTimeMultiplier * emissionMultiplier;
			}
		}

		private static void ApplySupportedColors(Material material, Color color, float emissionStrength)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			if (material.HasProperty(BaseColorProperty))
			{
				material.SetColor(BaseColorProperty, color);
			}
			if (material.HasProperty(ColorProperty))
			{
				material.SetColor(ColorProperty, color);
			}
			if (material.HasProperty(TintColorProperty))
			{
				material.SetColor(TintColorProperty, color);
			}
			if (material.HasProperty(EmissionColorProperty))
			{
				material.SetColor(EmissionColorProperty, color * emissionStrength);
				material.EnableKeyword("_EMISSION");
			}
		}

		private static Color WithAlpha(this Color color, float alpha)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			color.a = alpha;
			return color;
		}
	}
}
namespace StaffsOfFracturing.Utilities
{
	internal static class DamageUtility
	{
		private const float QualityStep = 0.25f;

		private static readonly Collider[] ColliderBuffer = (Collider[])(object)new Collider[128];

		internal static float ScaleForQuality(float baseValue, int itemQuality)
		{
			return baseValue * (1f + (float)Mathf.Max(0, itemQuality - 1) * 0.25f);
		}

		internal static Character FindCharacter(Collider collider)
		{
			if (!Object.op_Implicit((Object)(object)collider))
			{
				return null;
			}
			GameObject val = Projectile.FindHitObject(collider);
			if (!Object.op_Implicit((Object)(object)val))
			{
				return null;
			}
			return val.GetComponent<Character>();
		}

		internal static bool IsValidEnemy(Character owner, Character candidate)
		{
			if (!Object.op_Implicit((Object)(object)owner) || !Object.op_Implicit((Object)(object)candidate) || (Object)(object)owner == (Object)(object)candidate || candidate.IsDead())
			{
				return false;
			}
			if (!BaseAI.IsEnemy(owner, candidate))
			{
				if (Object.op_Implicit((Object)(object)candidate.GetBaseAI()) && candidate.GetBaseAI().IsAggravatable())
				{
					return owner.IsPlayer();
				}
				return false;
			}
			return true;
		}

		internal static Character FindNearestEnemy(Character owner, Character excluded, Vector3 origin, float radius)
		{
			//IL_0024: 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)
			//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)
			int mask = LayerMask.GetMask(new string[3] { "character", "character_net", "character_ghost" });
			int num = Physics.OverlapSphereNonAlloc(origin, radius, ColliderBuffer, mask, (QueryTriggerInteraction)2);
			Character result = null;
			float num2 = float.MaxValue;
			HashSet<Character> hashSet = new HashSet<Character>();
			for (int i = 0; i < num; i++)
			{
				Character val = FindCharacter(ColliderBuffer[i]);
				if (Object.op_Implicit((Object)(object)val) && !((Object)(object)val == (Object)(object)excluded) && hashSet.Add(val) && IsValidEnemy(owner, val))
				{
					Vector3 val2 = val.GetCenterPoint() - origin;
					float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude;
					if (sqrMagnitude < num2)
					{
						num2 = sqrMagnitude;
						result = val;
					}
				}
			}
			return result;
		}

		internal static int FindEnemiesInSphere(Character owner, Vector3 origin, float radius, Character[] results)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			int mask = LayerMask.GetMask(new string[3] { "character", "character_net", "character_ghost" });
			int num = Physics.OverlapSphereNonAlloc(origin, radius, ColliderBuffer, mask, (QueryTriggerInteraction)2);
			int num2 = 0;
			HashSet<Character> hashSet = new HashSet<Character>();
			for (int i = 0; i < num; i++)
			{
				if (num2 >= results.Length)
				{
					break;
				}
				Character val = FindCharacter(ColliderBuffer[i]);
				if (Object.op_Implicit((Object)(object)val) && hashSet.Add(val) && IsValidEnemy(owner, val))
				{
					results[num2++] = val;
				}
			}
			return num2;
		}

		internal static int FindEnemiesAlongSegment(Character owner, Vector3 start, Vector3 end, float radius, Character[] results)
		{
			//IL_0024: 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)
			int mask = LayerMask.GetMask(new string[3] { "character", "character_net", "character_ghost" });
			int num = Physics.OverlapCapsuleNonAlloc(start, end, radius, ColliderBuffer, mask, (QueryTriggerInteraction)2);
			int num2 = 0;
			HashSet<Character> hashSet = new HashSet<Character>();
			for (int i = 0; i < num; i++)
			{
				if (num2 >= results.Length)
				{
					break;
				}
				Character val = FindCharacter(ColliderBuffer[i]);
				if (Object.op_Implicit((Object)(object)val) && hashSet.Add(val) && IsValidEnemy(owner, val))
				{
					results[num2++] = val;
				}
			}
			return num2;
		}

		internal static void DealDamage(Character owner, Character target, Vector3 point, Vector3 direction, DamageTypes damage, SkillType skill)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: 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_0086: 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_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: 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_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Expected O, but got Unknown
			if (Object.op_Implicit((Object)(object)owner) && Object.op_Implicit((Object)(object)target) && !target.IsDead())
			{
				HitData val = new HitData
				{
					m_damage = damage,
					m_point = point,
					m_dir = ((((Vector3)(ref direction)).sqrMagnitude > 0.001f) ? ((Vector3)(ref direction)).normalized : Vector3.up),
					m_pushForce = 0f,
					m_backstabBonus = 1f,
					m_staggerMultiplier = 1f,
					m_dodgeable = false,
					m_blockable = false,
					m_ranged = true,
					m_skill = skill,
					m_skillLevel = owner.GetSkillLevel(skill),
					m_skillRaiseAmount = 0f,
					m_hitType = (HitType)((!owner.IsPlayer()) ? 1 : 2)
				};
				val.SetAttacker(owner);
				target.Damage(val);
			}
		}
	}
}
namespace StaffsOfFracturing.Projectiles
{
	internal abstract class FractureBallBehaviour : MonoBehaviour
	{
		private bool initialized;

		protected Projectile Projectile { get; private set; }

		protected Character Owner { get; private set; }

		protected ItemData Weapon { get; private set; }

		protected int ItemQuality { get; private set; } = 1;

		internal bool IsLive { get; private set; } = true;

		internal Character ShotOwner => Owner;

		internal int ShotQuality => ItemQuality;

		protected virtual void Awake()
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected O, but got Unknown
			Projectile = ((Component)this).GetComponent<Projectile>();
			if (Object.op_Implicit((Object)(object)Projectile))
			{
				Projectile projectile = Projectile;
				projectile.m_onHit = (OnProjectileHit)Delegate.Combine((Delegate?)(object)projectile.m_onHit, (Delegate?)new OnProjectileHit(HandleHit));
			}
		}

		internal void Initialize(Character owner, ItemData weapon, HitData originalHit)
		{
			if (!initialized)
			{
				initialized = true;
				Owner = owner;
				Weapon = weapon;
				ItemQuality = ((weapon == null) ? 1 : Mathf.Max(1, weapon.m_quality));
				OnInitialized(originalHit);
			}
		}

		protected abstract void OnInitialized(HitData originalHit);

		protected abstract void OnImpact(Collider collider, Vector3 hitPoint, bool water);

		private void HandleHit(Collider collider, Vector3 hitPoint, bool water)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			if (IsLive)
			{
				IsLive = false;
				if (initialized && Object.op_Implicit((Object)(object)Owner))
				{
					OnImpact(collider, hitPoint, water);
				}
			}
		}

		protected virtual void OnDestroy()
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			IsLive = false;
			if (Object.op_Implicit((Object)(object)Projectile))
			{
				Projectile projectile = Projectile;
				projectile.m_onHit = (OnProjectileHit)Delegate.Remove((Delegate?)(object)projectile.m_onHit, (Delegate?)new OnProjectileHit(HandleHit));
			}
		}
	}
	[HarmonyPatch(typeof(Projectile), "Setup")]
	internal static class ProjectileSetupPatch
	{
		private static void Postfix(Projectile __instance, Character owner, HitData hitData, ItemData item)
		{
			((Component)__instance).GetComponent<FractureBallBehaviour>()?.Initialize(owner, item, hitData);
		}
	}
}
namespace StaffsOfFracturing.Poison
{
	internal sealed class NetworkPoisonZone : MonoBehaviour
	{
		private static readonly int RadiusHash = StringExtensionMethods.GetStableHashCode("sof_poison_radius");

		private static readonly int ImmobilizedHash = StringExtensionMethods.GetStableHashCode("Immobilized");

		private static readonly Character[] Targets = (Character[])(object)new Character[64];

		private static readonly Dictionary<ZDOID, float> NextTargetCheck = new Dictionary<ZDOID, float>();

		private ZNetView networkView;

		private Character owner;

		private int itemQuality;

		private float radius;

		private float expiresAt;

		private float nextCheck;

		private bool initialized;

		private bool visualScaleApplied;

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

		internal void Initialize(Character source, int quality, float areaRadius, float duration)
		{
			if (Object.op_Implicit((Object)(object)networkView) && networkView.IsValid() && networkView.IsOwner() && Object.op_Implicit((Object)(object)source))
			{
				owner = source;
				itemQuality = Mathf.Max(1, quality);
				radius = areaRadius;
				expiresAt = Time.time + duration;
				nextCheck = Time.time + ModConfig.ImmobilizeCheckInterval.Value;
				initialized = true;
				networkView.GetZDO().Set(RadiusHash, radius);
				ApplyVisualScale(radius);
			}
		}

		private void Update()
		{
			if (!visualScaleApplied && Object.op_Implicit((Object)(object)networkView) && networkView.IsValid())
			{
				float num = networkView.GetZDO().GetFloat(RadiusHash, 0f);
				if (num > 0f)
				{
					ApplyVisualScale(num);
				}
			}
			if (initialized && Object.op_Implicit((Object)(object)networkView) && networkView.IsValid() && networkView.IsOwner())
			{
				if (!Object.op_Implicit((Object)(object)owner) || Time.time >= expiresAt)
				{
					DestroyNetworked();
				}
				else if (!(Time.time < nextCheck))
				{
					float value = ModConfig.ImmobilizeCheckInterval.Value;
					nextCheck = Time.time + value;
					CheckTargets(value);
				}
			}
		}

		private void CheckTargets(float interval)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: 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_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			int num = DamageUtility.FindEnemiesInSphere(owner, ((Component)this).transform.position, radius, Targets);
			float time = Time.time;
			for (int i = 0; i < num; i++)
			{
				Character val = Targets[i];
				Targets[i] = null;
				if (!Object.op_Implicit((Object)(object)val))
				{
					continue;
				}
				ZDOID zDOID = val.GetZDOID();
				if (!NextTargetCheck.TryGetValue(zDOID, out var value) || !(time < value))
				{
					NextTargetCheck[zDOID] = time + interval;
					SEMan sEMan = val.GetSEMan();
					if (!sEMan.HaveStatusEffect(ImmobilizedHash) && Random.value <= ModConfig.ImmobilizeChance.Value)
					{
						sEMan.AddStatusEffect(ImmobilizedHash, false, itemQuality, owner.GetSkillLevel((SkillType)9));
					}
				}
			}
			if (NextTargetCheck.Count > 256)
			{
				PruneCooldowns(time - 30f);
			}
		}

		private static void PruneCooldowns(float olderThan)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			List<ZDOID> list = new List<ZDOID>();
			foreach (KeyValuePair<ZDOID, float> item in NextTargetCheck)
			{
				if (item.Value < olderThan)
				{
					list.Add(item.Key);
				}
			}
			foreach (ZDOID item2 in list)
			{
				NextTargetCheck.Remove(item2);
			}
		}

		private void ApplyVisualScale(float areaRadius)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			((Component)this).transform.localScale = Vector3.one * Mathf.Clamp(areaRadius / 3.5f, 0.35f, 1.75f);
			visualScaleApplied = true;
		}

		private void DestroyNetworked()
		{
			initialized = false;
			if (Object.op_Implicit((Object)(object)ZNetScene.instance))
			{
				ZNetScene.instance.Destroy(((Component)this).gameObject);
			}
			else
			{
				Object.Destroy((Object)(object)((Component)this).gameObject);
			}
		}
	}
	internal sealed class PoisonBallBehaviour : FractureBallBehaviour
	{
		protected override void OnInitialized(HitData originalHit)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			base.Projectile.m_aoe = ModConfig.PoisonExplosionRadius.Value;
			base.Projectile.m_damage = new DamageTypes
			{
				m_blunt = DamageUtility.ScaleForQuality(ModConfig.PoisonBluntDamage.Value, base.ItemQuality),
				m_poison = DamageUtility.ScaleForQuality(ModConfig.PoisonDamage.Value, base.ItemQuality)
			};
			base.Projectile.m_type = (ProjectileType)17410;
		}

		protected override void OnImpact(Collider collider, Vector3 hitPoint, bool water)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)ContentRegistry.PoisonZonePrefab))
			{
				Object.Instantiate<GameObject>(ContentRegistry.PoisonZonePrefab, hitPoint, Quaternion.identity).GetComponent<NetworkPoisonZone>()?.Initialize(base.Owner, base.ItemQuality, ModConfig.PoisonExplosionRadius.Value, ModConfig.PoisonDuration.Value);
			}
		}
	}
}
namespace StaffsOfFracturing.Plugin
{
	[BepInPlugin("com.l4zershark.staffsoffracturing", "Staffs of Fracturing", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	[SynchronizationMode(/*Could not decode attribute arguments.*/)]
	public sealed class StaffsOfFracturingPlugin : BaseUnityPlugin
	{
		public const string ModGuid = "com.l4zershark.staffsoffracturing";

		public const string ModName = "Staffs of Fracturing";

		public const string ModVersion = "1.0.0";

		private Harmony harmony;

		internal static StaffsOfFracturingPlugin Instance { get; private set; }

		internal ManualLogSource ModLogger => ((BaseUnityPlugin)this).Logger;

		private void Awake()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			Instance = this;
			ModConfig.Bind(((BaseUnityPlugin)this).Config);
			harmony = new Harmony("com.l4zershark.staffsoffracturing");
			harmony.PatchAll();
			PrefabManager.OnVanillaPrefabsAvailable += RegisterContent;
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Staffs of Fracturing 1.0.0 initialized; waiting for vanilla prefabs.");
		}

		private void RegisterContent()
		{
			try
			{
				ContentRegistry.RegisterAll();
			}
			catch (Exception arg)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)$"Content registration failed: {arg}");
			}
		}

		private void OnDestroy()
		{
			PrefabManager.OnVanillaPrefabsAvailable -= RegisterContent;
			Harmony obj = harmony;
			if (obj != null)
			{
				obj.UnpatchSelf();
			}
			if ((Object)(object)Instance == (Object)(object)this)
			{
				Instance = null;
			}
		}
	}
}
namespace StaffsOfFracturing.Networking
{
	internal sealed class NetworkArcBehaviour : MonoBehaviour
	{
		private static readonly int StartHash = StringExtensionMethods.GetStableHashCode("sof_arc_start");

		private static readonly int EndHash = StringExtensionMethods.GetStableHashCode("sof_arc_end");

		private ZNetView networkView;

		private bool applied;

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

		internal void Initialize(Vector3 start, Vector3 end)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)networkView) && networkView.IsValid() && networkView.IsOwner())
			{
				networkView.GetZDO().Set(StartHash, start);
				networkView.GetZDO().Set(EndHash, end);
				Apply(start, end);
			}
		}

		private void Update()
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			if (!applied && Object.op_Implicit((Object)(object)networkView) && networkView.IsValid())
			{
				ZDO zDO = networkView.GetZDO();
				Vector3 start = default(Vector3);
				Vector3 end = default(Vector3);
				if (zDO.GetVec3(StartHash, ref start) && zDO.GetVec3(EndHash, ref end))
				{
					Apply(start, end);
				}
			}
		}

		private void Apply(Vector3 start, Vector3 end)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: 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_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = end - start;
			float magnitude = ((Vector3)(ref val)).magnitude;
			if (!(magnitude < 0.05f))
			{
				((Component)this).transform.position = start;
				((Component)this).transform.rotation = Quaternion.LookRotation(val / magnitude);
				((Component)this).transform.localScale = Vector3.one * magnitude;
				applied = true;
			}
		}
	}
}
namespace StaffsOfFracturing.Localization
{
	internal static class EnglishLocalization
	{
		internal static void Register()
		{
			CustomLocalization localization = LocalizationManager.Instance.GetLocalization();
			string text = "English";
			localization.AddTranslation(ref text, new Dictionary<string, string>
			{
				{ "sof_staff_iolite", "Iolite Staff of Fracturing" },
				{ "sof_staff_iolite_desc", "A fractured galdr staff awakened by iolite. Its splinters shock foes, leap to nearby enemies, and weave brief arcs between one another." },
				{ "sof_staff_jade", "Jade Staff of Fracturing" },
				{ "sof_staff_jade_desc", "A fractured galdr staff corrupted by jade. Its splinters burst into broad poison fields that can immobilize enemies caught within." },
				{ "sof_staff_bloodstone", "Bloodstone Staff of Fracturing" },
				{ "sof_staff_bloodstone_desc", "A fractured galdr staff steeped in bloodstone. Its splinters erupt with blunt force and launch bright, piercing blood shards." }
			});
		}
	}
}
namespace StaffsOfFracturing.Lightning
{
	internal sealed class LightningBallBehaviour : FractureBallBehaviour
	{
		protected override void OnInitialized(HitData originalHit)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			base.Projectile.m_aoe = 0.6f;
			base.Projectile.m_damage = new DamageTypes
			{
				m_lightning = DamageUtility.ScaleForQuality(ModConfig.LightningDamage.Value, base.ItemQuality)
			};
			base.Projectile.m_type = (ProjectileType)147458;
			LightningWebCoordinator.Register(this);
		}

		protected override void OnImpact(Collider collider, Vector3 hitPoint, bool water)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_006b: 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_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_0087: 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_0090: 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_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: 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)
			if (water || Random.value > ModConfig.EnemyChainChance.Value)
			{
				return;
			}
			Character val = DamageUtility.FindCharacter(collider);
			if (DamageUtility.IsValidEnemy(base.Owner, val))
			{
				Character val2 = DamageUtility.FindNearestEnemy(base.Owner, val, val.GetCenterPoint(), ModConfig.ChainRange.Value);
				if (Object.op_Implicit((Object)(object)val2))
				{
					Vector3 val3 = val.GetCenterPoint() + Vector3.up * 0.15f;
					Vector3 val4 = val2.GetCenterPoint() + Vector3.up * 0.15f;
					VfxFactory.SpawnLightningArc(val3, val4);
					DamageTypes damage = new DamageTypes
					{
						m_lightning = DamageUtility.ScaleForQuality(ModConfig.LightningDamage.Value, base.ItemQuality)
					};
					DamageUtility.DealDamage(base.Owner, val2, val4, val4 - val3, damage, (SkillType)9);
				}
			}
		}
	}
	internal static class LightningWebCoordinator
	{
		private readonly struct ShotKey : IEquatable<ShotKey>
		{
			private readonly ZDOID owner;

			private readonly int frame;

			internal ShotKey(ZDOID owner, int frame)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				this.owner = owner;
				this.frame = frame;
			}

			public bool Equals(ShotKey other)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_000a: Unknown result type (might be due to invalid IL or missing references)
				ZDOID val = owner;
				if (((ZDOID)(ref val)).Equals(other.owner))
				{
					return frame == other.frame;
				}
				return false;
			}

			public override bool Equals(object obj)
			{
				if (obj is ShotKey other)
				{
					return Equals(other);
				}
				return false;
			}

			public override int GetHashCode()
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				return (((object)owner/*cast due to .constrained prefix*/).GetHashCode() * 397) ^ frame;
			}
		}

		private const int MaximumLinksPerShot = 24;

		private const float FormationDelay = 0.13f;

		private const float SegmentRadius = 0.3f;

		private static readonly Dictionary<ShotKey, List<LightningBallBehaviour>> Shots = new Dictionary<ShotKey, List<LightningBallBehaviour>>();

		private static readonly Character[] SegmentTargets = (Character[])(object)new Character[64];

		internal static void Register(LightningBallBehaviour ball)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)ball) && Object.op_Implicit((Object)(object)ball.ShotOwner) && Object.op_Implicit((Object)(object)StaffsOfFracturingPlugin.Instance))
			{
				ShotKey key = new ShotKey(ball.ShotOwner.GetZDOID(), Time.frameCount);
				if (!Shots.TryGetValue(key, out var value))
				{
					value = new List<LightningBallBehaviour>(12);
					Shots.Add(key, value);
					((MonoBehaviour)StaffsOfFracturingPlugin.Instance).StartCoroutine(FormWeb(key));
				}
				value.Add(ball);
			}
		}

		private static IEnumerator FormWeb(ShotKey key)
		{
			yield return (object)new WaitForSeconds(0.13f);
			if (!Shots.TryGetValue(key, out var value))
			{
				yield break;
			}
			Shots.Remove(key);
			List<LightningBallBehaviour> list = new List<LightningBallBehaviour>(value.Count);
			foreach (LightningBallBehaviour item in value)
			{
				if (Object.op_Implicit((Object)(object)item) && item.IsLive)
				{
					list.Add(item);
				}
			}
			if (list.Count < 2)
			{
				yield break;
			}
			Character shotOwner = list[0].ShotOwner;
			int shotQuality = list[0].ShotQuality;
			Dictionary<Character, float> cooldowns = new Dictionary<Character, float>();
			int num = 0;
			float num2 = ModConfig.ChainRange.Value * 1.5f;
			for (int i = 0; i < list.Count - 1; i++)
			{
				if (num >= 24)
				{
					break;
				}
				for (int j = i + 1; j < list.Count; j++)
				{
					if (num >= 24)
					{
						break;
					}
					LightningBallBehaviour lightningBallBehaviour = list[i];
					LightningBallBehaviour lightningBallBehaviour2 = list[j];
					if (Object.op_Implicit((Object)(object)lightningBallBehaviour) && Object.op_Implicit((Object)(object)lightningBallBehaviour2) && lightningBallBehaviour.IsLive && lightningBallBehaviour2.IsLive)
					{
						Vector3 position = ((Component)lightningBallBehaviour).transform.position;
						Vector3 position2 = ((Component)lightningBallBehaviour2).transform.position;
						Vector3 val = position2 - position;
						if (!(((Vector3)(ref val)).sqrMagnitude > num2 * num2) && !(Random.value > ModConfig.BallChainChance.Value))
						{
							num++;
							VfxFactory.SpawnLightningArc(position, position2);
							DamageSegment(shotOwner, shotQuality, position, position2, cooldowns);
						}
					}
				}
			}
		}

		private static void DamageSegment(Character owner, int quality, Vector3 start, Vector3 end, Dictionary<Character, float> cooldowns)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: 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_009e: 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_00a4: 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_00a7: 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_00ad: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)owner) || ModConfig.LightningWebDamage.Value <= 0f)
			{
				return;
			}
			int num = DamageUtility.FindEnemiesAlongSegment(owner, start, end, 0.3f, SegmentTargets);
			float time = Time.time;
			for (int i = 0; i < num; i++)
			{
				Character val = SegmentTargets[i];
				SegmentTargets[i] = null;
				if (Object.op_Implicit((Object)(object)val) && (!cooldowns.TryGetValue(val, out var value) || !(time - value < ModConfig.LightningWebHitCooldown.Value)))
				{
					cooldowns[val] = time;
					Vector3 centerPoint = val.GetCenterPoint();
					DamageTypes damage = new DamageTypes
					{
						m_lightning = DamageUtility.ScaleForQuality(ModConfig.LightningWebDamage.Value, quality)
					};
					DamageUtility.DealDamage(owner, val, centerPoint, end - start, damage, (SkillType)9);
				}
			}
		}
	}
}
namespace StaffsOfFracturing.Items
{
	internal static class ContentRegistry
	{
		private sealed class VariantDefinition
		{
			internal string ItemPrefabName { get; }

			internal string PrimaryPrefabName { get; }

			internal string SecondaryPrefabName { get; }

			internal string NameToken { get; }

			internal string DescriptionToken { get; }

			internal string GemPrefabName { get; }

			internal ElementTheme Theme { get; }

			internal VariantDefinition(string itemPrefabName, string primaryPrefabName, string secondaryPrefabName, string nameToken, string descriptionToken, string gemPrefabName, ElementTheme theme)
			{
				ItemPrefabName = itemPrefabName;
				PrimaryPrefabName = primaryPrefabName;
				SecondaryPrefabName = secondaryPrefabName;
				NameToken = nameToken;
				DescriptionToken = descriptionToken;
				GemPrefabName = gemPrefabName;
				Theme = theme;
			}
		}

		private readonly struct VanillaSnapshot
		{
			private readonly SharedData shared;

			private readonly string name;

			private readonly float blunt;

			private readonly float fire;

			private readonly GameObject attackProjectile;

			private readonly GameObject spawnedSecondary;

			private readonly int spawnCount;

			private VanillaSnapshot(SharedData shared, string name, float blunt, float fire, GameObject attackProjectile, GameObject spawnedSecondary, int spawnCount)
			{
				this.shared = shared;
				this.name = name;
				this.blunt = blunt;
				this.fire = fire;
				this.attackProjectile = attackProjectile;
				this.spawnedSecondary = spawnedSecondary;
				this.spawnCount = spawnCount;
			}

			internal static VanillaSnapshot Capture()
			{
				ItemDrop val = ContentRegistry.RequireComponent<ItemDrop>(RequiredPrefab("StaffClusterbomb"));
				Projectile val2 = ContentRegistry.RequireComponent<Projectile>(RequiredPrefab("staff_clusterbombstaff_projectile"));
				return new VanillaSnapshot(val.m_itemData.m_shared, val.m_itemData.m_shared.m_name, val.m_itemData.m_shared.m_damages.m_blunt, val.m_itemData.m_shared.m_damages.m_fire, val.m_itemData.m_shared.m_attack.m_attackProjectile, val2.m_spawnOnHit, val2.m_spawnCount);
			}

			internal void AssertUnchanged()
			{
				ItemDrop obj = ContentRegistry.RequireComponent<ItemDrop>(RequiredPrefab("StaffClusterbomb"));
				Projectile val = ContentRegistry.RequireComponent<Projectile>(RequiredPrefab("staff_clusterbombstaff_projectile"));
				SharedData val2 = obj.m_itemData.m_shared;
				if (shared != val2 || val2.m_name != name || !Mathf.Approximately(val2.m_damages.m_blunt, blunt) || !Mathf.Approximately(val2.m_damages.m_fire, fire) || (Object)(object)val2.m_attack.m_attackProjectile != (Object)(object)attackProjectile || (Object)(object)val.m_spawnOnHit != (Object)(object)spawnedSecondary || val.m_spawnCount != spawnCount)
				{
					throw new InvalidOperationException("The vanilla Staff of Fracturing mutation audit failed.");
				}
			}
		}

		private const string VanillaStaff = "StaffClusterbomb";

		private const string VanillaPrimary = "staff_clusterbombstaff_projectile";

		private const string VanillaSecondary = "staff_clusterbombstaff_splinter_projectile";

		private static bool registered;

		private static CustomItem ioliteItem;

		private static CustomItem jadeItem;

		private static CustomItem bloodstoneItem;

		internal static GameObject PoisonZonePrefab => VfxFactory.PoisonZonePrefab;

		internal static GameObject BloodShrapnelPrefab => VfxFactory.BloodShrapnelPrefab;

		private static ManualLogSource Log => StaffsOfFracturingPlugin.Instance.ModLogger;

		internal static void RegisterAll()
		{
			if (!registered)
			{
				ValidateVanillaDependencies();
				VanillaSnapshot vanillaSnapshot = VanillaSnapshot.Capture();
				EnglishLocalization.Register();
				VfxFactory.BuildSharedPrefabs();
				ioliteItem = CreateVariant(new VariantDefinition("SOF_StaffFracturingIolite", "SOF_StaffFracturingIolite_Projectile", "SOF_StaffFracturingIolite_Ball", "$sof_staff_iolite", "$sof_staff_iolite_desc", "GemstoneBlue", ElementTheme.Lightning));
				jadeItem = CreateVariant(new VariantDefinition("SOF_StaffFracturingJade", "SOF_StaffFracturingJade_Projectile", "SOF_StaffFracturingJade_Ball", "$sof_staff_jade", "$sof_staff_jade_desc", "GemstoneGreen", ElementTheme.Poison));
				bloodstoneItem = CreateVariant(new VariantDefinition("SOF_StaffFracturingBloodstone", "SOF_StaffFracturingBloodstone_Projectile", "SOF_StaffFracturingBloodstone_Ball", "$sof_staff_bloodstone", "$sof_staff_bloodstone_desc", "GemstoneRed", ElementTheme.Blood));
				registered = true;
				RefreshDisplayedDamage();
				vanillaSnapshot.AssertUnchanged();
				AuditCustomContent();
				Log.LogInfo((object)"Registered three gemstone staffs, six fracture prefabs, bounded network VFX, recipes and localization.");
			}
		}

		internal static void RefreshDisplayedDamage()
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: 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_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: 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)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			CustomItem obj = ioliteItem;
			if (Object.op_Implicit((Object)(object)((obj != null) ? obj.ItemDrop : null)))
			{
				SetDamage(ioliteItem.ItemDrop.m_itemData.m_shared, new DamageTypes
				{
					m_lightning = ModConfig.LightningDamage.Value
				}, new DamageTypes
				{
					m_lightning = ModConfig.LightningDamage.Value * 0.25f
				});
			}
			CustomItem obj2 = jadeItem;
			if (Object.op_Implicit((Object)(object)((obj2 != null) ? obj2.ItemDrop : null)))
			{
				SetDamage(jadeItem.ItemDrop.m_itemData.m_shared, new DamageTypes
				{
					m_blunt = ModConfig.PoisonBluntDamage.Value,
					m_poison = ModConfig.PoisonDamage.Value
				}, new DamageTypes
				{
					m_blunt = ModConfig.PoisonBluntDamage.Value * 0.25f,
					m_poison = ModConfig.PoisonDamage.Value * 0.25f
				});
			}
			CustomItem obj3 = bloodstoneItem;
			if (Object.op_Implicit((Object)(object)((obj3 != null) ? obj3.ItemDrop : null)))
			{
				SetDamage(bloodstoneItem.ItemDrop.m_itemData.m_shared, new DamageTypes
				{
					m_blunt = ModConfig.BloodExplosionBluntDamage.Value
				}, new DamageTypes
				{
					m_blunt = ModConfig.BloodExplosionBluntDamage.Value * 0.25f
				});
			}
		}

		private static CustomItem CreateVariant(VariantDefinition definition)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Expected O, but got Unknown
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Expected O, but got Unknown
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Expected O, but got Unknown
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Expected O, but got Unknown
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Expected O, but got Unknown
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Expected O, but got Unknown
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_020c: 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_0228: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = CloneRequired(definition.SecondaryPrefabName, "staff_clusterbombstaff_splinter_projectile");
			ConfigureSecondary(val, definition.Theme);
			PrefabManager.Instance.AddPrefab(new CustomPrefab(val, false));
			GameObject val2 = CloneRequired(definition.PrimaryPrefabName, "staff_clusterbombstaff_projectile");
			Projectile obj = RequireComponent<Projectile>(val2);
			obj.m_spawnOnHit = val;
			obj.m_hitEffects = VfxFactory.GetHitEffects(definition.Theme);
			VfxFactory.StyleProjectile(val2, definition.Theme, secondary: false);
			PrefabManager.Instance.AddPrefab(new CustomPrefab(val2, false));
			ItemConfig val3 = new ItemConfig();
			val3.Name = definition.NameToken;
			val3.Description = definition.DescriptionToken;
			val3.CraftingStation = CraftingStations.GaldrTable;
			val3.RepairStation = CraftingStations.GaldrTable;
			val3.MinStationLevel = 2;
			val3.Amount = 1;
			val3.Requirements = (RequirementConfig[])(object)new RequirementConfig[3]
			{
				new RequirementConfig("StaffClusterbomb", 1, 0, true),
				new RequirementConfig("FlametalNew", 5, 5, true),
				new RequirementConfig(definition.GemPrefabName, 1, 1, true)
			};
			ItemConfig val4 = val3;
			CustomItem val5 = new CustomItem(definition.ItemPrefabName, "StaffClusterbomb", val4);
			if (!Object.op_Implicit((Object)(object)val5.ItemPrefab) || !Object.op_Implicit((Object)(object)val5.ItemDrop))
			{
				throw new InvalidOperationException("Could not create item '" + definition.ItemPrefabName + "'.");
			}
			ItemDrop val6 = RequireComponent<ItemDrop>(RequiredPrefab("StaffClusterbomb"));
			SharedData shared = val5.ItemDrop.m_itemData.m_shared;
			if (shared == val6.m_itemData.m_shared || shared.m_attack == val6.m_itemData.m_shared.m_attack)
			{
				throw new InvalidOperationException("Clone '" + definition.ItemPrefabName + "' unexpectedly shares mutable item data with the vanilla staff.");
			}
			shared.m_attack.m_attackProjectile = val2;
			shared.m_skillType = (SkillType)9;
			shared.m_attackStatusEffect = null;
			shared.m_attackStatusEffectChance = 1f;
			shared.m_projectileToolTip = true;
			Sprite val7 = ((shared.m_icons != null && shared.m_icons.Length != 0) ? shared.m_icons[0] : null);
			Color tint = ThemeColor(definition.Theme);
			if (Object.op_Implicit((Object)(object)val7))
			{
				shared.m_icons = (Sprite[])(object)new Sprite[1] { VfxStyler.CreateTintedIcon(val7, tint) };
			}
			VfxFactory.StyleStaff(val5.ItemPrefab, definition.Theme);
			ItemManager.Instance.AddItem(val5);
			return val5;
		}

		private static void ConfigureSecondary(GameObject secondary, ElementTheme theme)
		{
			Projectile obj = RequireComponent<Projectile>(secondary);
			obj.m_spawnOnHit = null;
			obj.m_spawnOnTtl = false;
			obj.m_spawnCount = 0;
			obj.m_randomSpawnOnHit.Clear();
			obj.m_randomSpawnOnHitCount = 0;
			obj.m_respawnItemOnHit = false;
			obj.m_projectilesInheritHitData = false;
			obj.m_onlySpawnedProjectilesDealDamage = false;
			obj.m_hitEffects = VfxFactory.GetHitEffects(theme);
			switch (theme)
			{
			case ElementTheme.Lightning:
				secondary.AddComponent<LightningBallBehaviour>();
				break;
			case ElementTheme.Poison:
				secondary.AddComponent<PoisonBallBehaviour>();
				break;
			case ElementTheme.Blood:
				secondary.AddComponent<BloodBallBehaviour>();
				break;
			default:
				throw new ArgumentOutOfRangeException("theme", theme, null);
			}
			VfxFactory.StyleProjectile(secondary, theme, secondary: true);
		}

		private static void SetDamage(SharedData shared, DamageTypes baseDamage, DamageTypes perLevel)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			shared.m_damages = baseDamage;
			shared.m_damagesPerLevel = perLevel;
		}

		private static void ValidateVanillaDependencies()
		{
			string[] array = new string[14]
			{
				"StaffClusterbomb", "staff_clusterbombstaff_projectile", "staff_clusterbombstaff_splinter_projectile", "StaffLightning", "fx_chainlightning_hit", "fx_chainlightning_spread", "fx_clusterbombstaff_hit", "poisoncloud", "vfx_Poison", "projectile_splitner_lightning",
				"GemstoneBlue", "GemstoneGreen", "GemstoneRed", "FlametalNew"
			};
			for (int i = 0; i < array.Length; i++)
			{
				RequiredPrefab(array[i]);
			}
		}

		private static void AuditCustomContent()
		{
			AssertBall<LightningBallBehaviour>("SOF_StaffFracturingIolite_Ball");
			AssertBall<PoisonBallBehaviour>("SOF_StaffFracturingJade_Ball");
			AssertBall<BloodBallBehaviour>("SOF_StaffFracturingBloodstone_Ball");
			Projectile val = RequireComponent<Projectile>(BloodShrapnelPrefab);
			if (Object.op_Implicit((Object)(object)val.m_spawnOnHit) || val.m_spawnOnTtl || val.m_respawnItemOnHit || Object.op_Implicit((Object)(object)((Component)val).GetComponent<BloodBallBehaviour>()))
			{
				throw new InvalidOperationException("Blood shrapnel recursion guard audit failed.");
			}
			if (!Object.op_Implicit((Object)(object)VfxFactory.LightningArcPrefab.GetComponent<ZNetView>()) || !Object.op_Implicit((Object)(object)PoisonZonePrefab.GetComponent<ZNetView>()))
			{
				throw new InvalidOperationException("Network VFX audit failed: a temporary effect lacks ZNetView.");
			}
		}

		private static void AssertBall<T>(string prefabName) where T : Component
		{
			GameObject obj = RequiredPrefab(prefabName);
			Projectile val = RequireComponent<Projectile>(obj);
			if (!Object.op_Implicit((Object)(object)obj.GetComponent<T>()) || Object.op_Implicit((Object)(object)val.m_spawnOnHit) || val.m_spawnOnTtl)
			{
				throw new InvalidOperationException("Fracture-ball audit failed for '" + prefabName + "'.");
			}
		}

		private static GameObject CloneRequired(string name, string baseName)
		{
			GameObject val = PrefabManager.Instance.CreateClonedPrefab(name, baseName);
			if (!Object.op_Implicit((Object)(object)val))
			{
				throw new InvalidOperationException("Could not clone '" + baseName + "' as '" + name + "'.");
			}
			return val;
		}

		private static GameObject RequiredPrefab(string name)
		{
			GameObject prefab = PrefabManager.Instance.GetPrefab(name);
			if (!Object.op_Implicit((Object)(object)prefab))
			{
				throw new InvalidOperationException("Required prefab '" + name + "' was not found in the current Valheim build.");
			}
			return prefab;
		}

		private static T RequireComponent<T>(GameObject gameObject) where T : Component
		{
			T component = gameObject.GetComponent<T>();
			if (!Object.op_Implicit((Object)(object)component))
			{
				throw new InvalidOperationException("Prefab '" + ((Object)gameObject).name + "' lacks required component " + typeof(T).Name + ".");
			}
			return component;
		}

		private static Color ThemeColor(ElementTheme theme)
		{
			//IL_0009: 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)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			return (Color)(theme switch
			{
				ElementTheme.Lightning => VfxStyler.Lightning, 
				ElementTheme.Poison => VfxStyler.Poison, 
				_ => VfxStyler.Blood, 
			});
		}
	}
}
namespace StaffsOfFracturing.Configuration
{
	internal static class ModConfig
	{
		internal static ConfigEntry<float> EnemyChainChance { get; private set; }

		internal static ConfigEntry<float> BallChainChance { get; private set; }

		internal static ConfigEntry<float> LightningDamage { get; private set; }

		internal static ConfigEntry<float> ChainRange { get; private set; }

		internal static ConfigEntry<float> LightningWebDamage { get; private set; }

		internal static ConfigEntry<float> LightningWebHitCooldown { get; private set; }

		internal static ConfigEntry<float> PoisonExplosionRadius { get; private set; }

		internal static ConfigEntry<float> PoisonBluntDamage { get; private set; }

		internal static ConfigEntry<float> PoisonDamage { get; private set; }

		internal static ConfigEntry<float> PoisonDuration { get; private set; }

		internal static ConfigEntry<float> ImmobilizeChance { get; private set; }

		internal static ConfigEntry<float> ImmobilizeCheckInterval { get; private set; }

		internal static ConfigEntry<float> BloodExplosionRadius { get; private set; }

		internal static ConfigEntry<float> BloodExplosionBluntDamage { get; private set; }

		internal static ConfigEntry<int> ShrapnelCount { get; private set; }

		internal static ConfigEntry<float> ShrapnelPierceDamage { get; private set; }

		internal static ConfigEntry<float> ShrapnelVelocity { get; private set; }

		internal static ConfigEntry<float> ShrapnelLifetime { get; private set; }

		internal static void Bind(ConfigFile config)
		{
			EnemyChainChance = Bind(config, "Lightning", "EnemyChainChance", 0.25f, "Independent chance that a lightning-ball enemy hit arcs once to the nearest other enemy.", 0f, 1f);
			BallChainChance = Bind(config, "Lightning", "BallChainChance", 0.25f, "Independent chance for each unordered pair of balls from one shot to form a web link.", 0f, 1f);
			LightningDamage = Bind(config, "Lightning", "LightningDamage", 18f, "Base lightning damage dealt by each fracture ball and a successful enemy chain.", 1f, 80f);
			ChainRange = Bind(config, "Lightning", "ChainRange", 8f, "Maximum enemy-chain range in metres; also bounds web-link length.", 2f, 20f);
			LightningWebDamage = Bind(config, "Lightning", "LightningWebDamage", 4f, "Lightning damage from intersecting a ball-to-ball web segment.", 0f, 30f);
			LightningWebHitCooldown = Bind(config, "Lightning", "LightningWebHitCooldown", 0.35f, "Minimum seconds before the same target may be damaged by another link from the shot.", 0.1f, 2f);
			PoisonExplosionRadius = Bind(config, "Poison", "ExplosionRadius", 3.5f, "Radius in metres of each Jade fracture-ball detonation and its lingering haze.", 1f, 6f);
			PoisonBluntDamage = Bind(config, "Poison", "BluntDamage", 8f, "Base blunt damage dealt by each Jade fracture-ball explosion.", 0f, 50f);
			PoisonDamage = Bind(config, "Poison", "PoisonDamage", 12f, "Base native poison damage applied by each Jade fracture-ball explosion.", 0f, 60f);
			PoisonDuration = Bind(config, "Poison", "PoisonDuration", 5f, "Lifetime in seconds of each poison-control area and its immobilization checks.", 1f, 12f);
			ImmobilizeChance = Bind(config, "Poison", "ImmobilizeChance", 0.2f, "Independent chance per affected enemy per check to apply Valheim's Immobilized effect.", 0f, 1f);
			ImmobilizeCheckInterval = Bind(config, "Poison", "ImmobilizeCheckInterval", 1f, "Seconds between per-enemy immobilization checks.", 0.25f, 3f);
			BloodExplosionRadius = Bind(config, "Blood", "ExplosionRadius", 2.25f, "Radius in metres of each Bloodstone fracture-ball blunt explosion.", 0.75f, 5f);
			BloodExplosionBluntDamage = Bind(config, "Blood", "ExplosionBluntDamage", 12f, "Base blunt damage dealt by each Bloodstone fracture-ball explosion.", 0f, 60f);
			ShrapnelCount = ConfigFileExtensions.BindConfigInOrder<int>(config, "Blood", "ShrapnelCount", 5, "Number of non-recursive projectiles launched by each detonation.", true, true, true, (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 8), (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			ShrapnelPierceDamage = Bind(config, "Blood", "ShrapnelPierceDamage", 7f, "Base pierce damage dealt by each shrapnel projectile.", 0f, 40f);
			ShrapnelVelocity = Bind(config, "Blood", "ShrapnelVelocity", 28f, "Launch velocity of Bloodstone shrapnel in metres per second.", 8f, 55f);
			ShrapnelLifetime = Bind(config, "Blood", "ShrapnelLifetime", 1.6f, "Lifetime of each shrapnel projectile in seconds.", 0.4f, 4f);
			SubscribeBalanceRefresh<float>(LightningDamage);
			SubscribeBalanceRefresh<float>(PoisonBluntDamage);
			SubscribeBalanceRefresh<float>(PoisonDamage);
			SubscribeBalanceRefresh<float>(BloodExplosionBluntDamage);
		}

		private static ConfigEntry<float> Bind(ConfigFile config, string section, string key, float defaultValue, string description, float minimum, float maximum)
		{
			return ConfigFileExtensions.BindConfigInOrder<float>(config, section, key, defaultValue, description, true, true, true, (AcceptableValueBase)(object)new AcceptableValueRange<float>(minimum, maximum), (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
		}

		private static void SubscribeBalanceRefresh<T>(ConfigEntry<T> entry)
		{
			entry.SettingChanged += delegate
			{
				ContentRegistry.RefreshDisplayedDamage();
			};
		}
	}
}
namespace StaffsOfFracturing.Blood
{
	internal sealed class BloodBallBehaviour : FractureBallBehaviour
	{
		protected override void OnInitialized(HitData originalHit)
		{
			//IL_001d: 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_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			base.Projectile.m_aoe = ModConfig.BloodExplosionRadius.Value;
			base.Projectile.m_damage = new DamageTypes
			{
				m_blunt = DamageUtility.ScaleForQuality(ModConfig.BloodExplosionBluntDamage.Value, base.ItemQuality)
			};
			base.Projectile.m_type = (ProjectileType)16394;
		}

		protected override void OnImpact(Collider collider, Vector3 hitPoint, bool water)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: 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_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: 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_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: 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_00c9: 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_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_00e9: 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_00ff: 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_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Expected O, but got Unknown
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)ContentRegistry.BloodShrapnelPrefab))
			{
				return;
			}
			int value = ModConfig.ShrapnelCount.Value;
			float pierce = DamageUtility.ScaleForQuality(ModConfig.ShrapnelPierceDamage.Value, base.ItemQuality);
			for (int i = 0; i < value; i++)
			{
				Vector3 val = Random.onUnitSphere;
				if (val.y < -0.15f)
				{
					val.y = (0f - val.y) * 0.4f;
				}
				val = ((Vector3)(ref val)).normalized;
				Vector3 val2 = hitPoint + val * 0.2f + Vector3.up * 0.12f;
				Projectile component = Object.Instantiate<GameObject>(ContentRegistry.BloodShrapnelPrefab, val2, Quaternion.LookRotation(val)).GetComponent<Projectile>();
				if (Object.op_Implicit((Object)(object)component))
				{
					component.m_ttl = ModConfig.ShrapnelLifetime.Value;
					HitData val3 = new HitData
					{
						m_damage = new DamageTypes
						{
							m_pierce = pierce
						},
						m_pushForce = 4f,
						m_backstabBonus = 1f,
						m_staggerMultiplier = 1f,
						m_dodgeable = true,
						m_blockable = true,
						m_ranged = true,
						m_skill = (SkillType)9,
						m_skillLevel = base.Owner.GetSkillLevel((SkillType)9),
						m_skillRaiseAmount = 0f,
						m_itemLevel = (short)base.ItemQuality,
						m_hitType = (HitType)((!base.Owner.IsPlayer()) ? 1 : 2)
					};
					val3.SetAttacker(base.Owner);
					component.Setup(base.Owner, val * ModConfig.ShrapnelVelocity.Value, 20f, val3, base.Weapon, (ItemData)null);
				}
			}
		}
	}
}