Decompiled source of Artificer v1.1.5

plugins\Artificer.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.EventSystems;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("0.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 Artificer
{
	[BepInPlugin("com.crasssam.artificer", "Artificer", "1.1.5")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	public sealed class ArtificerPlugin : BaseUnityPlugin
	{
		internal static ArtificerPlugin Instance;

		internal static readonly string[] Kinds = new string[5] { "Trap", "Twig", "Ballista", "Shield", "Obliterator" };

		internal static readonly int[] Seconds = new int[5] { 180, 60, 60, 30, 10 };

		internal static readonly float[] Stamina = new float[5] { 12f, 14f, 16f, 18f, 20f };

		internal static readonly float[] Eitr = new float[5] { 25f, 50f, 75f, 100f, 125f };

		private static readonly int[] RequiredTier = new int[5] { 0, 0, 1, 2, 3 };

		private static readonly string[] GearSlots = new string[3] { "Hood", "Tunic", "Trousers" };

		internal static readonly string[][] Visuals = new string[5][]
		{
			new string[1] { "piece_trap_troll" },
			new string[1] { "piece_TrainingDummy" },
			new string[1] { "piece_turret" },
			new string[2] { "piece_shieldgenerator", "piece_shield_generator" },
			new string[1] { "incinerator" }
		};

		internal static readonly string[] PackNames = new string[5] { "ArtificerPackTrap", "ArtificerPackTwig", "ArtificerPackBallista", "ArtificerPackShield", "ArtificerPackObliterator" };

		internal static readonly string[] GearNames = new string[4] { "ArtificerLeather", "ArtificerMist", "ArtificerAsh", "ArtificerNorth" };

		private static readonly string[] SetNames = new string[4] { "Tinker's Leathers", "Runewright's Gear", "Cinderwright's Gear", "Stormwright's Gear" };

		private readonly Dictionary<int, GameObject> summons = new Dictionary<int, GameObject>();

		private static readonly object[] destructionEffects = new object[5];

		private static readonly object[] placementEffects = new object[5];

		private static object ballistaShotEffect;

		private static AudioClip obliteratorThunder;

		private Harmony harmony;

		private int lastHeldKind = -1;

		private static bool loggedPlacementSound;

		private static bool loggedMissingThunder;

		private bool loggedHudHooks;

		internal static void LogBallistaPart(string message)
		{
			ArtificerPlugin instance = Instance;
			if (instance != null)
			{
				((BaseUnityPlugin)instance).Logger.LogInfo((object)message);
			}
		}

		private void Awake()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Expected O, but got Unknown
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Expected O, but got Unknown
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Expected O, but got Unknown
			Instance = this;
			PrefabManager.OnVanillaPrefabsAvailable += Register;
			harmony = new Harmony("com.crasssam.artificer");
			MethodInfo methodInfo = AccessTools.Method(typeof(Player), "GetTotalFoodValue", new Type[3]
			{
				typeof(float).MakeByRefType(),
				typeof(float).MakeByRefType(),
				typeof(float).MakeByRefType()
			}, (Type[])null);
			if (methodInfo != null)
			{
				harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(ArtificerPlugin), "FoodTotalPostfix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			else
			{
				((BaseUnityPlugin)this).Logger.LogError((object)"GetTotalFoodValue unavailable: armour maximum Eitr bonus cannot be applied");
			}
			MethodInfo methodInfo2 = AccessTools.Method(typeof(SEMan), "ModifyEitrRegen", (Type[])null, (Type[])null);
			if (methodInfo2 != null)
			{
				harmony.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(ArtificerPlugin), "EitrRegenPostfix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			else
			{
				((BaseUnityPlugin)this).Logger.LogError((object)"ModifyEitrRegen unavailable: armour set regeneration cannot be applied");
			}
			MethodInfo methodInfo3 = AccessTools.Method(typeof(ItemData), "GetWeaponLoadingTime", (Type[])null, (Type[])null);
			if (methodInfo3 != null)
			{
				harmony.Patch((MethodBase)methodInfo3, (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(ArtificerPlugin), "WeaponLoadTimePostfix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			else
			{
				((BaseUnityPlugin)this).Logger.LogError((object)"GetWeaponLoadingTime unavailable: crossbow reload bonuses cannot be applied");
			}
		}

		private void OnDestroy()
		{
			PrefabManager.OnVanillaPrefabsAvailable -= Register;
			Harmony obj = harmony;
			if (obj != null)
			{
				obj.UnpatchSelf();
			}
			Instance = null;
		}

		private static GameObject First(params string[] names)
		{
			foreach (string text in names)
			{
				GameObject prefab = PrefabManager.Instance.GetPrefab(text);
				if ((Object)(object)prefab != (Object)null)
				{
					return prefab;
				}
			}
			return null;
		}

		private void Register()
		{
			//IL_068c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0693: Expected O, but got Unknown
			PrefabManager.OnVanillaPrefabsAvailable -= Register;
			for (int i = 0; i < 5; i++)
			{
				GameObject val = First(Visuals[i]);
				if ((Object)(object)val == (Object)null)
				{
					((BaseUnityPlugin)this).Logger.LogError((object)("Missing visual prefab for " + Kinds[i] + ": " + string.Join(", ", Visuals[i])));
					continue;
				}
				if (i == 0)
				{
					foreach (Renderer item in val.GetComponentsInChildren<Renderer>(true).Take(28))
					{
						MeshFilter component = ((Component)item).GetComponent<MeshFilter>();
						SkinnedMeshRenderer val2 = (SkinnedMeshRenderer)(object)((item is SkinnedMeshRenderer) ? item : null);
						ManualLogSource logger = ((BaseUnityPlugin)this).Logger;
						string[] obj = new string[8]
						{
							"Trap visual: ",
							((Object)((Component)item).transform).name,
							" mesh=",
							null,
							null,
							null,
							null,
							null
						};
						object obj2;
						if (!((Object)(object)val2 != (Object)null))
						{
							if (component == null)
							{
								obj2 = null;
							}
							else
							{
								Mesh sharedMesh = component.sharedMesh;
								obj2 = ((sharedMesh != null) ? ((Object)sharedMesh).name : null);
							}
						}
						else
						{
							Mesh sharedMesh2 = val2.sharedMesh;
							obj2 = ((sharedMesh2 != null) ? ((Object)sharedMesh2).name : null);
						}
						obj[3] = (string)obj2;
						obj[4] = " active=";
						obj[5] = ((Component)item).gameObject.activeInHierarchy.ToString();
						obj[6] = " enabled=";
						obj[7] = item.enabled.ToString();
						logger.LogInfo((object)string.Concat(obj));
					}
					Animator[] componentsInChildren = val.GetComponentsInChildren<Animator>(true);
					foreach (Animator val3 in componentsInChildren)
					{
						((BaseUnityPlugin)this).Logger.LogInfo((object)("Trap animator " + ((Object)val3).name + " parameters=" + string.Join(",", val3.parameters.Select((AnimatorControllerParameter p) => p.name).ToArray())));
					}
				}
				if (i == 1)
				{
					Animator[] componentsInChildren = val.GetComponentsInChildren<Animator>(true);
					foreach (Animator val4 in componentsInChildren)
					{
						((BaseUnityPlugin)this).Logger.LogInfo((object)("Twig animator " + ((Object)val4).name + " controller=" + (((Object)(object)val4.runtimeAnimatorController != (Object)null) ? ((Object)val4.runtimeAnimatorController).name : "none") + " parameters=" + string.Join(",", val4.parameters.Select((AnimatorControllerParameter p) => p.name).ToArray()) + " clips=" + (((Object)(object)val4.runtimeAnimatorController != (Object)null) ? string.Join(",", val4.runtimeAnimatorController.animationClips.Select((AnimationClip c) => ((Object)c).name).ToArray()) : "none")));
					}
				}
				WearNTear componentInChildren = val.GetComponentInChildren<WearNTear>(true);
				destructionEffects[i] = ((!((Object)(object)componentInChildren != (Object)null)) ? null : AccessTools.Field(((object)componentInChildren).GetType(), "m_destroyedEffect")?.GetValue(componentInChildren));
				Piece component2 = val.GetComponent<Piece>();
				placementEffects[i] = ((!((Object)(object)component2 != (Object)null)) ? null : AccessTools.Field(((object)component2).GetType(), "m_placeEffect")?.GetValue(component2));
				if (i == 4)
				{
					MonoBehaviour incinerator = ((IEnumerable<MonoBehaviour>)val.GetComponentsInChildren<MonoBehaviour>(true)).FirstOrDefault((Func<MonoBehaviour, bool>)((MonoBehaviour val12) => (Object)(object)val12 != (Object)null && ((object)val12).GetType().Name == "Incinerator"));
					if ((Object)(object)incinerator != (Object)null)
					{
						FieldInfo[] array = (from f in ((object)incinerator).GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
							where f.FieldType.Name == "EffectList"
							orderby ((f.Name.IndexOf("incinerat", StringComparison.OrdinalIgnoreCase) >= 0) ? 8 : 0) + ((f.Name.IndexOf("lightning", StringComparison.OrdinalIgnoreCase) >= 0) ? 8 : 0) + ((f.Name.IndexOf("effect", StringComparison.OrdinalIgnoreCase) >= 0) ? 1 : 0) descending
							select f).ToArray();
						FieldInfo[] array2 = array;
						foreach (FieldInfo fieldInfo in array2)
						{
							((BaseUnityPlugin)this).Logger.LogInfo((object)("Obliterator source effect " + fieldInfo.Name + " present=" + (fieldInfo.GetValue(incinerator) != null)));
						}
						FieldInfo fieldInfo2 = array.FirstOrDefault((FieldInfo f) => f.GetValue(incinerator) != null);
						if (fieldInfo2 != null)
						{
							destructionEffects[i] = fieldInfo2.GetValue(incinerator);
						}
						((BaseUnityPlugin)this).Logger.LogInfo((object)("Obliterator chosen effect=" + (fieldInfo2?.Name ?? "WearNTear fallback")));
					}
				}
				if (i == 4)
				{
					List<AudioClip> list = (from a in val.GetComponentsInChildren<AudioSource>(true)
						where (Object)(object)a.clip != (Object)null
						select a.clip into c
						where ((Object)c).name.IndexOf("thunder", StringComparison.OrdinalIgnoreCase) >= 0
						select c).ToList();
					string[] array3 = new string[3] { "sfx_thunder", "sfx_incinerator", "sfx_lightning" };
					foreach (string text in array3)
					{
						GameObject prefab = PrefabManager.Instance.GetPrefab(text);
						if (!((Object)(object)prefab == (Object)null))
						{
							list.AddRange(from a in prefab.GetComponentsInChildren<AudioSource>(true)
								where (Object)(object)a.clip != (Object)null && ((Object)a.clip).name.IndexOf("thunder", StringComparison.OrdinalIgnoreCase) >= 0
								select a.clip);
						}
					}
					obliteratorThunder = list.OrderByDescending((AudioClip c) => c.length).FirstOrDefault();
					((BaseUnityPlugin)this).Logger.LogInfo((object)("Obliterator sound clip=" + (((Object)(object)obliteratorThunder != (Object)null) ? ((Object)obliteratorThunder).name : "generated thunder fallback")));
				}
				GameObject val5 = new GameObject("ArtificerSummon" + Kinds[i]);
				val5.SetActive(false);
				Dictionary<Transform, Transform> dictionary = new Dictionary<Transform, Transform>();
				CopyVisuals(val.transform, val5.transform, dictionary, i == 1);
				FixSkinnedMeshes(val.transform, dictionary);
				if (i == 1)
				{
					SkinnedMeshRenderer[] componentsInChildren2 = val5.GetComponentsInChildren<SkinnedMeshRenderer>(true);
					foreach (SkinnedMeshRenderer val6 in componentsInChildren2)
					{
						ManualLogSource logger2 = ((BaseUnityPlugin)this).Logger;
						string[] obj3 = new string[8]
						{
							"Twig skin ",
							((Object)val6).name,
							" mesh=",
							null,
							null,
							null,
							null,
							null
						};
						Mesh sharedMesh3 = val6.sharedMesh;
						obj3[3] = ((sharedMesh3 != null) ? ((Object)sharedMesh3).name : null);
						obj3[4] = " bones=";
						Transform[] bones = val6.bones;
						obj3[5] = ((bones != null) ? bones.Length : 0).ToString();
						obj3[6] = " unmapped=";
						obj3[7] = (val6.bones?.Count((Transform b) => (Object)(object)b == (Object)null) ?? 0).ToString();
						logger2.LogInfo((object)string.Concat(obj3));
					}
				}
				if (i == 0)
				{
					HideOverlappingTrapMeshes(val5);
				}
				if (i == 2)
				{
					MonoBehaviour turret = ((IEnumerable<MonoBehaviour>)val.GetComponentsInChildren<MonoBehaviour>(true)).FirstOrDefault((Func<MonoBehaviour, bool>)((MonoBehaviour val12) => (Object)(object)val12 != (Object)null && ((object)val12).GetType().Name == "Turret"));
					if ((Object)(object)turret != (Object)null)
					{
						FieldInfo fieldInfo3 = new string[3] { "m_shootEffect", "m_shotEffect", "m_fireEffect" }.Select((string name) => AccessTools.Field(((object)turret).GetType(), name)).FirstOrDefault((FieldInfo field) => field != null);
						ballistaShotEffect = fieldInfo3?.GetValue(turret);
						((BaseUnityPlugin)this).Logger.LogInfo((object)("Ballista shot effect=" + (fieldInfo3?.Name ?? "missing")));
					}
					object obj4 = ((!((Object)(object)turret != (Object)null)) ? null : AccessTools.Field(((object)turret).GetType(), "m_turretBody")?.GetValue(turret));
					object obj5 = ((obj4 is Transform) ? obj4 : null);
					if (obj5 == null)
					{
						object obj6 = ((obj4 is GameObject) ? obj4 : null);
						obj5 = ((obj6 != null) ? ((GameObject)obj6).transform : null);
					}
					Transform val7 = (Transform)obj5;
					if ((Object)(object)val7 != (Object)null && dictionary.TryGetValue(val7, out var value))
					{
						((Object)value).name = "ArtificerTurretHead";
						MeshRenderer[] componentsInChildren3 = val5.GetComponentsInChildren<MeshRenderer>(true);
						foreach (MeshRenderer val8 in componentsInChildren3)
						{
							if (!((Object)(object)((Component)val8).transform == (Object)(object)value) && !((Component)val8).transform.IsChildOf(value))
							{
								MeshFilter component3 = ((Component)val8).GetComponent<MeshFilter>();
								Mesh val9 = ((component3 != null) ? component3.sharedMesh : null);
								string text2 = (((Object)val8).name + " " + (((Object)(object)val9 != (Object)null) ? ((Object)val9).name : "")).ToLowerInvariant();
								if (text2.Contains("ring") || text2.Contains("circle") || text2.Contains("bearing"))
								{
									((Component)val8).transform.SetParent(value, true);
									((BaseUnityPlugin)this).Logger.LogInfo((object)("Ballista bearing follows turret: " + ((Object)val8).name));
								}
							}
						}
					}
				}
				if (i == 2)
				{
					List<Renderer> list2 = new List<Renderer>();
					List<Renderer> list3 = new List<Renderer>();
					Dictionary<Renderer, string> boltLabels = new Dictionary<Renderer, string>();
					Renderer[] componentsInChildren4 = val5.GetComponentsInChildren<Renderer>(true);
					foreach (Renderer val10 in componentsInChildren4)
					{
						MeshFilter component4 = ((Component)val10).GetComponent<MeshFilter>();
						object obj8;
						if (!((Object)(object)component4 != (Object)null) || !((Object)(object)component4.sharedMesh != (Object)null))
						{
							Renderer obj7 = ((val10 is SkinnedMeshRenderer) ? val10 : null);
							if (obj7 == null)
							{
								obj8 = null;
							}
							else
							{
								Mesh sharedMesh4 = ((SkinnedMeshRenderer)obj7).sharedMesh;
								obj8 = ((sharedMesh4 != null) ? ((Object)sharedMesh4).name : null);
							}
							if (obj8 == null)
							{
								obj8 = "";
							}
						}
						else
						{
							obj8 = ((Object)component4.sharedMesh).name;
						}
						string text3 = (string)obj8;
						string text4 = (((Object)val10).name + " " + text3).ToLowerInvariant();
						Transform parent = ((Component)val10).transform.parent;
						while ((Object)(object)parent != (Object)null && (Object)(object)parent != (Object)(object)val5.transform)
						{
							text4 = text4 + " " + ((Object)parent).name.ToLowerInvariant();
							parent = parent.parent;
						}
						string text5 = string.Join(" ", (from m in val10.sharedMaterials
							where (Object)(object)m != (Object)null
							select ((Object)m).name).ToArray()).ToLowerInvariant();
						if (text4.Contains("missile") || text4.Contains("projectile") || text4.Contains("bolt") || text4.Contains("arrow") || text4.Contains("ammo"))
						{
							list2.Add(val10);
							boltLabels[val10] = text4 + " " + text5;
							if ((text4 + " " + text5).Contains("blackmetal") || (text4 + " " + text5).Contains("black_metal"))
							{
								list3.Add(val10);
							}
							((BaseUnityPlugin)this).Logger.LogInfo((object)("Ballista projectile " + ((Object)val10).name + " mesh=" + text3 + " materials=" + text5));
						}
					}
					if (list3.Count == 0)
					{
						Renderer[] array4 = list2.Where((Renderer r) => !boltLabels[r].Contains("wood") && !boltLabels[r].Contains("flametal") && !boltLabels[r].Contains("fire")).ToArray();
						if (array4.Length != 0)
						{
							list3.Add(array4[0]);
						}
					}
					foreach (Renderer item2 in list2)
					{
						item2.enabled = list3.Contains(item2);
					}
					((BaseUnityPlugin)this).Logger.LogInfo((object)("Ballista projectiles=" + list2.Count + " visible black metal renderers=" + list3.Count));
				}
				if (i == 3)
				{
					MeshFilter[] componentsInChildren5 = val5.GetComponentsInChildren<MeshFilter>(true);
					foreach (MeshFilter val11 in componentsInChildren5)
					{
						if ((Object)(object)val11.sharedMesh != (Object)null && ((Object)val11.sharedMesh).name.IndexOf("sphere", StringComparison.OrdinalIgnoreCase) >= 0)
						{
							MeshRenderer component5 = ((Component)val11).GetComponent<MeshRenderer>();
							if ((Object)(object)component5 != (Object)null)
							{
								((Renderer)component5).enabled = false;
							}
						}
					}
				}
				val5.AddComponent<ZNetView>();
				val5.AddComponent<ArtificerSummon>().Kind = i;
				PrefabManager.Instance.AddPrefab(val5);
				summons[i] = val5;
				AddPack(i, val);
			}
			for (int num = 0; num < 4; num++)
			{
				AddArmorTier(num);
			}
			AddArtificerCrossbow();
			((BaseUnityPlugin)this).Logger.LogInfo((object)("Registered " + summons.Count + " contraption prefabs, four armour tiers and an Artificer crossbow"));
		}

		private static void CopyVisuals(Transform from, Transform to, Dictionary<Transform, Transform> map, bool includeInactive)
		{
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Expected O, but got Unknown
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			map[from] = to;
			Animator component = ((Component)from).GetComponent<Animator>();
			if ((Object)(object)component != (Object)null)
			{
				Animator obj = ((Component)to).gameObject.AddComponent<Animator>();
				obj.avatar = component.avatar;
				obj.runtimeAnimatorController = component.runtimeAnimatorController;
				obj.applyRootMotion = false;
				obj.cullingMode = (AnimatorCullingMode)0;
			}
			MeshFilter component2 = ((Component)from).GetComponent<MeshFilter>();
			MeshRenderer component3 = ((Component)from).GetComponent<MeshRenderer>();
			if ((Object)(object)component2 != (Object)null && (Object)(object)component3 != (Object)null)
			{
				((Component)to).gameObject.AddComponent<MeshFilter>().sharedMesh = component2.sharedMesh;
				MeshRenderer obj2 = ((Component)to).gameObject.AddComponent<MeshRenderer>();
				((Renderer)obj2).sharedMaterials = ((Renderer)component3).sharedMaterials;
				((Renderer)obj2).enabled = ((Renderer)component3).enabled;
			}
			SkinnedMeshRenderer component4 = ((Component)from).GetComponent<SkinnedMeshRenderer>();
			if ((Object)(object)component4 != (Object)null)
			{
				SkinnedMeshRenderer obj3 = ((Component)to).gameObject.AddComponent<SkinnedMeshRenderer>();
				obj3.sharedMesh = component4.sharedMesh;
				((Renderer)obj3).sharedMaterials = ((Renderer)component4).sharedMaterials;
				((Renderer)obj3).enabled = ((Renderer)component4).enabled;
			}
			bool flag = false;
			bool flag2 = false;
			if (includeInactive)
			{
				for (int i = 0; i < from.childCount; i++)
				{
					Transform child = from.GetChild(i);
					if (((Component)child).gameObject.activeSelf && ((Component)child).GetComponentsInChildren<SkinnedMeshRenderer>(false).Any((SkinnedMeshRenderer r) => ((Renderer)r).enabled))
					{
						flag2 = true;
					}
				}
			}
			for (int num = 0; num < from.childCount; num++)
			{
				Transform child2 = from.GetChild(num);
				if (!((Component)child2).gameObject.activeSelf && !includeInactive)
				{
					continue;
				}
				if (!((Component)child2).gameObject.activeSelf && includeInactive)
				{
					bool flag3 = ((Component)child2).GetComponentsInChildren<SkinnedMeshRenderer>(true).Length != 0 || ((Component)child2).GetComponentsInChildren<MeshRenderer>(true).Length > 1;
					if (flag3 && (flag || flag2))
					{
						continue;
					}
					if (flag3)
					{
						flag = true;
					}
				}
				GameObject val = new GameObject(((Object)child2).name);
				val.transform.SetParent(to, false);
				val.transform.localPosition = child2.localPosition;
				val.transform.localRotation = child2.localRotation;
				val.transform.localScale = child2.localScale;
				CopyVisuals(child2, val.transform, map, includeInactive);
			}
		}

		private static void FixSkinnedMeshes(Transform source, Dictionary<Transform, Transform> map)
		{
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			SkinnedMeshRenderer[] componentsInChildren = ((Component)source).GetComponentsInChildren<SkinnedMeshRenderer>(true);
			foreach (SkinnedMeshRenderer val in componentsInChildren)
			{
				if (!map.TryGetValue(((Component)val).transform, out var value))
				{
					continue;
				}
				SkinnedMeshRenderer component = ((Component)value).GetComponent<SkinnedMeshRenderer>();
				if (!((Object)(object)component == (Object)null))
				{
					component.bones = val.bones.Select((Transform b) => (!((Object)(object)b != (Object)null) || !map.TryGetValue(b, out var value3)) ? null : value3).ToArray();
					if ((Object)(object)val.rootBone != (Object)null && map.TryGetValue(val.rootBone, out var value2))
					{
						component.rootBone = value2;
					}
					((Renderer)component).localBounds = ((Renderer)val).localBounds;
					component.updateWhenOffscreen = true;
				}
			}
		}

		private static void HideOverlappingTrapMeshes(GameObject model)
		{
			HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
			MeshRenderer[] componentsInChildren = model.GetComponentsInChildren<MeshRenderer>(true);
			foreach (MeshRenderer val in componentsInChildren)
			{
				MeshFilter component = ((Component)val).GetComponent<MeshFilter>();
				if (!((Object)(object)component == (Object)null) && !((Object)(object)component.sharedMesh == (Object)null))
				{
					string name = ((Object)component.sharedMesh).name;
					((Renderer)val).enabled = !name.EndsWith("_LOD", StringComparison.OrdinalIgnoreCase) && hashSet.Add(name);
				}
			}
		}

		internal static AudioClip GetObliteratorSound()
		{
			return GetPlacementSound();
		}

		internal static AudioClip GetPlacementSound()
		{
			AudioClip val = ((IEnumerable<AudioClip>)Resources.FindObjectsOfTypeAll<AudioClip>()).FirstOrDefault((Func<AudioClip, bool>)((AudioClip c) => (Object)(object)c != (Object)null && ((Object)c).name == "Amb_ThunderClap_S_05"));
			if ((Object)(object)val != (Object)null && !loggedPlacementSound)
			{
				loggedPlacementSound = true;
				ArtificerPlugin instance = Instance;
				if (instance != null)
				{
					((BaseUnityPlugin)instance).Logger.LogInfo((object)("Artificer placement thunder: " + ((Object)val).name + " (" + val.length + "s)"));
				}
			}
			return val;
		}

		internal static void PlayBallistaShot(Vector3 position, Quaternion rotation)
		{
			//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)
			if (ballistaShotEffect != null)
			{
				PlayEffect(ballistaShotEffect, position, rotation, "ballista shot");
			}
		}

		internal static void PlayBuildingDestroyed(int kind, Vector3 position, Quaternion rotation)
		{
			//IL_001f: 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)
			if (kind >= 0 && kind < destructionEffects.Length && destructionEffects[kind] != null)
			{
				PlayEffect(destructionEffects[kind], position, rotation, "destruction");
			}
		}

		internal static void PlayBuildingDismantled(int kind, Vector3 position, Quaternion rotation)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: 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)
			if (kind != 4)
			{
				PlayBuildingDestroyed(kind, position, rotation);
			}
			if (kind != 0 && destructionEffects[0] != null)
			{
				PlayEffect(destructionEffects[0], position, rotation, "dismantle sound");
			}
		}

		private static void PlayBuildingPlaced(int kind, Player player, Vector3 position, Quaternion rotation)
		{
			//IL_0047: 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)
			object obj = ((kind >= 0 && kind < placementEffects.Length) ? placementEffects[kind] : null);
			if (obj == null && (Object)(object)player != (Object)null)
			{
				obj = AccessTools.Field(((object)player).GetType(), "m_placeEffect")?.GetValue(player);
			}
			if (obj != null)
			{
				PlayEffect(obj, position, rotation, "placement");
			}
		}

		private static void PlayEffect(object effect, Vector3 position, Quaternion rotation, string label)
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				MethodInfo methodInfo = effect.GetType().GetMethods().FirstOrDefault((MethodInfo m) => m.Name == "Create" && m.GetParameters().Length >= 2 && m.GetParameters()[0].ParameterType == typeof(Vector3) && m.GetParameters()[1].ParameterType == typeof(Quaternion));
				if (!(methodInfo == null))
				{
					ParameterInfo[] parameters = methodInfo.GetParameters();
					object[] array = new object[parameters.Length];
					array[0] = position;
					array[1] = rotation;
					for (int num = 2; num < array.Length; num++)
					{
						array[num] = (parameters[num].HasDefaultValue ? parameters[num].DefaultValue : (parameters[num].ParameterType.IsValueType ? Activator.CreateInstance(parameters[num].ParameterType) : null));
					}
					methodInfo.Invoke(effect, array);
				}
			}
			catch (Exception ex)
			{
				ArtificerPlugin instance = Instance;
				if (instance != null)
				{
					((BaseUnityPlugin)instance).Logger.LogWarning((object)("Building " + label + " effect failed: " + ex.Message));
				}
			}
		}

		private static ItemConfig Recipe(string name, string description, string[] resources, int[] amounts)
		{
			//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_000c: 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_001f: Expected O, but got Unknown
			ItemConfig val = new ItemConfig
			{
				Name = name,
				Description = description,
				CraftingStation = "piece_artisanstation"
			};
			for (int i = 0; i < resources.Length; i++)
			{
				val.AddRequirement(resources[i], amounts[i], 0);
			}
			return val;
		}

		private void AddPack(int i, GameObject visual)
		{
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Expected O, but got Unknown
			//IL_026c: Unknown result type (might be due to invalid IL or missing references)
			string[][] array = new string[5][]
			{
				new string[3] { "BlackMetal", "Iron", "Wood" },
				new string[4] { "BlackMetal", "FineWood", "BronzeNails", "LinenThread" },
				new string[3] { "BlackMetal", "YggdrasilWood", "MechanicalSpring" },
				new string[4] { "Iron", "Copper", "ShieldCore", "FlametalNew" },
				new string[4] { "Iron", "Copper", "Thunderstone", "Gold" }
			};
			int[][] array2 = new int[5][]
			{
				new int[3] { 10, 10, 20 },
				new int[4] { 10, 15, 20, 10 },
				new int[3] { 20, 20, 6 },
				new int[4] { 10, 10, 2, 10 },
				new int[4] { 16, 8, 2, 10 }
			};
			ItemConfig val = Recipe(Kinds[i] + " pack", "Reusable " + Kinds[i].ToLowerInvariant() + " deployment pack. Primary attack deploys a contraption. Costs " + Eitr[i] + " Eitr and up to " + Stamina[i] + " stamina.", array[i], array2[i]);
			Piece component = visual.GetComponent<Piece>();
			if ((Object)(object)component != (Object)null)
			{
				val.Icon = component.m_icon;
			}
			CustomItem val2 = new CustomItem(PackNames[i], "Hammer", val);
			ItemDrop itemDrop = val2.ItemDrop;
			itemDrop.m_itemData.m_shared.m_name = val.Name;
			itemDrop.m_itemData.m_shared.m_description = val.Description;
			itemDrop.m_itemData.m_shared.m_maxStackSize = 1;
			itemDrop.m_itemData.m_shared.m_durabilityPerLevel = 0f;
			itemDrop.m_itemData.m_shared.m_useDurability = false;
			itemDrop.m_itemData.m_shared.m_buildPieces = null;
			itemDrop.m_itemData.m_shared.m_itemType = (ItemType)3;
			itemDrop.m_itemData.m_shared.m_attack = null;
			itemDrop.m_itemData.m_shared.m_secondaryAttack = null;
			if ((Object)(object)component != (Object)null)
			{
				itemDrop.m_itemData.m_shared.m_icons = (Sprite[])(object)new Sprite[1] { component.m_icon };
			}
			ItemManager.Instance.AddItem(val2);
		}

		private void AddArtificerCrossbow()
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Expected O, but got Unknown
			ItemConfig val = Recipe("Artificer Crossbow", "Reusable Artificer crossbow. Fires ordinary bolts. 150 pierce damage before bolt damage.", new string[4] { "BlackMetal", "LinenThread", "FineWood", "Iron" }, new int[4] { 20, 15, 20, 10 });
			CustomItem val2 = new CustomItem("ArtificerCrossbow", "CrossbowArbalest", val);
			SharedData shared = val2.ItemDrop.m_itemData.m_shared;
			shared.m_name = val.Name;
			shared.m_description = val.Description;
			shared.m_damages.m_pierce = 150f;
			ItemManager.Instance.AddItem(val2);
		}

		private void AddArmorTier(int tier)
		{
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Expected O, but got Unknown
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fb: Expected O, but got Unknown
			string[][] array = new string[4][]
			{
				new string[3] { "BlackMetal", "LinenThread", "LoxPelt" },
				new string[3] { "Carapace", "Eitr", "ScaleHide" },
				new string[3] { "FlametalNew", "AskHide", "LinenThread" },
				new string[3] { "Gold", "FrostCore", "Carapace" }
			};
			string[] array2 = new string[4] { "HelmetHat3", "HelmetHat4", "HelmetCelebration", "HelmetAshlandsMediumHood" };
			string[] array3 = new string[4] { "ArmorLeatherLegs", "ArmorBronzeLegs", "ArmorMageLegs", "ArmorAshlandsMediumlegs" };
			string[] array4 = new string[3]
			{
				array2[tier],
				"ArmorHarvester1",
				array3[tier]
			};
			string[] gearSlots = GearSlots;
			StatusEffect val = ScriptableObject.CreateInstance<StatusEffect>();
			((Object)val).name = "ArtificerSetEffect" + tier;
			val.m_name = SetNames[tier];
			val.m_tooltip = "+50 maximum Eitr\n+50% Eitr regeneration\nUnlocks " + ((tier == 0) ? "trap and twig" : (Kinds[tier + 1].ToLowerInvariant() + " and earlier packs")) + "\n" + ((tier > 0) ? ("+" + 20 * tier + "% crossbow reload speed\n") : "");
			ItemManager.Instance.AddStatusEffect(new CustomStatusEffect(val, false));
			for (int i = 0; i < 3; i++)
			{
				ItemConfig val2 = Recipe(SetNames[tier] + " " + gearSlots[i], "Artificer armour. Wear all three matching pieces for the set effect.", array[tier], new int[3]
				{
					8 + tier * 4,
					8,
					6
				});
				CustomItem val3 = new CustomItem(GearNames[tier] + gearSlots[i], array4[i], val2);
				SharedData shared = val3.ItemDrop.m_itemData.m_shared;
				shared.m_name = val2.Name;
				shared.m_description = val2.Description;
				shared.m_setName = GearNames[tier];
				shared.m_setSize = 3;
				shared.m_setStatusEffect = val;
				shared.m_equipStatusEffect = null;
				if (i == 0 && shared.m_icons != null && shared.m_icons.Length != 0)
				{
					val.m_icon = shared.m_icons[0];
				}
				if (i != 2)
				{
					RecolorArmor(val3.ItemDrop, i switch
					{
						0 => tier == 1, 
						1 => true, 
						_ => false, 
					});
				}
				string[][] array5 = new string[4][]
				{
					new string[3] { "HelmetLox", "ArmorLoxChest", "ArmorLoxLegs" },
					new string[3] { "HelmetMage", "ArmorMageChest", "ArmorMageLegs" },
					new string[3] { "HelmetAshlandsMediumHood", "ArmorAshlandsMediumChest", "ArmorAshlandsMediumlegs" },
					new string[3] { "HelmetDNMediumHood", "ArmorDeepNorthMediumChest", "ArmorDeepNorthMediumlegs" }
				};
				GameObject prefab = PrefabManager.Instance.GetPrefab(array5[tier][i]);
				ItemDrop val4 = (((Object)(object)prefab != (Object)null) ? prefab.GetComponent<ItemDrop>() : null);
				if ((Object)(object)val4 != (Object)null)
				{
					shared.m_armor = ((tier == 1) ? 22f : val4.m_itemData.m_shared.m_armor);
					shared.m_armorPerLevel = val4.m_itemData.m_shared.m_armorPerLevel;
					((BaseUnityPlugin)this).Logger.LogInfo((object)(val2.Name + " armour=" + shared.m_armor + " per level=" + shared.m_armorPerLevel));
				}
				else
				{
					((BaseUnityPlugin)this).Logger.LogError((object)("Armour reference missing: " + array5[tier][i]));
				}
				ItemManager.Instance.AddItem(val3);
			}
		}

		private void RecolorArmor(ItemDrop drop, bool tunic)
		{
			if ((Object)(object)drop == (Object)null)
			{
				return;
			}
			SharedData shared = drop.m_itemData.m_shared;
			Dictionary<Material, Material> cache = new Dictionary<Material, Material>();
			Func<Material, Material> func = delegate(Material original)
			{
				//IL_001e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0024: Expected O, but got Unknown
				//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00af: Expected O, but got Unknown
				//IL_00c9: 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_017f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0184: Unknown result type (might be due to invalid IL or missing references)
				//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
				//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
				//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)original == (Object)null)
				{
					return (Material)null;
				}
				if (cache.TryGetValue(original, out var value))
				{
					return value;
				}
				value = new Material(original);
				((Object)value).name = "ArtificerOrange_" + ((Object)original).name;
				cache[original] = value;
				try
				{
					if (original.HasProperty("_MainTex"))
					{
						Texture texture = original.GetTexture("_MainTex");
						Texture2D val2 = (Texture2D)(object)((texture is Texture2D) ? texture : null);
						if ((Object)(object)val2 != (Object)null)
						{
							RenderTexture temporary = RenderTexture.GetTemporary(((Texture)val2).width, ((Texture)val2).height, 0);
							try
							{
								Graphics.Blit((Texture)(object)val2, temporary);
								RenderTexture active = RenderTexture.active;
								Texture2D val3;
								try
								{
									RenderTexture.active = temporary;
									val3 = new Texture2D(((Texture)val2).width, ((Texture)val2).height, (TextureFormat)4, false);
									val3.ReadPixels(new Rect(0f, 0f, (float)((Texture)val2).width, (float)((Texture)val2).height), 0, 0);
									val3.Apply();
								}
								finally
								{
									RenderTexture.active = active;
								}
								Color32[] pixels = val3.GetPixels32();
								float num3 = default(float);
								float num4 = default(float);
								float num5 = default(float);
								for (int i = 0; i < pixels.Length; i++)
								{
									Color.RGBToHSV(Color32.op_Implicit(pixels[i]), ref num3, ref num4, ref num5);
									bool flag = num3 > 0.18f && num3 < 0.49f && num4 > 0.16f;
									bool flag2 = num4 > 0.13f && num5 > 0.12f;
									if (tunic ? flag : flag2)
									{
										Color val4 = Color.HSVToRGB(0.075f, tunic ? Mathf.Max(0.5f, num4) : Mathf.Max(0.55f, num4), num5);
										val4.a = (float)(int)pixels[i].a / 255f;
										pixels[i] = Color32.op_Implicit(val4);
									}
								}
								val3.SetPixels32(pixels);
								val3.Apply();
								((Object)val3).name = "ArtificerOrange_" + ((Object)val2).name;
								value.SetTexture("_MainTex", (Texture)(object)val3);
							}
							finally
							{
								RenderTexture.ReleaseTemporary(temporary);
							}
						}
					}
				}
				catch (Exception ex)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not recolour " + ((Object)original).name + ": " + ex.Message));
				}
				return value;
			};
			if ((Object)(object)shared.m_armorMaterial != (Object)null)
			{
				shared.m_armorMaterial = func(shared.m_armorMaterial);
			}
			Renderer[] componentsInChildren = ((Component)drop).GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren)
			{
				Material[] sharedMaterials = val.sharedMaterials;
				for (int num2 = 0; num2 < sharedMaterials.Length; num2++)
				{
					sharedMaterials[num2] = func(sharedMaterials[num2]);
				}
				val.sharedMaterials = sharedMaterials;
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)("Recoloured " + ((Object)drop).name + " with " + cache.Count + " materials"));
		}

		internal static int EquippedTier(Player p)
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Invalid comparison between Unknown and I4
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Invalid comparison between Unknown and I4
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Invalid comparison between Unknown and I4
			if ((Object)(object)p == (Object)null)
			{
				return -1;
			}
			int num = 0;
			foreach (ItemData allItem in ((Humanoid)p).GetInventory().GetAllItems())
			{
				if (!allItem.m_equipped || allItem.m_shared == null)
				{
					continue;
				}
				int num2 = Array.IndexOf(GearNames, allItem.m_shared.m_setName);
				if (num2 >= 0)
				{
					int num3 = (((int)allItem.m_shared.m_itemType != 6) ? (((int)allItem.m_shared.m_itemType == 7) ? 1 : (((int)allItem.m_shared.m_itemType == 11) ? 2 : (-1))) : 0);
					if (num3 >= 0)
					{
						num |= 1 << num2 * 3 + num3;
					}
				}
			}
			for (int num4 = GearNames.Length - 1; num4 >= 0; num4--)
			{
				if (((num >> num4 * 3) & 7) == 7)
				{
					return num4;
				}
			}
			return -1;
		}

		private void Update()
		{
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsDead())
			{
				lastHeldKind = -1;
				return;
			}
			int num = EquippedKind(localPlayer);
			if (num != lastHeldKind)
			{
				lastHeldKind = num;
				if (num >= 0)
				{
					((Character)localPlayer).Message((MessageType)2, (EquippedTier(localPlayer) >= RequiredTier[num]) ? (Kinds[num] + " pack ready: attack to deploy") : ("Requires the complete " + SetNames[RequiredTier[num]] + " armour set"), 0, (Sprite)null, false);
				}
			}
			if (InventoryGui.IsVisible() || ((Object)(object)EventSystem.current != (Object)null && EventSystem.current.IsPointerOverGameObject()))
			{
				return;
			}
			MethodInfo methodInfo = AccessTools.Method(((object)localPlayer).GetType(), "TakeInput", Type.EmptyTypes, (Type[])null);
			if ((methodInfo != null && methodInfo.ReturnType == typeof(bool) && !(bool)methodInfo.Invoke(localPlayer, null)) || (!Input.GetMouseButtonDown(0) && (ZInput.instance == null || !ZInput.GetButtonDown("Attack"))))
			{
				return;
			}
			int num2 = num;
			if (num2 < 0 || !summons.ContainsKey(num2))
			{
				return;
			}
			int num3 = EquippedTier(localPlayer);
			if (num3 < RequiredTier[num2])
			{
				((Character)localPlayer).Message((MessageType)2, "Requires the complete " + SetNames[RequiredTier[num2]] + " armour set", 0, (Sprite)null, false);
				return;
			}
			bool flag = localPlayer.GetStamina() < Stamina[num2];
			bool flag2 = localPlayer.GetEitr() < Eitr[num2];
			if (flag || flag2)
			{
				if (flag)
				{
					FlashResourceBar(eitr: false);
				}
				if (flag2)
				{
					FlashResourceBar(eitr: true);
				}
			}
			else
			{
				Camera main = Camera.main;
				if ((Object)(object)main == (Object)null || !TryPlacementHit(localPlayer, main, out var result))
				{
					((Character)localPlayer).Message((MessageType)2, "Aim at terrain or a building within 5 m", 0, (Sprite)null, false);
				}
				else if (Vector3.Distance(((Component)localPlayer).transform.position, ((RaycastHit)(ref result)).point) > 5f)
				{
					((Character)localPlayer).Message((MessageType)2, "Aim closer to deploy", 0, (Sprite)null, false);
				}
				else
				{
					Deploy(localPlayer, num2, num3, ((RaycastHit)(ref result)).point);
				}
			}
		}

		private static bool TryPlacementHit(Player p, Camera cam, out RaycastHit result)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: 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_00c4: 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)
			result = default(RaycastHit);
			foreach (RaycastHit item in from h in Physics.RaycastAll(((Component)cam).transform.position, ((Component)cam).transform.forward, 25f, -1, (QueryTriggerInteraction)1)
				orderby ((RaycastHit)(ref h)).distance
				select h)
			{
				RaycastHit current = item;
				if (!((Object)(object)((RaycastHit)(ref current)).collider == (Object)null) && !((Object)(object)((Component)((RaycastHit)(ref current)).collider).GetComponentInParent<Player>() == (Object)(object)p))
				{
					if ((Object)(object)((Component)((RaycastHit)(ref current)).collider).GetComponentInParent<ArtificerSummon>() != (Object)null)
					{
						return false;
					}
					if ((Object)(object)((Component)((RaycastHit)(ref current)).collider).GetComponentInParent<Heightmap>() == (Object)null && (Object)(object)((Component)((RaycastHit)(ref current)).collider).GetComponentInParent<Piece>() == (Object)null)
					{
						return false;
					}
					result = current;
					return true;
				}
			}
			return false;
		}

		private static int EquippedKind(Player p)
		{
			object obj = AccessTools.Field(typeof(Humanoid), "m_visEquipment")?.GetValue(p);
			string text = ((obj != null) ? (AccessTools.Field(obj.GetType(), "m_rightItem")?.GetValue(obj) as string) : null);
			for (int i = 0; i < PackNames.Length; i++)
			{
				if (text == PackNames[i])
				{
					return i;
				}
			}
			object? obj2 = AccessTools.Field(typeof(Humanoid), "m_rightItem")?.GetValue(p);
			ItemData val = (ItemData)((obj2 is ItemData) ? obj2 : null);
			if ((Object)(object)val?.m_dropPrefab != (Object)null)
			{
				for (int j = 0; j < PackNames.Length; j++)
				{
					if (((Object)val.m_dropPrefab).name == PackNames[j])
					{
						return j;
					}
				}
			}
			foreach (ItemData item in from x in ((Humanoid)p).GetInventory().GetAllItems()
				where x.m_equipped && (Object)(object)x.m_dropPrefab != (Object)null
				select x)
			{
				for (int num = 0; num < PackNames.Length; num++)
				{
					if (((Object)item.m_dropPrefab).name == PackNames[num])
					{
						return num;
					}
				}
			}
			return -1;
		}

		private void FlashResourceBar(bool eitr)
		{
			Hud instance = Hud.instance;
			if ((Object)(object)instance == (Object)null)
			{
				return;
			}
			MethodInfo[] source = (from m in typeof(Hud).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
				where m.GetParameters().Length == 0 && (m.Name.IndexOf("flash", StringComparison.OrdinalIgnoreCase) >= 0 || m.Name.IndexOf("blink", StringComparison.OrdinalIgnoreCase) >= 0)
				select m).ToArray();
			if (!loggedHudHooks)
			{
				loggedHudHooks = true;
				((BaseUnityPlugin)this).Logger.LogInfo((object)("HUD flash methods: " + string.Join(", ", source.Select((MethodInfo m) => m.Name).ToArray())));
				((BaseUnityPlugin)this).Logger.LogInfo((object)("HUD resource fields: " + string.Join(", ", (from f in typeof(Hud).GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
					where f.Name.IndexOf("eitr", StringComparison.OrdinalIgnoreCase) >= 0 || f.Name.IndexOf("stamina", StringComparison.OrdinalIgnoreCase) >= 0
					select f.Name + ":" + f.FieldType.Name).ToArray())));
				((BaseUnityPlugin)this).Logger.LogInfo((object)("HUD bar animations: " + string.Join(", ", (from a in ((Component)instance).GetComponentsInChildren<Animator>(true)
					where ((Object)a).name.IndexOf("eitr", StringComparison.OrdinalIgnoreCase) >= 0 || ((Object)a).name.IndexOf("stamina", StringComparison.OrdinalIgnoreCase) >= 0
					select ((Object)a).name + "(" + string.Join("/", a.parameters.Select((AnimatorControllerParameter p) => p.name).ToArray()) + ")").ToArray())));
			}
			string resource = (eitr ? "eitr" : "stamina");
			MethodInfo methodInfo = source.FirstOrDefault((MethodInfo m) => m.Name.IndexOf(resource, StringComparison.OrdinalIgnoreCase) >= 0 && m.Name.IndexOf("uppgrade", StringComparison.OrdinalIgnoreCase) < 0 && m.Name.IndexOf("upgrade", StringComparison.OrdinalIgnoreCase) < 0);
			if (methodInfo == null)
			{
				return;
			}
			try
			{
				methodInfo.Invoke(instance, null);
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Native resource flash failed: " + ex.Message));
			}
		}

		private void Deploy(Player p, int kind, int tier, Vector3 point)
		{
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: 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_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: 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)
			if (tier < RequiredTier[kind])
			{
				return;
			}
			float num = Eitr[kind];
			if (p.GetStamina() < Stamina[kind] || p.GetEitr() < num)
			{
				if (p.GetStamina() < Stamina[kind])
				{
					FlashResourceBar(eitr: false);
				}
				if (p.GetEitr() < num)
				{
					FlashResourceBar(eitr: true);
				}
				return;
			}
			if (kind == 3 && ArtificerSummon.HasShield(p.GetPlayerID()))
			{
				((Character)p).Message((MessageType)2, "Only one shield at a time", 0, (Sprite)null, false);
				return;
			}
			((Character)p).UseStamina(Stamina[kind]);
			((Character)p).UseEitr(num);
			GameObject val = Object.Instantiate<GameObject>(summons[kind], point, Quaternion.LookRotation(Vector3.ProjectOnPlane(((Component)p).transform.forward, Vector3.up)));
			val.SetActive(true);
			val.GetComponent<ArtificerSummon>().Initialize(p.GetPlayerID(), tier);
			if (kind != 4)
			{
				PlayBuildingPlaced(kind, p, point, val.transform.rotation);
			}
			else
			{
				object obj = AccessTools.Field(((object)p).GetType(), "m_placeEffect")?.GetValue(p) ?? placementEffects[0];
				if (obj != null)
				{
					PlayEffect(obj, point, val.transform.rotation, "build sound");
				}
				ArtificerLightning.PlacementThunder(point);
			}
			ZSyncAnimation component = ((Component)p).GetComponent<ZSyncAnimation>();
			MethodInfo methodInfo = (((Object)(object)component != (Object)null) ? AccessTools.Method(((object)component).GetType(), "SetTrigger", new Type[1] { typeof(string) }, (Type[])null) : null);
			if (methodInfo != null)
			{
				methodInfo.Invoke(component, new object[1] { "place" });
			}
			else
			{
				Animator componentInChildren = ((Component)p).GetComponentInChildren<Animator>();
				if ((Object)(object)componentInChildren != (Object)null && componentInChildren.parameters.Any((AnimatorControllerParameter x) => x.name == "place"))
				{
					componentInChildren.SetTrigger("place");
				}
			}
			if (kind == 4)
			{
				((Character)p).Message((MessageType)2, "Obliterator charging! Clear the marked area!", 0, (Sprite)null, false);
			}
		}

		private static void WeaponLoadTimePostfix(ItemData __instance, ref float __result)
		{
			Player localPlayer = Player.m_localPlayer;
			if (!((Object)(object)localPlayer == (Object)null) && __instance?.m_shared != null && __instance.m_shared.m_attack != null && __instance.m_shared.m_attack.m_requiresReload && !(((object)Unsafe.As<SkillType, SkillType>(ref __instance.m_shared.m_skillType)/*cast due to .constrained prefix*/).ToString() != "Crossbows"))
			{
				int num = EquippedTier(localPlayer);
				if (num > 0)
				{
					__result /= 1f + (float)num * 0.2f;
				}
			}
		}

		private static void FoodTotalPostfix(Player __instance, ref float __2)
		{
			if (EquippedTier(__instance) >= 0)
			{
				__2 += 50f;
			}
		}

		private static void EitrRegenPostfix(SEMan __instance, ref float __0)
		{
			object? obj = AccessTools.Field(typeof(SEMan), "m_character")?.GetValue(__instance);
			Player val = (Player)((obj is Player) ? obj : null);
			if ((Object)(object)val != (Object)null && EquippedTier(val) >= 0)
			{
				__0 += 0.5f;
			}
		}
	}
	internal sealed class ArtificerLightning : MonoBehaviour
	{
		private LineRenderer beam;

		private LineRenderer[] rings;

		private Light flash;

		private float elapsed;

		private const float Lifetime = 0.85f;

		private static AudioClip fallbackThunder;

		private static AudioClip lightningCrack;

		internal static void Strike(Vector3 impact, AudioClip vanillaSound)
		{
			//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_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Expected O, but got Unknown
			GameObject val = new GameObject("Artificer obliterator lightning");
			val.transform.position = impact;
			val.AddComponent<ArtificerLightning>().Begin(vanillaSound);
			Object.Destroy((Object)val, Mathf.Max(5f, ((Object)(object)vanillaSound != (Object)null) ? (vanillaSound.length + 0.3f) : 0f));
		}

		internal static void PlacementThunder(Vector3 position)
		{
			//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_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Expected O, but got Unknown
			GameObject val = new GameObject("Artificer obliterator placement thunder");
			val.transform.position = position;
			AudioSource obj = val.AddComponent<AudioSource>();
			obj.spatialBlend = 1f;
			obj.minDistance = 4f;
			obj.maxDistance = 65f;
			obj.volume = 0.11f;
			AudioClip val2 = ArtificerPlugin.GetPlacementSound() ?? MakeThunder();
			obj.PlayOneShot(val2);
			Object.Destroy((Object)val, Mathf.Max(5f, val2.length + 0.3f));
		}

		private void Begin(AudioClip sound)
		{
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Expected O, but got Unknown
			//IL_00a6: 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_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: 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)
			beam = ((Component)this).gameObject.AddComponent<LineRenderer>();
			beam.useWorldSpace = false;
			beam.positionCount = 21;
			beam.startWidth = 0.16f;
			beam.endWidth = 0.4f;
			beam.numCapVertices = 3;
			((Renderer)beam).material = new Material(Shader.Find("Particles/Additive") ?? Shader.Find("Sprites/Default") ?? Shader.Find("Standard"));
			beam.startColor = new Color(0.65f, 0.9f, 1f, 1f);
			beam.endColor = new Color(0.85f, 0.98f, 1f, 1f);
			rings = (LineRenderer[])(object)new LineRenderer[3];
			for (int i = 0; i < rings.Length; i++)
			{
				GameObject val = new GameObject("Blue strike ring");
				val.transform.SetParent(((Component)this).transform, false);
				LineRenderer val2 = val.AddComponent<LineRenderer>();
				val2.useWorldSpace = false;
				val2.positionCount = 65;
				((Renderer)val2).material = ((Renderer)beam).material;
				float startWidth = (val2.endWidth = 0.13f);
				val2.startWidth = startWidth;
				rings[i] = val2;
			}
			flash = ((Component)this).gameObject.AddComponent<Light>();
			flash.color = new Color(0.4f, 0.8f, 1f);
			flash.range = 16f;
			flash.intensity = 9f;
			AudioSource obj = ((Component)this).gameObject.AddComponent<AudioSource>();
			obj.spatialBlend = 1f;
			obj.minDistance = 4f;
			obj.maxDistance = 65f;
			obj.volume = 0.3f;
			obj.PlayOneShot(sound ?? MakeThunder());
			obj.PlayOneShot(MakeLightningCrack(), 0.27f);
			Redraw();
			RedrawRings();
		}

		private void Update()
		{
			elapsed += Time.deltaTime;
			if (!((Object)(object)beam == (Object)null))
			{
				((Renderer)beam).enabled = elapsed < 0.52f;
				if ((Object)(object)flash != (Object)null)
				{
					flash.intensity = 9f * Mathf.Clamp01(1f - elapsed / 0.6f);
				}
				if (((Renderer)beam).enabled)
				{
					Redraw();
				}
				RedrawRings();
			}
		}

		private void RedrawRings()
		{
			//IL_0093: 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_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			if (rings == null)
			{
				return;
			}
			Color val2 = default(Color);
			for (int i = 0; i < rings.Length; i++)
			{
				float num = Mathf.Clamp01((elapsed - (float)i * 0.09f) / 0.52f);
				LineRenderer val = rings[i];
				((Renderer)val).enabled = elapsed >= (float)i * 0.09f && num < 1f;
				if (((Renderer)val).enabled)
				{
					float num2 = 0.7f + 7.3f * num;
					((Color)(ref val2))..ctor(0.28f, 0.74f, 1f, 0.8f * (1f - num));
					Color startColor = (val.endColor = val2);
					val.startColor = startColor;
					for (int j = 0; j < val.positionCount; j++)
					{
						float num3 = (float)j * (float)Math.PI * 2f / (float)(val.positionCount - 1);
						val.SetPosition(j, new Vector3(Mathf.Cos(num3) * num2, -0.25f, Mathf.Sin(num3) * num2));
					}
				}
			}
		}

		private void Redraw()
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < beam.positionCount; i++)
			{
				float num = 55f * (float)i / (float)(beam.positionCount - 1);
				float num2 = ((i == 0 || i == beam.positionCount - 1) ? 0f : 0.42f);
				beam.SetPosition(i, new Vector3(Random.Range(0f - num2, num2), num, Random.Range(0f - num2, num2)));
			}
		}

		private static AudioClip MakeLightningCrack()
		{
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Expected O, but got Unknown
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Expected O, but got Unknown
			if ((Object)(object)lightningCrack != (Object)null)
			{
				return lightningCrack;
			}
			float[] samples = new float[5512];
			float num = 0f;
			for (int i = 0; i < samples.Length; i++)
			{
				float num2 = (float)i / 22050f;
				num = num * 0.65f + Random.Range(-1f, 1f) * 0.35f;
				samples[i] = num * Mathf.Exp((0f - num2) * 22f) * 0.65f;
			}
			int cursor = 0;
			PCMReaderCallback val = (PCMReaderCallback)delegate(float[] data)
			{
				int num3 = Mathf.Min(data.Length, samples.Length - cursor);
				if (num3 > 0)
				{
					Array.Copy(samples, cursor, data, 0, num3);
				}
				cursor += num3;
			};
			lightningCrack = AudioClip.Create("Artificer lightning crack", samples.Length, 1, 22050, false, val, (PCMSetPositionCallback)delegate(int position)
			{
				cursor = position;
			});
			return lightningCrack;
		}

		private static AudioClip MakeThunder()
		{
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Expected O, but got Unknown
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Expected O, but got Unknown
			if ((Object)(object)fallbackThunder != (Object)null)
			{
				return fallbackThunder;
			}
			float[] samples = new float[110250];
			float num = 0f;
			float num2 = 0f;
			for (int i = 0; i < samples.Length; i++)
			{
				float num3 = (float)i / 22050f;
				num = num * 0.92f + Random.Range(-1f, 1f) * 0.08f;
				num2 = num2 * 0.995f + num * 0.005f;
				float num4 = Mathf.Min(1f, num3 * 5f) * Mathf.Exp((0f - num3) * 0.43f);
				samples[i] = Mathf.Clamp((num * 0.45f + num2 * 3.6f) * num4, -1f, 1f);
			}
			int cursor = 0;
			PCMReaderCallback val = (PCMReaderCallback)delegate(float[] data)
			{
				int num5 = Mathf.Min(data.Length, samples.Length - cursor);
				if (num5 > 0)
				{
					Array.Copy(samples, cursor, data, 0, num5);
				}
				cursor += num5;
			};
			return fallbackThunder = AudioClip.Create("Artificer long thunder", samples.Length, 1, 22050, false, val, (PCMSetPositionCallback)delegate(int position)
			{
				cursor = position;
			});
		}
	}
	public sealed class ArtificerSummon : MonoBehaviour, Hoverable, Interactable
	{
		private sealed class BreakPart
		{
			internal Transform Part;

			internal Vector3 Position;

			internal Quaternion Rotation;

			internal Vector3 Scatter;
		}

		private static class ShieldMovement
		{
			internal static void Track(Character __instance)
			{
				//IL_002c: Unknown result type (might be due to invalid IL or missing references)
				//IL_001a: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)__instance == (Object)null)
				{
					return;
				}
				if (LastPositions.TryGetValue(__instance, out var value))
				{
					Contain(__instance, value);
				}
				LastPositions[__instance] = ((Component)__instance).transform.position;
				if (LastPositions.Count > 1024)
				{
					Character[] array = LastPositions.Keys.Where((Character k) => (Object)(object)k == (Object)null).ToArray();
					foreach (Character key in array)
					{
						LastPositions.Remove(key);
					}
				}
			}
		}

		private static class ShieldProjectiles
		{
			internal static void Track(Projectile __instance)
			{
				//IL_0029: Unknown result type (might be due to invalid IL or missing references)
				//IL_002e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0188: Unknown result type (might be due to invalid IL or missing references)
				//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
				//IL_00af: 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_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_00d3: 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_00d5: 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_00f1: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f3: 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_00f9: 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_011e: 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_012c: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)__instance == (Object)null)
				{
					return;
				}
				ZNetView component = ((Component)__instance).GetComponent<ZNetView>();
				if ((Object)(object)component != (Object)null && !component.IsOwner())
				{
					return;
				}
				Vector3 position = ((Component)__instance).transform.position;
				if (LastProjectiles.TryGetValue(__instance, out var value))
				{
					ArtificerSummon[] array = All.ToArray();
					foreach (ArtificerSummon artificerSummon in array)
					{
						if ((Object)(object)artificerSummon == (Object)null || artificerSummon.removing || artificerSummon.Kind != 3 || (Object)(object)artificerSummon.view == (Object)null || !artificerSummon.view.IsValid())
						{
							continue;
						}
						Vector3 position2 = ((Component)artificerSummon).transform.position;
						bool flag = Vector3.Distance(value, position2) < 7.25f;
						bool flag2 = Vector3.Distance(position, position2) < 7.25f;
						Vector3 val = position - value;
						float num = ((((Vector3)(ref val)).sqrMagnitude > 0.0001f) ? Mathf.Clamp01(Vector3.Dot(position2 - value, val) / ((Vector3)(ref val)).sqrMagnitude) : 0f);
						if (flag != flag2 || (!flag && !flag2 && Vector3.Distance(value + val * num, position2) < 7.25f))
						{
							LastProjectiles.Remove(__instance);
							if ((Object)(object)component != (Object)null && component.IsValid())
							{
								component.Destroy();
							}
							else
							{
								Object.Destroy((Object)(object)((Component)__instance).gameObject);
							}
							return;
						}
					}
				}
				LastProjectiles[__instance] = position;
				if (LastProjectiles.Count > 1024)
				{
					Projectile[] array2 = LastProjectiles.Keys.Where((Projectile k) => (Object)(object)k == (Object)null).ToArray();
					foreach (Projectile key in array2)
					{
						LastProjectiles.Remove(key);
					}
				}
			}
		}

		private const string OwnerKey = "artificer_owner";

		private const string TierKey = "artificer_tier";

		private const string RemainingKey = "artificer_remaining";

		private const string FiredKey = "artificer_fired";

		private const string TwigAttackKey = "artificer_twig_attack";

		private const string TwigFacingKey = "artificer_twig_facing";

		private const string RemovingKey = "artificer_removing";

		private const float ShieldRadius = 7.25f;

		private static readonly HashSet<ArtificerSummon> All = new HashSet<ArtificerSummon>();

		private static int lastShieldPollFrame = -1;

		internal int Kind;

		private ZNetView view;

		private float nextShot;

		private bool detonated;

		private bool removing;

		private float removalStarted;

		private bool obliteratorBreaking;

		private Vector3 originalScale;

		private LineRenderer boundary;

		private LineRenderer shotLine;

		private float jawClosedAt;

		private Light chargeLight;

		private float remaining = -1f;

		private float nextTimeSync;

		private Transform turretHead;

		private Transform reloadPart;

		private Vector3 reloadRest;

		private float lastReloadPitch;

		private float reloadStarted = -1f;

		private int observedReload = -1;

		private readonly List<Renderer> loadedBolts = new List<Renderer>();

		private readonly List<BreakPart> breakParts = new List<BreakPart>();

		private Transform twigBody;

		private Transform twigFacing;

		private Quaternion twigFacingOffset;

		private float desiredTwigHeading;

		private bool hasTwigHeading;

		private Quaternion twigRestRotation;

		private float twigAttackUntil;

		private int observedTwigAttack = -1;

		private float nextFacingSync;

		private Transform trapVisual;

		private Transform trapArm1;

		private Transform trapArm2;

		private Quaternion trapArm1Closed;

		private Quaternion trapArm2Closed;

		private Quaternion trapArm1Open;

		private Quaternion trapArm2Open;

		private Transform trapBase;

		private Vector3 trapArm1RestPosition;

		private Vector3 trapArm2RestPosition;

		private Vector3 trapBaseRestPosition;

		private float trapClosingStart = -1f;

		private static readonly Dictionary<Character, Vector3> LastPositions = new Dictionary<Character, Vector3>();

		private static readonly Dictionary<Projectile, Vector3> LastProjectiles = new Dictionary<Projectile, Vector3>();

		public string GetHoverName()
		{
			return "Artificer " + ArtificerPlugin.Kinds[Mathf.Clamp(Kind, 0, 4)];
		}

		public float GetHoverOffset()
		{
			return 0f;
		}

		public bool Interact(Humanoid user, bool hold, bool alt)
		{
			if (!(Kind == 4 || hold))
			{
				Player val = (Player)(object)((user is Player) ? user : null);
				if (val != null)
				{
					return Dismiss(val.GetPlayerID());
				}
			}
			return false;
		}

		public bool UseItem(Humanoid user, ItemData item)
		{
			return false;
		}

		public string GetHoverText()
		{
			float num = ((remaining < 0f && (Object)(object)view != (Object)null && view.IsValid()) ? view.GetZDO().GetFloat("artificer_remaining", 0f) : Mathf.Max(0f, remaining));
			return GetHoverName() + "\nExpires in " + Mathf.CeilToInt(num) + "s" + ((Kind == 4) ? "" : "\nPress E to dismantle");
		}

		private void Awake()
		{
			//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_00a1: 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_00d9: 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_025b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0262: Expected O, but got Unknown
			//IL_027c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0286: 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_0158: 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_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: 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_021d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < ArtificerPlugin.Kinds.Length; i++)
			{
				if (((Object)((Component)this).gameObject).name.StartsWith("ArtificerSummon" + ArtificerPlugin.Kinds[i], StringComparison.Ordinal))
				{
					Kind = i;
					break;
				}
			}
			view = ((Component)this).GetComponent<ZNetView>();
			originalScale = ((Component)this).transform.localScale;
			All.Add(this);
			BoxCollider obj = ((Component)this).gameObject.AddComponent<BoxCollider>();
			obj.size = ((Kind == 0) ? new Vector3(1.7f, 0.4f, 1.7f) : new Vector3(1.5f, 2f, 1.5f));
			obj.center = ((Kind == 0) ? new Vector3(0f, 0.2f, 0f) : new Vector3(0f, 1f, 0f));
			((Collider)obj).isTrigger = false;
			if (Kind == 0)
			{
				trapVisual = ((((Component)this).transform.childCount > 0) ? ((Component)this).transform.GetChild(0) : null);
				ArmTrapVisual();
			}
			if (Kind == 1)
			{
				PrepareTwig();
			}
			if (Kind == 2)
			{
				PrepareTurret();
			}
			if (Kind == 3)
			{
				foreach (Transform item in ((Component)this).transform)
				{
					item.localScale *= 0.5f;
				}
				float num = float.PositiveInfinity;
				MeshRenderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<MeshRenderer>(true);
				foreach (MeshRenderer val2 in componentsInChildren)
				{
					if (((Renderer)val2).enabled)
					{
						float num2 = num;
						Bounds bounds = ((Renderer)val2).bounds;
						num = Mathf.Min(num2, ((Bounds)(ref bounds)).min.y);
					}
				}
				if (!float.IsInfinity(num))
				{
					float num3 = ((Component)this).transform.position.y - num;
					foreach (Transform item2 in ((Component)this).transform)
					{
						item2.position += Vector3.up * num3;
					}
				}
				MakeShieldDome();
			}
			if (Kind == 4)
			{
				GameObject val4 = new GameObject("obliterator charge glow");
				val4.transform.SetParent(((Component)this).transform, false);
				val4.transform.localPosition = Vector3.up * 1.5f;
				chargeLight = val4.AddComponent<Light>();
				chargeLight.color = new Color(0.62f, 0.7f, 1f);
				chargeLight.range = 12f;
			}
			if (Kind == 4)
			{
				DrawBoundary(8f);
			}
		}

		private void OnDestroy()
		{
			All.Remove(this);
		}

		internal void Initialize(long owner, int tier)
		{
			if ((Object)(object)view == (Object)null)
			{
				view = ((Component)this).GetComponent<ZNetView>();
			}
			ZDO val = (((Object)(object)view != (Object)null) ? view.GetZDO() : null);
			if (val != null)
			{
				val.Set("artificer_owner", owner);
				val.Set("artificer_kind", Kind);
				val.Set("artificer_tier", tier);
				remaining = ArtificerPlugin.Seconds[Kind];
				val.Set("artificer_remaining", remaining);
			}
		}

		internal static bool HasShield(long owner)
		{
			return All.Any((ArtificerSummon s) => (Object)(object)s != (Object)null && !s.removing && s.Kind == 3 && (Object)(object)s.view != (Object)null && s.view.IsValid() && s.view.GetZDO().GetLong("artificer_owner", 0L) == owner);
		}

		internal bool Dismiss(long playerId)
		{
			if (Kind == 4 || removing || (Object)(object)view == (Object)null || !view.IsValid() || !view.IsOwner() || view.GetZDO().GetLong("artificer_owner", 0L) != playerId)
			{
				return false;
			}
			Remove();
			return true;
		}

		private static Player FindOwner(long id)
		{
			return ((IEnumerable<Player>)Player.GetAllPlayers()).FirstOrDefault((Func<Player, bool>)((Player p) => p.GetPlayerID() == id));
		}

		private void Update()
		{
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//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_00f6: 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_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: 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_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d6: 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_03e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0596: Unknown result type (might be due to invalid IL or missing references)
			//IL_059b: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_05d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_05d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_05dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_05f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_05f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_05fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0603: Unknown result type (might be due to invalid IL or missing references)
			//IL_0607: Unknown result type (might be due to invalid IL or missing references)
			//IL_06fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0734: Unknown result type (might be due to invalid IL or missing references)
			//IL_0727: Unknown result type (might be due to invalid IL or missing references)
			//IL_075a: Unknown result type (might be due to invalid IL or missing references)
			//IL_074d: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)view == (Object)null || !view.IsValid())
			{
				return;
			}
			ZDO zDO = view.GetZDO();
			if (!removing && zDO.GetBool("artificer_removing", false))
			{
				BeginRemoval();
			}
			if (removing)
			{
				if (Kind == 4 && !obliteratorBreaking)
				{
					if (Time.time - removalStarted < 0.65f)
					{
						return;
					}
					obliteratorBreaking = true;
					StartBreakingVisuals();
					EmitObliteratorBurst();
					removalStarted = Time.time;
				}
				float num = Mathf.Clamp01((Time.time - removalStarted) / 0.8f);
				foreach (BreakPart breakPart in breakParts)
				{
					if ((Object)(object)breakPart.Part != (Object)null)
					{
						breakPart.Part.position = breakPart.Position + breakPart.Scatter * num + Vector3.down * (1.5f * num * num);
						breakPart.Part.rotation = breakPart.Rotation * Quaternion.Euler(55f * num, 90f * num, -40f * num);
					}
				}
				if (num >= 1f)
				{
					if (view.IsOwner())
					{
						view.Destroy();
					}
					Object.Destroy((Object)(object)((Component)this).gameObject);
				}
				return;
			}
			float num2 = zDO.GetFloat("artificer_remaining", -1f);
			if (num2 < 0f)
			{
				return;
			}
			if (remaining < 0f || Mathf.Abs(remaining - num2) > 1.25f)
			{
				remaining = num2;
			}
			remaining = Mathf.Max(0f, remaining - Time.deltaTime);
			if (view.IsOwner() && (Time.time >= nextTimeSync || remaining <= 0f))
			{
				zDO.Set("artificer_remaining", remaining);
				nextTimeSync = Time.time + 0.25f;
			}
			if ((Object)(object)boundary != (Object)null)
			{
				((Renderer)boundary).enabled = true;
			}
			if (Kind == 1)
			{
				int num3 = zDO.GetInt("artificer_twig_attack", 0);
				if (observedTwigAttack >= 0 && num3 != observedTwigAttack && !view.IsOwner())
				{
					PlayTwigAttack();
				}
				observedTwigAttack = num3;
				if (!view.IsOwner())
				{
					TurnTwig(zDO.GetFloat("artificer_twig_facing", ((Component)this).transform.eulerAngles.y));
				}
			}
			if (Kind == 4 && (Object)(object)chargeLight != (Object)null)
			{
				float num4 = 1f - Mathf.Clamp01(remaining / (float)ArtificerPlugin.Seconds[4]);
				chargeLight.intensity = 0.5f + num4 * 3f + Mathf.PingPong(Time.time * (3f + num4 * 12f), 0.7f);
				if ((Object)(object)boundary != (Object)null)
				{
					LineRenderer obj = boundary;
					float startWidth = (boundary.endWidth = 0.08f + num4 * 0.22f);
					obj.startWidth = startWidth;
				}
			}
			if (trapClosingStart >= 0f)
			{
				float num6 = Mathf.Clamp01((Time.time - trapClosingStart) / 0.3f);
				if ((Object)(object)trapArm1 != (Object)null)
				{
					trapArm1.localRotation = Quaternion.Slerp(trapArm1Open, trapArm1Closed, num6);
				}
				if ((Object)(object)trapArm2 != (Object)null)
				{
					trapArm2.localRotation = Quaternion.Slerp(trapArm2Open, trapArm2Closed, num6);
				}
			}
			if (Kind == 0 && zDO.GetBool("artificer_fired", false) && jawClosedAt <= 0f)
			{
				CloseTrap();
				jawClosedAt = Time.time + 0.35f;
			}
			if ((Object)(object)shotLine != (Object)null && Time.time >= nextShot - 2.5f)
			{
				((Renderer)shotLine).enabled = false;
			}
			if (Kind == 0 && jawClosedAt > 0f)
			{
				if (Time.time >= jawClosedAt)
				{
					Remove();
				}
				return;
			}
			if (Kind == 3 && lastShieldPollFrame != Time.frameCount)
			{
				lastShieldPollFrame = Time.frameCount;
				Character[] array = Character.GetAllCharacters().ToArray();
				for (int i = 0; i < array.Length; i++)
				{
					ShieldMovement.Track(array[i]);
				}
				Projectile[] array2 = Object.FindObjectsByType<Projectile>((FindObjectsSortMode)0);
				for (int i = 0; i < array2.Length; i++)
				{
					ShieldProjectiles.Track(array2[i]);
				}
			}
			if (!view.IsOwner())
			{
				return;
			}
			if (remaining <= 0f)
			{
				try
				{
					if (Kind == 4 && !detonated)
					{
						Detonate();
					}
					return;
				}
				finally
				{
					Remove();
				}
			}
			if (Kind == 3 || Kind == 4)
			{
				return;
			}
			float radius = ((Kind == 1) ? 3.8f : ((Kind == 2) ? 28f : 2.1f));
			Character val = (from c in Targets(radius)
				orderby Vector3.SqrMagnitude(((Component)c).transform.position - ((Component)this).transform.position)
				select c).FirstOrDefault();
			if (Kind == 2 && (Object)(object)val != (Object)null)
			{
				AimTurret(((Component)val).transform.position + Vector3.up);
			}
			if (Kind == 1 && (Object)(object)val != (Object)null)
			{
				Vector3 val2 = Vector3.ProjectOnPlane(((Component)val).transform.position - ((Component)this).transform.position, Vector3.up);
				if (((Vector3)(ref val2)).sqrMagnitude > 0.01f)
				{
					Quaternion val3 = Quaternion.LookRotation(val2, Vector3.up);
					float y = ((Quaternion)(ref val3)).eulerAngles.y;
					TurnTwig(y);
					if (Time.time >= nextFacingSync)
					{
						zDO.Set("artificer_twig_facing", y);
						nextFacingSync = Time.time + 0.1f;
					}
				}
			}
			if (!(Time.time < nextShot) && !((Object)(object)val == (Object)null))
			{
				if (Kind == 0)
				{
					zDO.Set("artificer_fired", true);
					CloseTrap();
					Strike(val, 75f, forceStagger: true);
					jawClosedAt = Time.time + 0.35f;
				}
				else if (Kind == 1)
				{
					Strike(val, 50f);
					observedTwigAttack = zDO.GetInt("artificer_twig_attack", 0) + 1;
					zDO.Set("artificer_twig_attack", observedTwigAttack);
					PlayTwigAttack();
					nextShot = Time.time + 1.8f;
				}
				else
				{
					Strike(val, 120f);
					DrawShot(((Component)val).transform.position);
					reloadStarted = Time.time;
					ArtificerPlugin.PlayBallistaShot(((Object)(object)turretHead != (Object)null) ? turretHead.position : ((Component)this).transform.position, ((Object)(object)turretHead != (Object)null) ? turretHead.rotation : ((Component)this).transform.rotation);
					observedReload = zDO.GetInt("artificer_reload_serial", 0) + 1;
					zDO.Set("artificer_reload_serial", observedReload);
					nextShot = Time.time + 2.8f;
				}
			}
		}

		private bool ClearShot(Character target)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: 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_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_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: 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_0041: 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_0049: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = ((Component)this).transform.position + Vector3.up * 1.5f;
			Vector3 val2 = ((Component)target).transform.position + Vector3.up;
			Vector3 val3 = val2 - val;
			RaycastHit val4 = default(RaycastHit);
			if (Physics.Raycast(val, ((Vector3)(ref val3)).normalized, ref val4, Vector3.Distance(val, val2)))
			{
				return (Object)(object)((Component)((RaycastHit)(ref val4)).collider).GetComponentInParent<Character>() == (Object)(object)target;
			}
			return true;
		}

		private IEnumerable<Character> Targets(float radius)
		{
			ZDO zDO = view.GetZDO();
			Player owner = FindOwner(zDO.GetLong("artificer_owner", 0L));
			if ((Object)(object)owner == (Object)null)
			{
				yield break;
			}
			foreach (Character allCharacter in Character.GetAllCharacters())
			{
				if (!((Object)(object)allCharacter == (Object)null) && !allCharacter.IsDead() && !allCharacter.IsPlayer() && !allCharacter.IsTamed() && IsHostile(owner, allCharacter) && Vector3.SqrMagnitude(((Component)allCharacter).transform.position - ((Component)this).transform.position) <= radius * radius)
				{
					yield return allCharacter;
				}
			}
		}

		private void Strike(Character target, float damage, bool forceStagger = false)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: 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)
			HitData val = new HitData();
			val.m_damage.m_pierce = damage;
			val.m_staggerMultiplier = 0f;
			val.m_point = ((Component)target).transform.position;
			Player val2 = FindOwner(view.GetZDO().GetLong("artificer_owner", 0L));
			if ((Object)(object)val2 != (Object)null)
			{
				val.SetAttacker((Character)(object)val2);
			}
			target.Damage(val);
			if (forceStagger && !target.IsDead())
			{
				MethodInfo methodInfo = AccessTools.Method(((object)target).GetType(), "Stagger", new Type[1] { typeof(Vector3) }, (Type[])null);
				if (methodInfo != null)
				{
					object[] array = new object[1];
					Vector3 val3 = ((Component)target).transform.position - ((Component)this).transform.position;
					array[0] = ((Vector3)(ref val3)).normalized;
					methodInfo.Invoke(target, array);
				}
			}
		}

		private void Detonate()
		{
			//IL_0118: 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_0127: 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)
			detonated = true;
			if ((Object)(object)view != (Object)null && view.IsValid() && view.IsOwner())
			{
				view.GetZDO().Set("artificer_detonated", true);
			}
			try
			{
				PlayVisualTrigger("incinerate");
				PlayVisualTrigger("activate");
				Animator[] componentsInChildren = ((Component)this).GetComponentsInChildren<Animator>(true);
				foreach (Animator val in componentsInChildren)
				{
					if (!((Behaviour)val).enabled || !((Object)(object)val.runtimeAnimatorController != (Object)null))
					{
						continue;
					}
					AnimationClip[] animationClips = val.runtimeAnimatorController.animationClips;
					foreach (AnimationClip val2 in animationClips)
					{
						if ((Object)(object)val2 != (Object)null && (((Object)val2).name.IndexOf("incinerat", StringComparison.OrdinalIgnoreCase) >= 0 || ((Object)val2).name.IndexOf("lightning", StringComparison.OrdinalIgnoreCase) >= 0))
						{
							val.Play(((Object)val2).name, 0, 0f);
							break;
						}
					}
				}
				BlastEverything(8f);
				DigSmallCrater();
			}
			finally
			{
				ArtificerLightning.Strike(((Component)this).transform.position + Vector3.up * 0.35f, ArtificerPlugin.GetObliteratorSound());
			}
		}

		private void BlastEverything(float radius)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Expected O, but got Unknown
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: 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_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_0213: Unknown result type (might be due to invalid IL or missing references)
			//IL_0218: Unknown result type (might be due to invalid IL or missing references)
			//IL_021d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0221: Unknown result type (might be due to invalid IL or missing references)
			//IL_0226: Unknown result type (might be due to invalid IL or missing references)
			HashSet<int> hashSet = new HashSet<int>();
			Collider[] array = Physics.OverlapSphere(((Component)this).transform.position, radius);
			foreach (Collider val in array)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				MonoBehaviour[] componentsInParent = ((Component)val).GetComponentsInParent<MonoBehaviour>(true);
				foreach (MonoBehaviour val2 in componentsInParent)
				{
					if ((Object)(object)val2 == (Object)null || val2 is ArtificerSummon)
					{
						continue;
					}
					string name = ((object)val2).GetType().Name;
					if ((!(name != "Character") || val2 is Character || !(name != "WearNTear") || !(name != "Destructible") || !(name != "TreeBase") || !(name != "TreeLog") || !(name != "MineRock") || !(name != "MineRock5")) && hashSet.Add(((Object)val2).GetInstanceID()))
					{
						HitData val3 = new HitData();
						val3.m_damage.m_pierce = 2000f;
						if (name == "TreeBase" || name == "TreeLog")
						{
							val3.m_damage.m_pierce = 0f;
							val3.m_damage.m_chop = 2000f;
						}
						if (name == "MineRock" || name == "MineRock5")
						{
							val3.m_damage.m_pierce = 0f;
							val3.m_damage.m_pickaxe = 2000f;
						}
						FieldInfo fieldInfo = AccessTools.Field(typeof(HitData), "m_toolTier");
						if (fieldInfo != null)
						{
							fieldInfo.SetValue(val3, Convert.ChangeType(4, fieldInfo.FieldType));
						}
						FieldInfo fieldInfo2 = AccessTools.Field(typeof(HitData), "m_hitCollider");
						if (fieldInfo2 != null)
						{
							fieldInfo2.SetValue(val3, val);
						}
						val3.m_point = val.ClosestPoint(((Component)this).transform.position);
						Vector3 val4 = ((Component)val2).transform.position - ((Component)this).transform.position;
						val3.m_dir = ((Vector3)(ref val4)).normalized;
						MethodInfo methodInfo = AccessTools.Method(((object)val2).GetType(), "Damage", new Type[1] { typeof(HitData) }, (Type[])null);
						if (methodInfo != null)
						{
							methodInfo.Invoke(val2, new object[1] { val3 });
						}
					}
				}
			}
		}

		private void DigSmallCrater()
		{
			//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_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_0042: 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)
			GameObject prefab = PrefabManager.Instance.GetPrefab("digg_v2");
			if (!((Object)(object)prefab == (Object)null))
			{
				Vector3 position = ((Component)this).transform.position;
				GameObject obj = Object.Instantiate<GameObject>(prefab, position, Quaternion.identity);
				((Object)obj).name = "ArtificerObliteratorCrater";
				obj.transform.localScale = Vector3.one * 0.5f;
			}
		}

		private void Remove()
		{
			if (!removing)
			{
				if ((Object)(object)view != (Object)null && view.IsValid() && view.IsOwner())
				{
					view.GetZDO().Set("artificer_removing", true);
				}
				BeginRemoval();
			}
		}

		private void BeginRemoval()
		{
			//IL_0117: 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_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)
			if (removing)
			{
				return;
			}
			removing = true;
			removalStarted = Time.time;
			if (Kind == 4)
			{
				if ((Object)(object)view != (Object)null && view.IsValid() && !view.IsOwner() && view.GetZDO().GetBool("artificer_detonated", false))
				{
					ArtificerLightning.Strike(((Component)this).transform.position + Vector3.up * 0.35f, ArtificerPlugin.GetObliteratorSound());
				}
				if ((Object)(object)boundary != (Object)null)
				{
					((Renderer)boundary).enabled = false;
				}
				if ((Object)(object)chargeLight != (Object)null)
				{
					((Behaviour)chargeLight).enabled = false;
				}
				All.Remove(this);
			}
			else
			{
				StartBreakingVisuals();
				All.Remove(this);
				if ((Object)(object)view != (Object)null && view.IsValid() && view.IsOwner())
				{
					ArtificerPlugin.PlayBuildingDismantled(Kind, ((Component)this).transform.position, ((Component)this).transform.rotation);
				}
			}
		}

		private void EmitObliteratorBurst()
		{
			//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_0016: 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_0025: 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_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: 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_00b0: 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_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: 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_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Expected O, but got Unknown
			//IL_0137: Expected O, but got Unknown
			GameObject val = new GameObject("Artificer obliterator burst");
			val.transform.position = ((Component)this).transform.position + Vector3.up * 0.7f;
			ParticleSystem obj = val.AddComponent<ParticleSystem>();
			MainModule main = obj.main;
			((MainModule)(ref main)).loop = false;
			((MainModule)(ref main)).playOnAwake = false;
			((MainModule)(ref main)).startLifetime = MinMaxCurve.op_Implicit(1.1f);
			((MainModule)(ref main)).startSpeed = MinMaxCurve.op_Implicit(7f);
			((MainModule)(ref main)).startSize = MinMaxCurve.op_Implicit(0.19f);
			((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(new Color(0.45f, 0.82f, 1f, 1f));
			((MainModule)(ref main)).gravityModifier = MinMaxCurve.op_Implicit(0.5f);
			((MainModule)(ref main)).maxParticles = 160;
			EmissionModule emission = obj.emission;
			((EmissionModule)(ref emission)).enabled = false;
			ShapeModule shape = obj.shape;
			((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)0;
			((ShapeModule)(ref shape)).radius = 0.45f;
			((Renderer)((Component)obj).GetComponent<ParticleSystemRenderer>()).material = new Material(Shader.Find("Particles/Additive") ?? Shader.Find("Sprites/Default") ?? Shader.Find("Standard"));
			obj.Emit(100);
			Object.Destroy((Object)val, 2.5f);
		}

		private void StartBreakingVisuals()
		{
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Expected O, but got Unknown
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: 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_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: 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_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_02de: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e5: Expected O, but got Unknown
			//IL_02f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_030b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0323: Unknown result type (might be due to invalid IL or missing references)
			//IL_0378: Unknown result type (might be due to invalid IL or missing references)
			//IL_037d: Unknown result type (might be due to invalid IL or missing references)
			//IL_038a: Unknown result type (might be due to invalid IL or missing references)
			//IL_038f: 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_03c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_020d: 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_0267: Unknown result type (might be due to invalid IL or missing references)
			Animator[] componentsInChildren = ((Component)this).GetComponentsInChildren<Animator>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				((Behaviour)componentsInChildren[i]).enabled = false;
			}
			if ((Object)(object)boundary != (Object)null)
			{
				((Renderer)boundary).enabled = false;
			}
			int num = 0;
			Renderer[] componentsInChildren2 = ((Component)this).GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren2)
			{
				if (!val.enabled)
				{
					continue;
				}
				if (((Object)((Component)val).gameObject).name.StartsWith("Artificer "))
				{
					val.enabled = false;
					continue;
				}
				Mesh val2 = null;
				SkinnedMeshRenderer val3 = (SkinnedMeshRenderer)(object)((val is SkinnedMeshRenderer) ? val : null);
				if ((Object)(object)val3 != (Object)null && (Object)(object)val3.sharedMesh != (Object)null)
				{
					val2 = new Mesh();
					val3.BakeMesh(val2);
				}
				else
				{
					MeshFilter component = ((Component)val).GetComponent<MeshFilter>();
					if ((Object)(object)component != (Object)null)
					{
						val2 = component.sharedMesh;
					}
				}
				if ((Kind == 1 || Kind == 3 || Kind == 4) && num < ((Kind == 4) ? 48 : 12))
				{
					for (int j = 0; j < ((Kind == 4) ? 4 : 2); j++)
					{
						GameObject val4 = GameObject.CreatePrimitive((PrimitiveType)3);
						((Object)val4).name = "Artificer break fragment";
						Object.Destroy((Object)(object)val4.GetComponent<Collider>());
						Transform transform = val4.transform;
						Bounds bounds = val.bounds;
						transform.position = ((Bounds)(ref bounds)).center + Random.insideUnitSphere * 0.2f;
						val4.transform.rotation = Random.ro