Decompiled source of HatterValuablesPack v1.0.1

HatterValuablesPack.dll

Decompiled an hour ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Photon.Pun;
using REPOLib.Modules;
using TMPro;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("HatterValuablesPack")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("HatterValuablesPack")]
[assembly: AssemblyTitle("HatterValuablesPack")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace HatterValuablesPack;

public class Compass : MonoBehaviour
{
	public enum Kind
	{
		Enemy,
		Extraction
	}

	public Kind kind;

	public Transform needle;

	public Transform emblem;

	public Vector3 modelCentre;

	private const float SearchInterval = 0.25f;

	private const float Stiffness = 45f;

	private const float Damping = 6f;

	private static readonly FieldInfo SpawnedField = AccessTools.Field(typeof(EnemyParent), "Spawned");

	private static readonly FieldInfo ParentEnemyField = AccessTools.Field(typeof(EnemyParent), "Enemy");

	private static readonly FieldInfo HealthField = AccessTools.Field(typeof(Enemy), "Health");

	private static readonly FieldInfo DeadField = AccessTools.Field(typeof(EnemyHealth), "dead");

	private static readonly FieldInfo StateField = AccessTools.Field(typeof(ExtractionPoint), "currentState");

	private static readonly FieldInfo ShopField = AccessTools.Field(typeof(ExtractionPoint), "isShop");

	private static ExtractionPoint[] points = (ExtractionPoint[])(object)new ExtractionPoint[0];

	private static float pointsAt = -10f;

	private Vector3 pointing;

	private Vector3 velocity;

	private Vector3 wanderTarget;

	private float nextSearch;

	private float nextWander;

	private float shakeTime;

	private bool hasTarget;

	private Vector3 target;

	private bool emblemDone;

	private void Start()
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		pointing = Random.onUnitSphere;
		wanderTarget = pointing;
		if (!((Object)(object)emblem != (Object)null) || emblemDone)
		{
			return;
		}
		emblemDone = true;
		if (kind == Kind.Enemy)
		{
			try
			{
				if ((Object)(object)RobeMini.Spawn(emblem, CompassBuilder.EmblemHeight, Settings.CompassRobeYaw.Value) != (Object)null)
				{
					HideBuiltInEmblem();
				}
				return;
			}
			catch (Exception arg)
			{
				Plugin.Log.LogWarning((object)$"Enemy Compass: the little Robe failed: {arg}");
				return;
			}
		}
		try
		{
			if ((Object)(object)ExtractionMini.Spawn(emblem, CompassBuilder.EmblemHeight) != (Object)null)
			{
				HideBuiltInEmblem();
			}
		}
		catch (Exception arg2)
		{
			Plugin.Log.LogWarning((object)$"Extraction Compass: copying the extraction screen failed: {arg2}");
		}
	}

	private void Update()
	{
		//IL_0079: Unknown result type (might be due to invalid IL or missing references)
		//IL_0084: Unknown result type (might be due to invalid IL or missing references)
		//IL_0089: Unknown result type (might be due to invalid IL or missing references)
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		//IL_008e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_0102: Unknown result type (might be due to invalid IL or missing references)
		//IL_0107: Unknown result type (might be due to invalid IL or missing references)
		//IL_0109: Unknown result type (might be due to invalid IL or missing references)
		//IL_010e: 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_011e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0128: Unknown result type (might be due to invalid IL or missing references)
		//IL_012d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0133: Unknown result type (might be due to invalid IL or missing references)
		//IL_0138: Unknown result type (might be due to invalid IL or missing references)
		//IL_013d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0144: Unknown result type (might be due to invalid IL or missing references)
		//IL_014a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0150: Unknown result type (might be due to invalid IL or missing references)
		//IL_0155: Unknown result type (might be due to invalid IL or missing references)
		//IL_015a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0184: Unknown result type (might be due to invalid IL or missing references)
		//IL_0189: Unknown result type (might be due to invalid IL or missing references)
		//IL_0172: Unknown result type (might be due to invalid IL or missing references)
		//IL_0173: Unknown result type (might be due to invalid IL or missing references)
		//IL_029a: Unknown result type (might be due to invalid IL or missing references)
		//IL_029b: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_0256: Unknown result type (might be due to invalid IL or missing references)
		//IL_0260: Unknown result type (might be due to invalid IL or missing references)
		//IL_0265: Unknown result type (might be due to invalid IL or missing references)
		//IL_026a: Unknown result type (might be due to invalid IL or missing references)
		//IL_026f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0272: Unknown result type (might be due to invalid IL or missing references)
		//IL_0277: Unknown result type (might be due to invalid IL or missing references)
		//IL_027a: Unknown result type (might be due to invalid IL or missing references)
		//IL_027f: 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_028b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0290: Unknown result type (might be due to invalid IL or missing references)
		//IL_0294: Unknown result type (might be due to invalid IL or missing references)
		//IL_0299: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d8: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)needle == (Object)null)
		{
			return;
		}
		if (Time.time >= nextSearch)
		{
			nextSearch = Time.time + 0.25f;
			hasTarget = ((kind == Kind.Enemy) ? NearestEnemy(needle.position, out target) : NearestExtraction(needle.position, out target));
		}
		Vector3 val = (hasTarget ? (target - needle.position) : Vector3.zero);
		Vector3 normalized;
		if (hasTarget && ((Vector3)(ref val)).sqrMagnitude > 1E-06f)
		{
			normalized = ((Vector3)(ref val)).normalized;
		}
		else
		{
			if (Time.time >= nextWander)
			{
				nextWander = Time.time + Random.Range(0.35f, 1.4f);
				wanderTarget = Random.onUnitSphere;
			}
			normalized = wanderTarget;
		}
		((Vector3)(ref normalized)).Normalize();
		float num = Mathf.Min(Time.deltaTime, 0.05f);
		velocity += ((normalized - pointing) * 45f - velocity * 6f) * num;
		pointing += velocity * num;
		if (((Vector3)(ref pointing)).sqrMagnitude < 1E-06f)
		{
			pointing = normalized;
		}
		((Vector3)(ref pointing)).Normalize();
		Vector3 normalized2 = pointing;
		if (hasTarget)
		{
			float num2 = Mathf.Max(Settings.CompassShakeFar.Value, Settings.CompassShakeNear.Value + 0.1f);
			float value = Settings.CompassShakeNear.Value;
			float num3 = Mathf.Clamp01((num2 - ((Vector3)(ref val)).magnitude) / (num2 - value));
			if (num3 > 0f)
			{
				shakeTime += Time.deltaTime * Mathf.Lerp(4f, 22f, num3);
				float num4 = Mathf.Tan(Settings.CompassShakeMax.Value * (MathF.PI / 180f)) * num3 * num3;
				Vector3 val2 = new Vector3(Mathf.PerlinNoise(shakeTime, 0.1f), Mathf.PerlinNoise(shakeTime, 3.7f), Mathf.PerlinNoise(shakeTime, 7.3f)) * 2f - Vector3.one;
				Vector3 val3 = pointing + Vector3.ProjectOnPlane(val2, pointing) * num4;
				normalized2 = ((Vector3)(ref val3)).normalized;
			}
		}
		Vector3 val4 = ((Mathf.Abs(Vector3.Dot(normalized2, Vector3.up)) > 0.98f) ? needle.parent.forward : Vector3.up);
		needle.rotation = Quaternion.LookRotation(-normalized2, val4);
	}

	private void HideBuiltInEmblem()
	{
		Transform val = (((Object)(object)emblem != (Object)null) ? emblem.Find("Emblem (built in)") : null);
		if ((Object)(object)val != (Object)null)
		{
			((Component)val).gameObject.SetActive(false);
		}
	}

	private static bool NearestEnemy(Vector3 from, out Vector3 best)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0128: Unknown result type (might be due to invalid IL or missing references)
		//IL_011a: Unknown result type (might be due to invalid IL or missing references)
		//IL_012d: 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_0131: Unknown result type (might be due to invalid IL or missing references)
		//IL_0132: Unknown result type (might be due to invalid IL or missing references)
		//IL_0137: Unknown result type (might be due to invalid IL or missing references)
		//IL_014b: Unknown result type (might be due to invalid IL or missing references)
		//IL_014d: Unknown result type (might be due to invalid IL or missing references)
		best = default(Vector3);
		EnemyDirector instance = EnemyDirector.instance;
		if ((Object)(object)instance == (Object)null || instance.enemiesSpawned == null)
		{
			return false;
		}
		float num = float.MaxValue;
		foreach (EnemyParent item in instance.enemiesSpawned)
		{
			if ((Object)(object)item == (Object)null || (SpawnedField != null && !(bool)SpawnedField.GetValue(item)))
			{
				continue;
			}
			Enemy val = (Enemy)(((object)((ParentEnemyField != null) ? /*isinst with value type is only supported in some contexts*/: null)) ?? ((object)((Component)item).GetComponentInChildren<Enemy>()));
			if ((Object)(object)val == (Object)null || !((Component)val).gameObject.activeInHierarchy)
			{
				continue;
			}
			EnemyHealth val2 = (EnemyHealth)((HealthField != null) ? /*isinst with value type is only supported in some contexts*/: null);
			if (!((Object)(object)val2 != (Object)null) || !(DeadField != null) || !(bool)DeadField.GetValue(val2))
			{
				Vector3 val3 = (((Object)(object)val.CenterTransform != (Object)null) ? val.CenterTransform.position : ((Component)val).transform.position);
				Vector3 val4 = val3 - from;
				float sqrMagnitude = ((Vector3)(ref val4)).sqrMagnitude;
				if (sqrMagnitude < num)
				{
					num = sqrMagnitude;
					best = val3;
				}
			}
		}
		return num < float.MaxValue;
	}

	private static bool NearestExtraction(Vector3 from, out Vector3 best)
	{
		//IL_0001: 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_00bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00db: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
		best = default(Vector3);
		if (Time.time - pointsAt > 3f)
		{
			pointsAt = Time.time;
			points = Object.FindObjectsByType<ExtractionPoint>((FindObjectsSortMode)0);
		}
		float num = float.MaxValue;
		ExtractionPoint[] array = points;
		foreach (ExtractionPoint val in array)
		{
			if (!((Object)(object)val == (Object)null) && ((Component)val).gameObject.activeInHierarchy && (!(ShopField != null) || !(bool)ShopField.GetValue(val)) && (!(StateField != null) || !(StateField.GetValue(val)?.ToString() == "Complete")))
			{
				Vector3 val2 = ((Component)val).transform.position - from;
				float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude;
				if (sqrMagnitude < num)
				{
					num = sqrMagnitude;
					best = ((Component)val).transform.position;
				}
			}
		}
		return num < float.MaxValue;
	}
}
internal static class CompassBuilder
{
	internal const string EnemyName = "Enemy Compass";

	internal const string ExtractionName = "Extraction Compass";

	private static readonly string[] BasePaths = new string[4] { "Valuables/02 Small/Valuable Desert Gold Bar", "Valuables/02 Small/Valuable Arctic Hdd", "Valuables/02 Small/Valuable Arctic Calculator", "Valuables/02 Small/Valuable Manor Globe" };

	private const string WatchPath = "Valuables/01 Tiny/Valuable Manor Pocket Watch";

	private const string CrystalPath = "Valuables/03 Medium/Valuable Wizard Power Crystal";

	internal static readonly Vector3 SphereCentre = new Vector3(0f, 0.046f, 0f);

	internal static readonly Vector3 Top = new Vector3(0f, 0.09f, 0f);

	private const float FrameWidth = 0.083f;

	internal const float FrameHeight = 0.09f;

	private const float BuiltInEmblemHeight = 0.03f;

	internal const string SimpleEmblemName = "Emblem (built in)";

	private static GameObject holder;

	internal static float EmblemHeight => 0.09f * Settings.CompassEmblemVsCompass.Value;

	internal static GameObject BuildEnemy()
	{
		return Build("Enemy Compass", "Valuable Hatter Enemy Compass", Compass.Kind.Enemy, Settings.EnemyCompassValueMin.Value, Settings.EnemyCompassValueMax.Value);
	}

	internal static GameObject BuildExtraction()
	{
		return Build("Extraction Compass", "Valuable Hatter Extraction Compass", Compass.Kind.Extraction, Settings.ExtractionCompassValueMin.Value, Settings.ExtractionCompassValueMax.Value);
	}

	private static GameObject Build(string label, string prefabName, Compass.Kind kind, int valueMin, int valueMax)
	{
		//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_00d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dc: Expected O, but got Unknown
		//IL_02f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_031f: Unknown result type (might be due to invalid IL or missing references)
		//IL_032b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0337: Unknown result type (might be due to invalid IL or missing references)
		//IL_0341: Unknown result type (might be due to invalid IL or missing references)
		//IL_034d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0354: Unknown result type (might be due to invalid IL or missing references)
		//IL_036a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0370: 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_03c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_03f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_03f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_0410: Unknown result type (might be due to invalid IL or missing references)
		//IL_0415: Unknown result type (might be due to invalid IL or missing references)
		//IL_0423: Unknown result type (might be due to invalid IL or missing references)
		//IL_0438: Unknown result type (might be due to invalid IL or missing references)
		//IL_0442: Unknown result type (might be due to invalid IL or missing references)
		//IL_046b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0499: Unknown result type (might be due to invalid IL or missing references)
		//IL_04b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_0392: Unknown result type (might be due to invalid IL or missing references)
		//IL_0398: Unknown result type (might be due to invalid IL or missing references)
		//IL_051a: Unknown result type (might be due to invalid IL or missing references)
		//IL_051f: Unknown result type (might be due to invalid IL or missing references)
		//IL_052b: Unknown result type (might be due to invalid IL or missing references)
		//IL_053c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0543: Unknown result type (might be due to invalid IL or missing references)
		//IL_0548: Unknown result type (might be due to invalid IL or missing references)
		//IL_054d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0561: Unknown result type (might be due to invalid IL or missing references)
		//IL_0568: Unknown result type (might be due to invalid IL or missing references)
		//IL_0579: Unknown result type (might be due to invalid IL or missing references)
		//IL_057b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0580: Unknown result type (might be due to invalid IL or missing references)
		//IL_058a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0594: Unknown result type (might be due to invalid IL or missing references)
		//IL_0599: 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_05a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_05aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_05ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_05d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_05f4: Unknown result type (might be due to invalid IL or missing references)
		//IL_04df: Unknown result type (might be due to invalid IL or missing references)
		//IL_04e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_04fe: Unknown result type (might be due to invalid IL or missing references)
		//IL_050e: Unknown result type (might be due to invalid IL or missing references)
		//IL_086e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0875: Expected O, but got Unknown
		//IL_088e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0898: Unknown result type (might be due to invalid IL or missing references)
		//IL_089d: Unknown result type (might be due to invalid IL or missing references)
		//IL_08b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_08bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_08c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_08d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_08de: Unknown result type (might be due to invalid IL or missing references)
		//IL_08ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_08f4: Unknown result type (might be due to invalid IL or missing references)
		//IL_0927: Unknown result type (might be due to invalid IL or missing references)
		//IL_092c: Unknown result type (might be due to invalid IL or missing references)
		//IL_093c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0946: Unknown result type (might be due to invalid IL or missing references)
		//IL_094d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0952: Unknown result type (might be due to invalid IL or missing references)
		//IL_0957: Unknown result type (might be due to invalid IL or missing references)
		//IL_0995: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = null;
		string text = null;
		string[] basePaths = BasePaths;
		foreach (string text2 in basePaths)
		{
			val = Resources.Load<GameObject>(text2);
			if ((Object)(object)val != (Object)null && (Object)(object)val.GetComponent<ValuableObject>() != (Object)null)
			{
				text = text2;
				break;
			}
			val = null;
		}
		if ((Object)(object)val == (Object)null)
		{
			Plugin.Log.LogError((object)(label + ": no small vanilla valuable found to build it from."));
			return null;
		}
		MeshLibrary.Model model = MeshLibrary.Get("compass.mesh", "Compass_Frame");
		MeshLibrary.Model model2 = MeshLibrary.Get("compass.mesh", "Compass_Glass");
		MeshLibrary.Model model3 = MeshLibrary.Get("compass.mesh", "Compass_Needle");
		MeshLibrary.Model model4 = MeshLibrary.Get("compass.mesh", (kind == Compass.Kind.Enemy) ? "Compass_EmblemEnemy" : "Compass_EmblemExtraction");
		if (model == null || model3 == null)
		{
			return null;
		}
		if ((Object)(object)holder == (Object)null)
		{
			holder = new GameObject("HatterValuablesPack.CompassHolder");
			holder.SetActive(false);
			Object.DontDestroyOnLoad((Object)(object)holder);
			((Object)holder).hideFlags = (HideFlags)61;
		}
		GameObject val2 = Object.Instantiate<GameObject>(val, holder.transform);
		((Object)val2).name = prefabName;
		Transform transform = val2.transform;
		Bounds val3 = NukeBuilder.LocalMeshBounds(transform);
		string text3 = "'" + text + "'";
		NukeBuilder.LogComponents(val2, label, text3);
		MonoBehaviour[] componentsInChildren = val2.GetComponentsInChildren<MonoBehaviour>(true);
		foreach (MonoBehaviour val4 in componentsInChildren)
		{
			if (!((Object)(object)val4 == (Object)null) && !(val4 is ValuableObject))
			{
				string name = ((object)val4).GetType().Name;
				bool flag = name.StartsWith("ValuableDiscover") || name == "MapValuable" || name == "NotValuableObject";
				if (val4 is Trap || (name.Contains("Valuable") && !flag) || val4 is MusicalValuableLogic)
				{
					Plugin.Log.LogInfo((object)(label + ": removed " + name + "."));
					Object.DestroyImmediate((Object)(object)val4);
				}
			}
		}
		ParticleSystem[] componentsInChildren2 = val2.GetComponentsInChildren<ParticleSystem>(true);
		for (int i = 0; i < componentsInChildren2.Length; i++)
		{
			((Component)componentsInChildren2[i]).gameObject.SetActive(false);
		}
		Light[] componentsInChildren3 = val2.GetComponentsInChildren<Light>(true);
		for (int i = 0; i < componentsInChildren3.Length; i++)
		{
			((Behaviour)componentsInChildren3[i]).enabled = false;
		}
		AudioSource[] componentsInChildren4 = val2.GetComponentsInChildren<AudioSource>(true);
		for (int i = 0; i < componentsInChildren4.Length; i++)
		{
			((Behaviour)componentsInChildren4[i]).enabled = false;
		}
		Material val5 = null;
		Renderer[] componentsInChildren5 = val2.GetComponentsInChildren<Renderer>(true);
		foreach (Renderer val6 in componentsInChildren5)
		{
			if ((Object)(object)val5 == (Object)null && val6 is MeshRenderer && (Object)(object)val6.sharedMaterial != (Object)null)
			{
				val5 = val6.sharedMaterial;
			}
			val6.enabled = false;
		}
		float value = Settings.CompassScale.Value;
		Transform transform2 = new GameObject("Compass Model").transform;
		transform2.SetParent(transform, false);
		((Component)transform2).gameObject.layer = val2.layer;
		transform2.localPosition = new Vector3(((Bounds)(ref val3)).center.x, ((Bounds)(ref val3)).min.y, ((Bounds)(ref val3)).center.z);
		transform2.localScale = Vector3.one * value;
		MeshLibrary.Attach(model, transform2, "Compass Frame", val5).layer = val2.layer;
		if (model2 != null)
		{
			MeshLibrary.Attach(model2, transform2, "Compass Glass", val5).layer = val2.layer;
		}
		Transform transform3 = new GameObject("Needle Pivot").transform;
		transform3.SetParent(transform2, false);
		transform3.localPosition = SphereCentre;
		((Component)transform3).gameObject.layer = val2.layer;
		MeshLibrary.Attach(model3, transform3, "Needle", val5).layer = val2.layer;
		GameObject val7 = new GameObject("Needle Tip Glow");
		val7.transform.SetParent(transform3, false);
		val7.transform.localPosition = new Vector3(0f, 0f, -0.024f);
		val7.layer = val2.layer;
		Light obj = val7.AddComponent<Light>();
		obj.type = (LightType)2;
		obj.color = new Color(1f, 0.08f, 0.05f);
		obj.range = 0.05f * value;
		obj.intensity = 1.5f;
		obj.shadows = (LightShadows)0;
		Transform transform4 = new GameObject("Emblem").transform;
		transform4.SetParent(transform2, false);
		transform4.localPosition = Top;
		((Component)transform4).gameObject.layer = val2.layer;
		if (model4 != null)
		{
			GameObject obj2 = MeshLibrary.Attach(model4, transform4, "Emblem (built in)", val5);
			obj2.layer = val2.layer;
			obj2.transform.localScale = Vector3.one * (EmblemHeight / 0.03f);
		}
		Vector3 localPosition = transform2.localPosition;
		NukeBuilder.ReplaceColliders(transform, new(Vector3, Quaternion, Vector3)[2]
		{
			(localPosition + new Vector3(0f, 0.045f, 0f) * value, Quaternion.identity, new Vector3(0.083f, 0.09f, 0.083f) * value),
			(localPosition + (Top + Vector3.up * EmblemHeight / 2f) * value, Quaternion.identity, new Vector3(EmblemHeight * 0.6f, EmblemHeight, EmblemHeight * 0.6f) * value)
		}, label, text3);
		ValuableObject component = val2.GetComponent<ValuableObject>();
		component.volumeType = (Type)2;
		Value val8 = ScriptableObject.CreateInstance<Value>();
		((Object)val8).name = prefabName + " Value";
		val8.valueMin = Mathf.Min(valueMin, valueMax);
		val8.valueMax = Mathf.Max(valueMin, valueMax);
		component.valuePreset = val8;
		GameObject obj3 = Resources.Load<GameObject>("Valuables/01 Tiny/Valuable Manor Pocket Watch");
		ValuableObject val9 = ((obj3 != null) ? obj3.GetComponent<ValuableObject>() : null);
		if ((Object)(object)val9 != (Object)null)
		{
			if ((Object)(object)val9.audioPreset != (Object)null)
			{
				component.audioPreset = val9.audioPreset;
				component.audioPresetPitch = val9.audioPresetPitch;
			}
			if ((Object)(object)val9.physAttributePreset != (Object)null)
			{
				PhysAttribute val10 = ScriptableObject.CreateInstance<PhysAttribute>();
				((Object)val10).name = prefabName + " Weight";
				val10.mass = val9.physAttributePreset.mass * 6f;
				component.physAttributePreset = val10;
			}
		}
		else
		{
			Plugin.Log.LogWarning((object)(label + ": the pocket watch wasn't found; it keeps " + text3 + "'s sound and weight."));
		}
		PhysGrabObjectImpactDetector componentInChildren = val2.GetComponentInChildren<PhysGrabObjectImpactDetector>(true);
		GameObject val11 = Resources.Load<GameObject>("Valuables/03 Medium/Valuable Wizard Power Crystal");
		ValuableObject val12 = (((Object)(object)val11 != (Object)null) ? val11.GetComponent<ValuableObject>() : null);
		PhysGrabObjectImpactDetector val13 = (((Object)(object)val11 != (Object)null) ? val11.GetComponentInChildren<PhysGrabObjectImpactDetector>(true) : null);
		if ((Object)(object)val12 != (Object)null && (Object)(object)val12.durabilityPreset != (Object)null)
		{
			component.durabilityPreset = val12.durabilityPreset;
		}
		else
		{
			Plugin.Log.LogWarning((object)(label + ": the power crystal wasn't found; it keeps " + text3 + "'s toughness."));
		}
		if ((Object)(object)componentInChildren != (Object)null)
		{
			if ((Object)(object)val13 != (Object)null)
			{
				componentInChildren.fragilityMultiplier = val13.fragilityMultiplier;
				componentInChildren.impactFragilityMultiplier = val13.impactFragilityMultiplier;
			}
			componentInChildren.destroyDisable = false;
			componentInChildren.slidingDisable = false;
		}
		Plugin.Log.LogInfo((object)($"{label}: toughness from the power crystal: fragility {(((Object)(object)component.durabilityPreset != (Object)null) ? component.durabilityPreset.fragility : (-1f)):0.#}, " + $"durability {(((Object)(object)component.durabilityPreset != (Object)null) ? component.durabilityPreset.durability : (-1f)):0.#}, multipliers " + $"{(((Object)(object)componentInChildren != (Object)null) ? componentInChildren.fragilityMultiplier : (-1f)):0.##} / {(((Object)(object)componentInChildren != (Object)null) ? componentInChildren.impactFragilityMultiplier : (-1f)):0.##}."));
		Gradient val14 = new Gradient();
		val14.SetKeys((GradientColorKey[])(object)new GradientColorKey[2]
		{
			new GradientColorKey(new Color(0.85f, 0.65f, 0.3f), 0f),
			new GradientColorKey(new Color(0.95f, 0.92f, 0.85f), 1f)
		}, (GradientAlphaKey[])(object)new GradientAlphaKey[2]
		{
			new GradientAlphaKey(1f, 0f),
			new GradientAlphaKey(1f, 1f)
		});
		component.particleColors = val14;
		Compass compass = val2.AddComponent<Compass>();
		compass.kind = kind;
		compass.needle = transform3;
		compass.emblem = transform4;
		compass.modelCentre = transform2.localPosition + Vector3.up * (0.09f + EmblemHeight) * 0.5f * value;
		Plugin.Log.LogInfo((object)string.Format("{0}: built from {1}, {2:0} cm tall, volume {3}, ${4:0}–{5:0}, material '{6}'.", label, text3, (0.09f + EmblemHeight) * value * 100f, component.volumeType, val8.valueMin, val8.valueMax, ((Object)(object)val5 != (Object)null) ? ((Object)val5).name : "none"));
		return val2;
	}
}
[HarmonyPatch(typeof(ValuableDiscoverGraphic), "RendererBoundsInScreenSpace")]
internal static class DiscoverBoundsPatch
{
	private static bool logged;

	private static void Prefix(ValuableDiscoverGraphic __instance, ref Bounds bigBounds)
	{
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0128: Unknown result type (might be due to invalid IL or missing references)
		//IL_0129: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_00be: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cf: 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_00f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0109: Unknown result type (might be due to invalid IL or missing references)
		//IL_0076: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		PhysGrabObject val = (((Object)(object)__instance != (Object)null) ? __instance.target : null);
		if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).GetComponent<Compass>() == (Object)null)
		{
			return;
		}
		bool flag = false;
		Bounds val2 = default(Bounds);
		Collider[] componentsInChildren = ((Component)val).GetComponentsInChildren<Collider>();
		foreach (Collider val3 in componentsInChildren)
		{
			if (!((Object)(object)val3 == (Object)null) && !val3.isTrigger && val3.enabled)
			{
				if (!flag)
				{
					val2 = val3.bounds;
					flag = true;
				}
				else
				{
					((Bounds)(ref val2)).Encapsulate(val3.bounds);
				}
			}
		}
		if (flag)
		{
			if (!logged)
			{
				logged = true;
				Plugin.Log.LogInfo((object)($"Compass highlight: sized from the colliders ({((Bounds)(ref val2)).size.x:0.00} x {((Bounds)(ref val2)).size.y:0.00} x {((Bounds)(ref val2)).size.z:0.00} m) " + $"instead of the renderers ({((Bounds)(ref bigBounds)).size.x:0.00} x {((Bounds)(ref bigBounds)).size.y:0.00} x {((Bounds)(ref bigBounds)).size.z:0.00} m)."));
			}
			bigBounds = val2;
		}
	}
}
internal class ExtractionMini : MonoBehaviour
{
	private TMP_Text emojiCopy;

	private TMP_Text haulCopy;

	private TMP_Text emojiSource;

	private TMP_Text haulSource;

	private float nextSync;

	private static bool logged;

	internal static ExtractionMini Spawn(Transform parent, float height)
	{
		//IL_005c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ac: Expected O, but got Unknown
		//IL_00b1: 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_01e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_0206: Unknown result type (might be due to invalid IL or missing references)
		//IL_0121: Unknown result type (might be due to invalid IL or missing references)
		//IL_0126: Unknown result type (might be due to invalid IL or missing references)
		//IL_0134: 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_0147: Unknown result type (might be due to invalid IL or missing references)
		//IL_014c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0156: Unknown result type (might be due to invalid IL or missing references)
		//IL_0183: Unknown result type (might be due to invalid IL or missing references)
		//IL_023e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0251: Unknown result type (might be due to invalid IL or missing references)
		//IL_0264: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_02fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0355: Unknown result type (might be due to invalid IL or missing references)
		//IL_035a: Unknown result type (might be due to invalid IL or missing references)
		//IL_035f: Unknown result type (might be due to invalid IL or missing references)
		//IL_033d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0364: Unknown result type (might be due to invalid IL or missing references)
		//IL_0389: Unknown result type (might be due to invalid IL or missing references)
		//IL_038e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0393: Unknown result type (might be due to invalid IL or missing references)
		//IL_0380: Unknown result type (might be due to invalid IL or missing references)
		//IL_0398: Unknown result type (might be due to invalid IL or missing references)
		//IL_03a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_03b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_03c6: 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_03fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_0408: Unknown result type (might be due to invalid IL or missing references)
		//IL_040f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0420: Unknown result type (might be due to invalid IL or missing references)
		//IL_0422: Unknown result type (might be due to invalid IL or missing references)
		//IL_0424: Unknown result type (might be due to invalid IL or missing references)
		//IL_042b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0430: Unknown result type (might be due to invalid IL or missing references)
		ExtractionPoint val = null;
		ExtractionPoint[] array = Object.FindObjectsByType<ExtractionPoint>((FindObjectsSortMode)0);
		foreach (ExtractionPoint val2 in array)
		{
			if (!((Object)(object)val2 == (Object)null) && !((Object)(object)val2.emojiScreen == (Object)null))
			{
				val = val2;
				break;
			}
		}
		if ((Object)(object)val == (Object)null)
		{
			return null;
		}
		Transform transform = ((Component)val).transform;
		Matrix4x4 toFrame = transform.worldToLocalMatrix;
		string report;
		List<Renderer> list = Pick(val, out report);
		if (!logged)
		{
			logged = true;
			Plugin.Log.LogInfo((object)report);
		}
		if (list.Count == 0 && (Object)(object)val.emojiScreen == (Object)null)
		{
			return null;
		}
		GameObject val3 = new GameObject("Little Extraction Screen (from the level)");
		Transform transform2 = new GameObject("Pieces").transform;
		transform2.SetParent(val3.transform, false);
		bool any = false;
		Bounds b = default(Bounds);
		foreach (Renderer item in list)
		{
			MeshFilter component = ((Component)item).GetComponent<MeshFilter>();
			if (!((Object)(object)component == (Object)null) && !((Object)(object)component.sharedMesh == (Object)null))
			{
				GameObject val4 = new GameObject(((Object)item).name);
				val4.transform.SetParent(transform2, false);
				Place(val4.transform, toFrame * ((Component)item).transform.localToWorldMatrix);
				val4.AddComponent<MeshFilter>().sharedMesh = component.sharedMesh;
				MeshRenderer obj = val4.AddComponent<MeshRenderer>();
				((Renderer)obj).sharedMaterials = item.sharedMaterials;
				((Renderer)obj).shadowCastingMode = (ShadowCastingMode)0;
				Grow(item.bounds);
			}
		}
		int childCount = transform2.childCount;
		ExtractionMini extractionMini = val3.AddComponent<ExtractionMini>();
		extractionMini.emojiSource = (TMP_Text)(object)val.emojiScreen;
		extractionMini.haulSource = (TMP_Text)(object)val.haulGoalScreen;
		extractionMini.emojiCopy = CopyText((TMP_Text)(object)val.emojiScreen, transform2, toFrame, Grow);
		extractionMini.haulCopy = CopyText((TMP_Text)(object)val.haulGoalScreen, transform2, toFrame, Grow);
		float num = (any ? Mathf.Max(new float[3]
		{
			((Bounds)(ref b)).size.x,
			((Bounds)(ref b)).size.y,
			((Bounds)(ref b)).size.z
		}) : 0f);
		Plugin.Log.LogInfo((object)$"Extraction Compass: copied {childCount} piece(s) from '{((Object)val).name}', {((Bounds)(ref b)).size.x:0.00} x {((Bounds)(ref b)).size.y:0.00} x {((Bounds)(ref b)).size.z:0.00} m.");
		if (!any || childCount == 0 || ((Bounds)(ref b)).size.y < 0.15f || num > 4f)
		{
			Plugin.Log.LogWarning((object)"Extraction Compass: the copied screen doesn't look right (no pieces, or the wrong size); the built-in dollar sign stays. Send the 'extraction point's pieces' list to fix the pick, or set ExtractionScreenParts.");
			Object.Destroy((Object)(object)val3);
			return null;
		}
		Vector3 val5 = (((Object)(object)val.emojiScreen != (Object)null) ? ((Matrix4x4)(ref toFrame)).MultiplyVector(-val.emojiScreen.transform.forward) : Vector3.forward);
		val5.y = 0f;
		Quaternion val6 = ((((Vector3)(ref val5)).sqrMagnitude > 0.0001f) ? Quaternion.FromToRotation(((Vector3)(ref val5)).normalized, Vector3.forward) : Quaternion.identity);
		float num2 = height / ((Bounds)(ref b)).size.y;
		Vector3 val7 = default(Vector3);
		((Vector3)(ref val7))..ctor(((Bounds)(ref b)).center.x, ((Bounds)(ref b)).min.y, ((Bounds)(ref b)).center.z);
		val3.transform.SetParent(parent, false);
		val3.transform.localRotation = val6;
		val3.transform.localScale = Vector3.one * num2;
		val3.transform.localPosition = val6 * (-val7 * num2);
		SetLayer(val3.transform, ((Component)parent).gameObject.layer);
		extractionMini.Sync();
		return extractionMini;
		void Grow(Bounds wb)
		{
			//IL_0006: 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_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_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			for (int j = 0; j < 8; j++)
			{
				Vector3 val8 = ((Bounds)(ref wb)).center + Vector3.Scale(((Bounds)(ref wb)).extents, new Vector3((float)(((j & 1) != 0) ? 1 : (-1)), (float)(((j & 2) != 0) ? 1 : (-1)), (float)(((j & 4) != 0) ? 1 : (-1))));
				Vector3 val9 = ((Matrix4x4)(ref toFrame)).MultiplyPoint3x4(val8);
				if (!any)
				{
					b = new Bounds(val9, Vector3.zero);
					any = true;
				}
				else
				{
					((Bounds)(ref b)).Encapsulate(val9);
				}
			}
		}
	}

	private static void Place(Transform t, Matrix4x4 m)
	{
		//IL_0004: Unknown result type (might be due to invalid IL or missing references)
		//IL_0009: Unknown result type (might be due to invalid IL or missing references)
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		t.localPosition = Vector4.op_Implicit(((Matrix4x4)(ref m)).GetColumn(3));
		t.localRotation = ((Matrix4x4)(ref m)).rotation;
		t.localScale = ((Matrix4x4)(ref m)).lossyScale;
	}

	private static TMP_Text CopyText(TMP_Text source, Transform parent, Matrix4x4 toFrame, Action<Bounds> grow)
	{
		//IL_0079: Unknown result type (might be due to invalid IL or missing references)
		//IL_0080: Expected O, but got Unknown
		//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cf: 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_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_0131: Unknown result type (might be due to invalid IL or missing references)
		//IL_0136: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_010f: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)source == (Object)null)
		{
			return null;
		}
		GameObject val = Object.Instantiate<GameObject>(((Component)source).gameObject, parent, false);
		((Object)val).name = ((Object)source).name;
		MonoBehaviour[] componentsInChildren = val.GetComponentsInChildren<MonoBehaviour>(true);
		foreach (MonoBehaviour val2 in componentsInChildren)
		{
			if ((Object)(object)val2 != (Object)null && !(val2 is TMP_Text) && !(val2 is TMP_SubMesh))
			{
				Object.DestroyImmediate((Object)(object)val2);
			}
		}
		foreach (Transform item in val.transform)
		{
			Transform val3 = item;
			if ((Object)(object)((Component)val3).GetComponent<TMP_SubMesh>() == (Object)null)
			{
				Object.Destroy((Object)(object)((Component)val3).gameObject);
			}
		}
		val.SetActive(true);
		Place(val.transform, toFrame * source.transform.localToWorldMatrix);
		Renderer component = ((Component)source).GetComponent<Renderer>();
		if ((Object)(object)component != (Object)null)
		{
			Bounds bounds = component.bounds;
			Vector3 size = ((Bounds)(ref bounds)).size;
			if (((Vector3)(ref size)).sqrMagnitude > 1E-06f)
			{
				grow(component.bounds);
				goto IL_0140;
			}
		}
		grow(new Bounds(source.transform.position, Vector3.one * 0.2f));
		goto IL_0140;
		IL_0140:
		return val.GetComponent<TMP_Text>();
	}

	private static List<Renderer> Pick(ExtractionPoint ep, out string report)
	{
		//IL_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0115: Unknown result type (might be due to invalid IL or missing references)
		//IL_011a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0121: Unknown result type (might be due to invalid IL or missing references)
		//IL_00af: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00be: 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_008a: Unknown result type (might be due to invalid IL or missing references)
		//IL_008f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0093: Unknown result type (might be due to invalid IL or missing references)
		//IL_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_03a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_03a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ab: Unknown result type (might be due to invalid IL or missing references)
		List<Renderer> list = new List<Renderer>();
		Transform transform = ((Component)ep).transform;
		string[] array = SplitList(Settings.CompassExtractionParts.Value);
		Bounds val = default(Bounds);
		((Bounds)(ref val))..ctor(ep.emojiScreen.transform.position, Vector3.one * 0.3f);
		TextMeshPro[] array2 = (TextMeshPro[])(object)new TextMeshPro[2] { ep.emojiScreen, ep.haulGoalScreen };
		Bounds bounds;
		for (int i = 0; i < array2.Length; i++)
		{
			TMP_Text val2 = (TMP_Text)(object)array2[i];
			if ((Object)(object)val2 == (Object)null)
			{
				continue;
			}
			Renderer component = ((Component)val2).GetComponent<Renderer>();
			? val3;
			if ((Object)(object)component != (Object)null)
			{
				bounds = component.bounds;
				Vector3 size = ((Bounds)(ref bounds)).size;
				if (((Vector3)(ref size)).sqrMagnitude > 1E-06f)
				{
					val3 = component.bounds;
					goto IL_00d1;
				}
			}
			val3 = new Bounds(val2.transform.position, Vector3.one * 0.3f);
			goto IL_00d1;
			IL_00d1:
			((Bounds)(ref val)).Encapsulate((Bounds)val3);
		}
		((Bounds)(ref val)).Expand(new Vector3(0.35f, 0.2f, 0.35f));
		((Bounds)(ref val)).SetMinMax(((Bounds)(ref val)).min - Vector3.up * 0.8f, ((Bounds)(ref val)).max);
		List<Transform> list2 = new List<Transform>();
		Transform[] array3 = (Transform[])(object)new Transform[12]
		{
			ep.spotlightHead1,
			ep.spotlightHead2,
			ep.extractionTube,
			ep.platform,
			ep.ramp,
			((Object)(object)ep.button != (Object)null) ? ((Component)ep.button).transform : null,
			ep.haulBar,
			((Object)(object)ep.hurtColliders != (Object)null) ? ep.hurtColliders.transform : null,
			((Object)(object)ep.extractionArea != (Object)null) ? ep.extractionArea.transform : null,
			((Object)(object)ep.grossUp != (Object)null) ? ep.grossUp.transform : null,
			((Object)(object)ep.emojiScreenGlitch != (Object)null) ? ep.emojiScreenGlitch.transform : null,
			((Object)(object)ep.roomVolume != (Object)null) ? ep.roomVolume.transform : null
		};
		foreach (Transform val4 in array3)
		{
			if ((Object)(object)val4 != (Object)null)
			{
				list2.Add(val4);
			}
		}
		array3 = (Transform[])(object)new Transform[2] { ep.spotlightHead1, ep.spotlightHead2 };
		foreach (Transform val5 in array3)
		{
			if ((Object)(object)val5 != (Object)null && (Object)(object)val5.parent != (Object)null && (Object)(object)val5.parent != (Object)(object)transform && !ep.emojiScreen.transform.IsChildOf(val5.parent))
			{
				list2.Add(val5.parent);
			}
		}
		StringBuilder stringBuilder = new StringBuilder("Extraction Compass: the extraction point's pieces (+ = on the compass; set [Compasses] ExtractionScreenParts to choose others):");
		MeshRenderer[] componentsInChildren = ((Component)transform).GetComponentsInChildren<MeshRenderer>(true);
		foreach (MeshRenderer val6 in componentsInChildren)
		{
			if ((Object)(object)val6 == (Object)null || (Object)(object)((Component)val6).GetComponent<TMP_Text>() != (Object)null || (Object)(object)((Component)val6).GetComponent<TMP_SubMesh>() != (Object)null)
			{
				continue;
			}
			string text = Path(((Component)val6).transform, transform);
			bool flag;
			if (array.Length != 0)
			{
				string text2 = text.ToLowerInvariant();
				flag = false;
				string[] array4 = array;
				foreach (string value in array4)
				{
					if (text2.Contains(value))
					{
						flag = true;
						break;
					}
				}
			}
			else
			{
				int num;
				if (((Renderer)val6).enabled && ((Component)val6).gameObject.activeInHierarchy)
				{
					bounds = ((Renderer)val6).bounds;
					num = (((Bounds)(ref val)).Contains(((Bounds)(ref bounds)).center) ? 1 : 0);
				}
				else
				{
					num = 0;
				}
				flag = (byte)num != 0;
				foreach (Transform item in list2)
				{
					if ((Object)(object)((Component)val6).transform == (Object)(object)item || ((Component)val6).transform.IsChildOf(item))
					{
						flag = false;
						break;
					}
				}
			}
			if (flag)
			{
				list.Add((Renderer)(object)val6);
			}
			stringBuilder.Append("\n  ").Append(flag ? "+ " : "- ").Append(text);
		}
		report = stringBuilder.ToString();
		return list;
	}

	private void Update()
	{
		if (Time.time >= nextSync)
		{
			Sync();
		}
	}

	private void Sync()
	{
		nextSync = Time.time + 0.5f;
		if ((Object)(object)emojiCopy != (Object)null && (Object)(object)emojiSource != (Object)null && emojiCopy.text != emojiSource.text)
		{
			emojiCopy.text = emojiSource.text;
		}
		if ((Object)(object)haulCopy != (Object)null && (Object)(object)haulSource != (Object)null && haulCopy.text != haulSource.text)
		{
			haulCopy.text = haulSource.text;
		}
	}

	private static string[] SplitList(string s)
	{
		List<string> list = new List<string>();
		string[] array = (s ?? "").Split(',');
		for (int i = 0; i < array.Length; i++)
		{
			string text = array[i].Trim().ToLowerInvariant();
			if (text.Length > 0)
			{
				list.Add(text);
			}
		}
		return list.ToArray();
	}

	private static string Path(Transform t, Transform root)
	{
		string text = ((Object)t).name;
		t = t.parent;
		while ((Object)(object)t != (Object)null && (Object)(object)t != (Object)(object)root)
		{
			text = ((Object)t).name + "/" + text;
			t = t.parent;
		}
		return text;
	}

	private static void SetLayer(Transform t, int layer)
	{
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: Expected O, but got Unknown
		((Component)t).gameObject.layer = layer;
		foreach (Transform item in t)
		{
			SetLayer(item, layer);
		}
	}
}
internal static class MeshLibrary
{
	internal class Part
	{
		public string MaterialName;

		public Color Color;

		public float Smoothness;

		public float Metallic;
	}

	internal class Model
	{
		public string Name;

		public Mesh Mesh;

		public List<Part> Parts = new List<Part>();
	}

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

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

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

	internal static Model Get(string file, string objectName)
	{
		if (!cache.TryGetValue(file, out var value))
		{
			value = (cache[file] = Load(file));
		}
		if (value == null || !value.TryGetValue(objectName, out var value2))
		{
			return null;
		}
		return value2;
	}

	private static Dictionary<string, Model> Load(string file)
	{
		//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0102: 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_01da: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e9: Expected O, but got Unknown
		//IL_0159: Unknown result type (might be due to invalid IL or missing references)
		//IL_0177: Unknown result type (might be due to invalid IL or missing references)
		string text = "HatterValuablesPack.Assets." + file;
		using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(text);
		if (stream == null)
		{
			Plugin.Log.LogError((object)("Embedded model '" + text + "' is missing."));
			return null;
		}
		using BinaryReader binaryReader = new BinaryReader(stream);
		if (Encoding.ASCII.GetString(binaryReader.ReadBytes(4)) != "HWM1")
		{
			Plugin.Log.LogError((object)("'" + file + "' is not a HWM1 model."));
			return null;
		}
		Dictionary<string, Model> dictionary = new Dictionary<string, Model>();
		int num = binaryReader.ReadInt32();
		for (int i = 0; i < num; i++)
		{
			Model model = new Model
			{
				Name = ReadString(binaryReader)
			};
			List<Vector3> list = new List<Vector3>();
			List<Vector3> list2 = new List<Vector3>();
			List<int[]> list3 = new List<int[]>();
			int num2 = binaryReader.ReadInt32();
			for (int j = 0; j < num2; j++)
			{
				Part part = new Part
				{
					MaterialName = ReadString(binaryReader)
				};
				part.Color = new Color(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle());
				part.Smoothness = binaryReader.ReadSingle();
				part.Metallic = binaryReader.ReadSingle();
				model.Parts.Add(part);
				int count = list.Count;
				int num3 = binaryReader.ReadInt32();
				for (int k = 0; k < num3; k++)
				{
					list.Add(new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()));
					list2.Add(new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()));
				}
				int num4 = binaryReader.ReadInt32();
				int[] array = new int[num4];
				for (int l = 0; l < num4; l++)
				{
					array[l] = binaryReader.ReadInt32() + count;
				}
				list3.Add(array);
			}
			Mesh val = new Mesh
			{
				name = model.Name
			};
			if (list.Count > 65000)
			{
				val.indexFormat = (IndexFormat)1;
			}
			val.SetVertices(list);
			val.SetNormals(list2);
			val.subMeshCount = list3.Count;
			for (int m = 0; m < list3.Count; m++)
			{
				val.SetTriangles(list3[m], m, false);
			}
			val.RecalculateBounds();
			val.UploadMeshData(false);
			model.Mesh = val;
			dictionary[model.Name] = model;
		}
		return dictionary;
	}

	private static string ReadString(BinaryReader r)
	{
		return Encoding.UTF8.GetString(r.ReadBytes(r.ReadInt32()));
	}

	internal static GameObject Attach(Model model, Transform parent, string name, Material template, Vector3 localPosition = default(Vector3))
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Expected O, but got Unknown
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject(name);
		val.transform.SetParent(parent, false);
		val.transform.localPosition = localPosition;
		val.layer = ((Component)parent).gameObject.layer;
		val.AddComponent<MeshFilter>().sharedMesh = model.Mesh;
		MeshRenderer val2 = val.AddComponent<MeshRenderer>();
		Material[] array = (Material[])(object)new Material[model.Parts.Count];
		for (int i = 0; i < array.Length; i++)
		{
			array[i] = MakeMaterial(template, model.Parts[i]);
		}
		((Renderer)val2).sharedMaterials = array;
		return val;
	}

	internal static Material MaterialFor(Material template, string name, Color color, float smoothness, float metallic)
	{
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_000f: Unknown result type (might be due to invalid IL or missing references)
		return MakeMaterial(template, new Part
		{
			MaterialName = name,
			Color = color,
			Smoothness = smoothness,
			Metallic = metallic
		});
	}

	private static Material MakeMaterial(Material template, Part part)
	{
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_0053: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: Unknown result type (might be due to invalid IL or missing references)
		//IL_006a: Expected O, but got Unknown
		//IL_0118: Unknown result type (might be due to invalid IL or missing references)
		//IL_0110: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bc: Expected O, but got Unknown
		//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d2: 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_00de: Unknown result type (might be due to invalid IL or missing references)
		//IL_011e: Expected O, but got Unknown
		//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_0223: Unknown result type (might be due to invalid IL or missing references)
		//IL_0229: Unknown result type (might be due to invalid IL or missing references)
		if (materialCache.TryGetValue(part.MaterialName, out var value))
		{
			return value;
		}
		if (part.MaterialName.StartsWith("Glass"))
		{
			Shader val = Shader.Find("Sprites/Default");
			if ((Object)(object)val != (Object)null)
			{
				Material val2 = new Material(val)
				{
					name = part.MaterialName,
					color = part.Color,
					renderQueue = 3000
				};
				materialCache[part.MaterialName] = val2;
				return val2;
			}
		}
		if (part.MaterialName.StartsWith("Glow"))
		{
			Shader val3 = Shader.Find("Sprites/Default");
			if ((Object)(object)val3 != (Object)null)
			{
				Material val4 = new Material(val3)
				{
					name = part.MaterialName
				};
				Color color = part.Color;
				color.a = 1f;
				val4.color = Color.Lerp(color, Color.white, 0.15f);
				materialCache[part.MaterialName] = val4;
				return val4;
			}
		}
		Material val5 = (((Object)(object)template != (Object)null) ? new Material(template) : new Material(Shader.Find("Standard")));
		((Object)val5).name = part.MaterialName;
		string[] array = new string[6] { "_MainTex", "_BaseMap", "_BumpMap", "_MetallicGlossMap", "_EmissionMap", "_OcclusionMap" };
		foreach (string text in array)
		{
			if (val5.HasProperty(text))
			{
				val5.SetTexture(text, (Texture)null);
			}
		}
		array = new string[2] { "_Color", "_BaseColor" };
		foreach (string text2 in array)
		{
			if (val5.HasProperty(text2))
			{
				val5.SetColor(text2, part.Color);
			}
		}
		float value2;
		float num = (part.MaterialName.StartsWith("Glow") ? 2.5f : (SelfLit.TryGetValue(part.MaterialName, out value2) ? value2 : 0f));
		if (val5.HasProperty("_EmissionColor"))
		{
			val5.SetColor("_EmissionColor", part.Color * num);
		}
		if (num > 0f)
		{
			val5.EnableKeyword("_EMISSION");
			val5.globalIlluminationFlags = (MaterialGlobalIlluminationFlags)1;
		}
		if (val5.HasProperty("_Metallic"))
		{
			val5.SetFloat("_Metallic", part.Metallic);
		}
		array = new string[2] { "_Smoothness", "_Glossiness" };
		foreach (string text3 in array)
		{
			if (val5.HasProperty(text3))
			{
				val5.SetFloat(text3, part.Smoothness);
			}
		}
		materialCache[part.MaterialName] = val5;
		return val5;
	}
}
[HarmonyPatch(typeof(PhysGrabObject), "Start")]
internal static class MidPointPatch
{
	private static bool logged;

	private static void Postfix(PhysGrabObject __instance)
	{
		//IL_0063: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_0075: 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_007f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0086: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: 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)
		if ((Object)(object)__instance == (Object)null)
		{
			return;
		}
		Compass component = ((Component)__instance).GetComponent<Compass>();
		if (!((Object)(object)component == (Object)null))
		{
			if (!logged)
			{
				logged = true;
				Plugin.Log.LogInfo((object)($"Compass value tag: the game measured its middle at {__instance.midPointOffset} (local), " + $"set to the model's middle {component.modelCentre}."));
			}
			__instance.midPointOffset = component.modelCentre;
			__instance.midPoint = ((Component)__instance).transform.TransformPoint(component.modelCentre);
			__instance.centerPoint = __instance.midPoint;
		}
	}
}
public class Nuke : MonoBehaviour
{
	public Transform modelRoot;

	private const float HitGap = 0.5f;

	private const float SpawnGrace = 4f;

	private PhotonView view;

	private PhysGrabObject grab;

	private float spawnedAt;

	private float lastCountedHit = -10f;

	private int hits;

	private bool armed;

	private bool detonated;

	private NukeSmoke smoke;

	private AudioSource alarm;

	private static bool Debug => Settings.NukeDebugLog.Value;

	internal Vector3 Centre
	{
		get
		{
			//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_0014: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)modelRoot != (Object)null))
			{
				return ((Component)this).transform.position;
			}
			return modelRoot.TransformPoint(NukeBuilder.BlastCentre);
		}
	}

	private void Awake()
	{
		view = ((Component)this).GetComponent<PhotonView>();
		grab = ((Component)this).GetComponent<PhysGrabObject>();
		spawnedAt = Time.time;
	}

	internal void HostHeavyImpact(float force)
	{
		if (armed || detonated || !SemiFunc.IsMasterClientOrSingleplayer())
		{
			return;
		}
		if (Time.time - spawnedAt < 4f)
		{
			if (Debug)
			{
				Plugin.Log.LogInfo((object)$"A-Bomb: heavy hit {force:0} ignored (just spawned).");
			}
			return;
		}
		if (force >= Settings.NukeInstantArmForce.Value)
		{
			Plugin.Log.LogInfo((object)$"A-Bomb: hit {force:0} >= {Settings.NukeInstantArmForce.Value:0}: armed at once.");
			Arm();
			return;
		}
		if (force < Settings.NukeHeavyHitForce.Value)
		{
			if (Debug)
			{
				Plugin.Log.LogInfo((object)$"A-Bomb: hit {force:0}, below HeavyHitForce.");
			}
			return;
		}
		if (Time.time - lastCountedHit < 0.5f)
		{
			if (Debug)
			{
				Plugin.Log.LogInfo((object)$"A-Bomb: hit {force:0} (same landing).");
			}
			return;
		}
		lastCountedHit = Time.time;
		hits++;
		Plugin.Log.LogInfo((object)$"A-Bomb: heavy hit {force:0}, {hits}/{Settings.NukeHitsToArm.Value}.");
		if (hits >= Settings.NukeHitsToArm.Value)
		{
			Arm();
		}
	}

	private void Arm()
	{
		if (!armed)
		{
			if (SemiFunc.IsMultiplayer())
			{
				view.RPC("NukeArmRPC", (RpcTarget)0, Array.Empty<object>());
			}
			else
			{
				NukeArmRPC();
			}
			((MonoBehaviour)this).StartCoroutine(Fuse());
		}
	}

	[PunRPC]
	public void NukeArmRPC()
	{
		if (!armed)
		{
			armed = true;
			if (Debug)
			{
				Plugin.Log.LogInfo((object)$"A-Bomb: armed, {Settings.NukeFuseSeconds.Value:0.#} s to go.");
			}
			if ((Object)(object)modelRoot != (Object)null)
			{
				smoke = NukeSmoke.Attach(modelRoot, Settings.NukeFuseSeconds.Value);
			}
			alarm = NukeSounds.PlayAlarm(((Object)(object)modelRoot != (Object)null) ? modelRoot : ((Component)this).transform, Settings.NukeFuseSeconds.Value);
		}
	}

	private IEnumerator Fuse()
	{
		yield return (object)new WaitForSeconds(Settings.NukeFuseSeconds.Value);
		if (!((Object)(object)this == (Object)null) && !detonated)
		{
			Detonate();
		}
	}

	private void Detonate()
	{
		//IL_0008: 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_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_0064: Unknown result type (might be due to invalid IL or missing references)
		detonated = true;
		Vector3 centre = Centre;
		Plugin.Log.LogInfo((object)$"A-Bomb: detonating at {centre}.");
		try
		{
			NukeBlast.HostApply(this, centre);
		}
		catch (Exception arg)
		{
			Plugin.Log.LogError((object)$"A-Bomb: blast failed: {arg}");
		}
		if (SemiFunc.IsMultiplayer())
		{
			view.RPC("NukeDetonateRPC", (RpcTarget)0, new object[1] { centre });
		}
		else
		{
			NukeDetonateRPC(centre);
		}
		try
		{
			PhysGrabObjectImpactDetector componentInChildren = ((Component)this).GetComponentInChildren<PhysGrabObjectImpactDetector>();
			if ((Object)(object)componentInChildren != (Object)null)
			{
				componentInChildren.DestroyObject(false, true);
			}
			else if (SemiFunc.IsMultiplayer())
			{
				PhotonNetwork.Destroy(((Component)this).gameObject);
			}
			else
			{
				Object.Destroy((Object)(object)((Component)this).gameObject);
			}
		}
		catch (Exception arg2)
		{
			Plugin.Log.LogWarning((object)$"A-Bomb: removing the bomb failed: {arg2}");
		}
	}

	[PunRPC]
	public void NukeDetonateRPC(Vector3 centre)
	{
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		detonated = true;
		if ((Object)(object)smoke != (Object)null)
		{
			smoke.Detach();
		}
		smoke = null;
		StopAlarm();
		if ((Object)(object)modelRoot != (Object)null)
		{
			((Component)modelRoot).gameObject.SetActive(false);
		}
		NukeFx.Explode(centre);
	}

	private void OnDestroy()
	{
		try
		{
			if ((Object)(object)smoke != (Object)null)
			{
				smoke.Detach();
			}
		}
		catch (Exception)
		{
		}
		StopAlarm();
	}

	private void StopAlarm()
	{
		try
		{
			if ((Object)(object)alarm != (Object)null)
			{
				alarm.Stop();
			}
		}
		catch (Exception)
		{
		}
		alarm = null;
	}
}
internal static class NukeBlast
{
	private static readonly FieldInfo PlayerDisabled = AccessTools.Field(typeof(PlayerAvatar), "isDisabled");

	private static readonly FieldInfo PlayerDead = AccessTools.Field(typeof(PlayerAvatar), "deadSet");

	private static readonly FieldInfo ValuableRooms = AccessTools.Field(typeof(ValuableObject), "roomVolumeCheck");

	private static readonly FieldInfo GrabDetector = AccessTools.Field(typeof(PhysGrabObject), "impactDetector");

	private static readonly FieldInfo ValuableGrab = AccessTools.Field(typeof(ValuableObject), "physGrabObject");

	private static readonly FieldInfo SpawnedField = AccessTools.Field(typeof(EnemyParent), "Spawned");

	private static readonly FieldInfo ParentEnemyField = AccessTools.Field(typeof(EnemyParent), "Enemy");

	private static readonly FieldInfo HealthField = AccessTools.Field(typeof(Enemy), "Health");

	private static readonly FieldInfo DeadField = AccessTools.Field(typeof(EnemyHealth), "dead");

	private static int roomMask = -1;

	private static bool Debug => Settings.NukeDebugLog.Value;

	private static int RoomMask
	{
		get
		{
			if (roomMask < 0)
			{
				return roomMask = LayerMask.GetMask(new string[1] { "RoomVolume" });
			}
			return roomMask;
		}
	}

	internal static Object Key(RoomVolume r)
	{
		if (!((Object)(object)r == (Object)null))
		{
			if (!((Object)(object)r.Module != (Object)null))
			{
				return (Object)(object)r;
			}
			return (Object)(object)r.Module;
		}
		return null;
	}

	internal static HashSet<Object> RoomsAt(Vector3 p, float radius = 0.3f)
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		HashSet<Object> hashSet = new HashSet<Object>();
		Collider[] array = Physics.OverlapSphere(p, radius, RoomMask, (QueryTriggerInteraction)2);
		for (int i = 0; i < array.Length; i++)
		{
			RoomVolume componentInParent = ((Component)array[i]).GetComponentInParent<RoomVolume>();
			if ((Object)(object)componentInParent != (Object)null)
			{
				hashSet.Add(Key(componentInParent));
			}
		}
		return hashSet;
	}

	internal static HashSet<Object> RoomsOf(RoomVolumeCheck check, Vector3 fallback)
	{
		//IL_0064: Unknown result type (might be due to invalid IL or missing references)
		//IL_0078: Unknown result type (might be due to invalid IL or missing references)
		HashSet<Object> hashSet = new HashSet<Object>();
		if ((Object)(object)check != (Object)null && check.CurrentRooms != null)
		{
			foreach (RoomVolume currentRoom in check.CurrentRooms)
			{
				if ((Object)(object)currentRoom != (Object)null)
				{
					hashSet.Add(Key(currentRoom));
				}
			}
		}
		if (hashSet.Count == 0)
		{
			hashSet = RoomsAt(fallback);
		}
		if (hashSet.Count == 0)
		{
			hashSet = RoomsAt(fallback, 2f);
		}
		return hashSet;
	}

	internal static Dictionary<Object, HashSet<Object>> BuildMap()
	{
		//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
		Dictionary<Object, HashSet<Object>> map = new Dictionary<Object, HashSet<Object>>();
		RoomVolume[] array = Object.FindObjectsByType<RoomVolume>((FindObjectsSortMode)0);
		RoomVolume[] array2 = array;
		for (int i = 0; i < array2.Length; i++)
		{
			Node(Key(array2[i]));
		}
		IEnumerable<LevelPoint> enumerable2;
		if (!((Object)(object)LevelGenerator.Instance != (Object)null) || LevelGenerator.Instance.LevelPathPoints == null || LevelGenerator.Instance.LevelPathPoints.Count <= 0)
		{
			IEnumerable<LevelPoint> enumerable = Object.FindObjectsByType<LevelPoint>((FindObjectsSortMode)0);
			enumerable2 = enumerable;
		}
		else
		{
			IEnumerable<LevelPoint> enumerable = LevelGenerator.Instance.LevelPathPoints;
			enumerable2 = enumerable;
		}
		int num = 0;
		foreach (LevelPoint item in enumerable2)
		{
			if ((Object)(object)item == (Object)null || (Object)(object)item.Room == (Object)null || item.ConnectedPoints == null)
			{
				continue;
			}
			foreach (LevelPoint connectedPoint in item.ConnectedPoints)
			{
				if ((Object)(object)connectedPoint != (Object)null && (Object)(object)connectedPoint.Room != (Object)null && Key(connectedPoint.Room) != Key(item.Room))
				{
					Link(Key(item.Room), Key(connectedPoint.Room));
					num++;
				}
			}
		}
		Dictionary<Object, List<Bounds>> dictionary = new Dictionary<Object, List<Bounds>>();
		array2 = array;
		foreach (RoomVolume obj in array2)
		{
			Object key = Key(obj);
			if (!dictionary.TryGetValue(key, out var value))
			{
				value = (dictionary[key] = new List<Bounds>());
			}
			Collider[] componentsInChildren = ((Component)obj).GetComponentsInChildren<Collider>(true);
			foreach (Collider val in componentsInChildren)
			{
				value.Add(val.bounds);
			}
		}
		int num2 = 0;
		foreach (KeyValuePair<Object, List<Bounds>> item2 in dictionary)
		{
			if (map[item2.Key].Count > 0)
			{
				continue;
			}
			foreach (KeyValuePair<Object, List<Bounds>> other in dictionary)
			{
				if (!(other.Key == item2.Key) && item2.Value.Any((Bounds a) => other.Value.Any(delegate(Bounds b)
				{
					//IL_0001: Unknown result type (might be due to invalid IL or missing references)
					//IL_0006: Unknown result type (might be due to invalid IL or missing references)
					//IL_0015: Unknown result type (might be due to invalid IL or missing references)
					Bounds val2 = a;
					((Bounds)(ref val2)).Expand(0.6f);
					return ((Bounds)(ref val2)).Intersects(b);
				})))
				{
					Link(item2.Key, other.Key);
					num2++;
				}
			}
		}
		if (Debug)
		{
			Plugin.Log.LogInfo((object)$"A-Bomb: room map: {map.Count} rooms, {num} path crossings, {num2} links by touching volumes.");
		}
		return map;
		void Link(Object a, Object b)
		{
			if (!(a == (Object)null) && !(b == (Object)null) && !(a == b))
			{
				Node(a);
				Node(b);
				map[a].Add(b);
				map[b].Add(a);
			}
		}
		void Node(Object a)
		{
			if (a != (Object)null && !map.ContainsKey(a))
			{
				map[a] = new HashSet<Object>();
			}
		}
	}

	internal static Dictionary<Object, int> Distances(Dictionary<Object, HashSet<Object>> map, HashSet<Object> start, int maxSteps)
	{
		Dictionary<Object, int> dictionary = new Dictionary<Object, int>();
		Queue<Object> queue = new Queue<Object>();
		foreach (Object item in start)
		{
			if (item != (Object)null && !dictionary.ContainsKey(item))
			{
				dictionary[item] = 0;
				queue.Enqueue(item);
			}
		}
		while (queue.Count > 0)
		{
			Object key = queue.Dequeue();
			if (dictionary[key] >= maxSteps || !map.TryGetValue(key, out var value))
			{
				continue;
			}
			foreach (Object item2 in value)
			{
				if (!dictionary.ContainsKey(item2))
				{
					dictionary[item2] = dictionary[key] + 1;
					queue.Enqueue(item2);
				}
			}
		}
		return dictionary;
	}

	internal static int StepsTo(Dictionary<Object, int> dist, HashSet<Object> rooms)
	{
		int num = int.MaxValue;
		foreach (Object room in rooms)
		{
			if (room != (Object)null && dist.TryGetValue(room, out var value) && value < num)
			{
				num = value;
			}
		}
		return num;
	}

	internal static HashSet<Object> BlastRooms(Vector3 centre)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: 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_006e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		HashSet<Object> hashSet = RoomsAt(centre, 0.5f);
		if (hashSet.Count > 0)
		{
			return hashSet;
		}
		hashSet = RoomsAt(centre, 3f);
		if (hashSet.Count > 0)
		{
			return hashSet;
		}
		LevelPoint val = null;
		float num = float.MaxValue;
		LevelPoint[] array = Object.FindObjectsByType<LevelPoint>((FindObjectsSortMode)0);
		foreach (LevelPoint val2 in array)
		{
			if (!((Object)(object)val2 == (Object)null) && !((Object)(object)val2.Room == (Object)null))
			{
				Vector3 val3 = ((Component)val2).transform.position - centre;
				float sqrMagnitude = ((Vector3)(ref val3)).sqrMagnitude;
				if (sqrMagnitude < num)
				{
					num = sqrMagnitude;
					val = val2;
				}
			}
		}
		if ((Object)(object)val != (Object)null)
		{
			hashSet.Add(Key(val.Room));
		}
		return hashSet;
	}

	internal static void HostApply(Nuke bomb, Vector3 centre)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0003: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_051b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0520: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cd: 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_020b: Unknown result type (might be due to invalid IL or missing references)
		//IL_020e: 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_0551: Unknown result type (might be due to invalid IL or missing references)
		//IL_0556: Unknown result type (might be due to invalid IL or missing references)
		//IL_0579: Unknown result type (might be due to invalid IL or missing references)
		//IL_0580: 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_03b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_03c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_03cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_03f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_03e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_0472: Unknown result type (might be due to invalid IL or missing references)
		//IL_0475: Unknown result type (might be due to invalid IL or missing references)
		//IL_047a: Unknown result type (might be due to invalid IL or missing references)
		//IL_047f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0483: Unknown result type (might be due to invalid IL or missing references)
		int killRooms = Settings.NukeKillRooms.Value;
		float minRadius = Settings.NukeMinKillRadius.Value;
		Dictionary<Object, HashSet<Object>> map = BuildMap();
		HashSet<Object> hashSet = BlastRooms(centre);
		Dictionary<Object, int> dist = Distances(map, hashSet, killRooms);
		if (Debug)
		{
			Plugin.Log.LogInfo((object)string.Format("A-Bomb: in {0} room(s) ({1}); {2} room(s) within {3}: {4}.", hashSet.Count, string.Join(", ", hashSet.Select(Name)), dist.Count, killRooms, string.Join(", ", dist.Select((KeyValuePair<Object, int> kv) => Name(kv.Key) + "=" + kv.Value))));
		}
		Vector3 val2;
		foreach (PlayerAvatar item in SemiFunc.PlayerGetList())
		{
			if ((Object)(object)item == (Object)null || !((Component)item).gameObject.activeInHierarchy || (PlayerDisabled != null && (bool)PlayerDisabled.GetValue(item)) || (PlayerDead != null && (bool)PlayerDead.GetValue(item)))
			{
				continue;
			}
			Vector3 val = (((Object)(object)item.PlayerVisionTarget != (Object)null && (Object)(object)item.PlayerVisionTarget.VisionTransform != (Object)null) ? item.PlayerVisionTarget.VisionTransform.position : ((Component)item).transform.position);
			HashSet<Object> rooms = RoomsOf(item.RoomVolumeCheck, val);
			bool flag = InRange(rooms, val);
			if (Debug)
			{
				ManualLogSource log = Plugin.Log;
				object[] obj = new object[4]
				{
					SemiFunc.PlayerGetName(item),
					Steps(dist, rooms),
					null,
					null
				};
				val2 = val - centre;
				obj[2] = ((Vector3)(ref val2)).magnitude;
				obj[3] = (flag ? "killed" : "safe");
				log.LogInfo((object)string.Format("A-Bomb: player '{0}' {1}, {2:0.0} m: {3}.", obj));
			}
			if (flag)
			{
				try
				{
					item.PlayerDeath(-1);
				}
				catch (Exception arg)
				{
					Plugin.Log.LogWarning((object)$"A-Bomb: killing a player failed: {arg}");
				}
			}
		}
		EnemyDirector instance = EnemyDirector.instance;
		if ((Object)(object)instance != (Object)null && instance.enemiesSpawned != null)
		{
			foreach (EnemyParent item2 in instance.enemiesSpawned.ToList())
			{
				if ((Object)(object)item2 == (Object)null || (SpawnedField != null && !(bool)SpawnedField.GetValue(item2)))
				{
					continue;
				}
				Enemy val3 = (Enemy)(((object)((ParentEnemyField != null) ? /*isinst with value type is only supported in some contexts*/: null)) ?? ((object)((Component)item2).GetComponentInChildren<Enemy>()));
				if ((Object)(object)val3 == (Object)null || !((Component)val3).gameObject.activeInHierarchy)
				{
					continue;
				}
				EnemyHealth val4 = (EnemyHealth)(((object)((HealthField != null) ? /*isinst with value type is only supported in some contexts*/: null)) ?? ((object)((Component)val3).GetComponentInChildren<EnemyHealth>()));
				if ((Object)(object)val4 == (Object)null || (DeadField != null && (bool)DeadField.GetValue(val4)))
				{
					continue;
				}
				Vector3 val5 = (((Object)(object)val3.CenterTransform != (Object)null) ? val3.CenterTransform.position : ((Component)val3).transform.position);
				HashSet<Object> hashSet2 = RoomsAt(val5);
				if (hashSet2.Count == 0)
				{
					hashSet2 = RoomsAt(val5, 2f);
				}
				bool flag2 = InRange(hashSet2, val5);
				if (Debug)
				{
					Plugin.Log.LogInfo((object)("A-Bomb: enemy '" + ((Object)item2).name + "' " + Steps(dist, hashSet2) + ": " + (flag2 ? "killed" : "safe") + "."));
				}
				if (flag2)
				{
					try
					{
						val2 = val5 - centre;
						val4.Hurt(99999, ((Vector3)(ref val2)).normalized);
					}
					catch (Exception arg2)
					{
						Plugin.Log.LogWarning((object)$"A-Bomb: killing an enemy failed: {arg2}");
					}
				}
			}
		}
		int num = 0;
		ValuableObject[] array = Object.FindObjectsByType<ValuableObject>((FindObjectsSortMode)0);
		foreach (ValuableObject val6 in array)
		{
			if ((Object)(object)val6 == (Object)null || (Object)(object)((Component)val6).gameObject == (Object)(object)((Component)bomb).gameObject || !((Component)val6).gameObject.activeInHierarchy)
			{
				continue;
			}
			Vector3 val7 = ((Component)val6).transform.position;
			PhysGrabObject val8 = (PhysGrabObject)((ValuableGrab != null) ? /*isinst with value type is only supported in some contexts*/: null);
			if ((Object)(object)val8 != (Object)null)
			{
				val7 = val8.centerPoint;
			}
			if (!InRange(RoomsOf((RoomVolumeCheck)((ValuableRooms != null) ? /*isinst with value type is only supported in some contexts*/: null), val7), val7))
			{
				continue;
			}
			PhysGrabObjectImpactDetector val9 = (PhysGrabObjectImpactDetector)(((object)(((Object)(object)val8 != (Object)null && GrabDetector != null) ? /*isinst with value type is only supported in some contexts*/: null)) ?? ((object)((Component)val6).GetComponent<PhysGrabObjectImpactDetector>()));
			if (!((Object)(object)val9 == (Object)null))
			{
				try
				{
					val9.DestroyObject(true, true);
					num++;
				}
				catch (Exception arg3)
				{
					Plugin.Log.LogWarning((object)$"A-Bomb: destroying '{((Object)val6).name}' failed: {arg3}");
				}
			}
		}
		if (Debug)
		{
			Plugin.Log.LogInfo((object)$"A-Bomb: {num} valuable(s) destroyed.");
		}
		bool InRange(HashSet<Object> rooms2, Vector3 at)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			if (StepsTo(dist, rooms2) > killRooms)
			{
				if (minRadius > 0f)
				{
					Vector3 val10 = at - centre;
					return ((Vector3)(ref val10)).sqrMagnitude <= minRadius * minRadius;
				}
				return false;
			}
			return true;
		}
	}

	private static string Steps(Dictionary<Object, int> dist, HashSet<Object> rooms)
	{
		int num = StepsTo(dist, rooms);
		if (rooms.Count != 0)
		{
			if (num != int.MaxValue)
			{
				return $"{num} room(s) away";
			}
			return "out of reach (" + string.Join(", ", rooms.Select(Name)) + ")";
		}
		return "in no room";
	}

	internal static string Name(Object o)
	{
		if (!(o == (Object)null))
		{
			return o.name;
		}
		return "?";
	}
}
internal static class NukeBuilder
{
	internal const string DisplayName = "A-Bomb";

	internal const string PrefabName = "Valuable Hatter A-Bomb";

	private const string PianoPath = "Valuables/05 Wide/Valuable Manor Piano";

	private static readonly string[] MetalSoundFrom = new string[3] { "Valuables/03 Medium/Valuable Arctic Propane Tank", "Valuables/04 Big/Valuable Arctic Barrel", "Valuables/03 Medium/Valuable Arctic Fire Extinguisher" };

	internal const float ModelLength = 2.25f;

	internal static PrefabRef Registered;

	private static GameObject holder;

	private static readonly (Vector3 centre, Vector3 size)[] ModelBoxes = new(Vector3, Vector3)[6]
	{
		(U(0.42f, 0f, 0.68f), S(1.25f, 0.98f, 0.98f)),
		(U(1f, 0f, 0.68f), S(0.25f, 0.62f, 0.62f)),
		(U(-0.33f, 0f, 0.68f), S(0.2f, 0.62f, 0.62f)),
		(U(-0.55f, 0f, 0.68f), S(0.26f, 0.36f, 0.36f)),
		(U(-0.9f, 0f, 0.68f), S(0.45f, 1.03f, 1.03f)),
		(U(0.38f, 0f, 0.12f), S(1f, 0.64f, 0.24f))
	};

	internal static readonly Vector3[] SmokePoints = (Vector3[])(object)new Vector3[5]
	{
		U(0.91f, 0f, 1.08f),
		U(0.91f, 0.38f, 0.85f),
		U(0.91f, -0.38f, 0.85f),
		U(-0.55f, 0f, 0.86f),
		U(0.23f, 0f, 1.2f)
	};

	internal static readonly Vector3 BlastCentre = U(0.35f, 0f, 0.68f);

	internal static bool Is(PrefabRef p)
	{
		if (p != null && Registered != null)
		{
			if (p != Registered)
			{
				return ((PrefabRef<GameObject>)(object)p).ResourcePath == ((PrefabRef<GameObject>)(object)Registered).ResourcePath;
			}
			return true;
		}
		return false;
	}

	private static Vector3 U(float bx, float by, float bz)
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		return new Vector3(0f - bx, bz, 0f - by);
	}

	private static Vector3 S(float sx, float sy, float sz)
	{
		//IL_0003: Unknown result type (might be due to invalid IL or missing references)
		return new Vector3(sx, sz, sy);
	}

	internal static GameObject Build()
	{
		//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_00be: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e6: 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_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: Expected O, but got Unknown
		//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0209: Unknown result type (might be due to invalid IL or missing references)
		//IL_0215: Unknown result type (might be due to invalid IL or missing references)
		//IL_025f: Unknown result type (might be due to invalid IL or missing references)
		//IL_028a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0296: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_02bc: 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: Unknown result type (might be due to invalid IL or missing references)
		//IL_02fb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0301: Unknown result type (might be due to invalid IL or missing references)
		//IL_03b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_03b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_03c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_03d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_03d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_03da: Unknown result type (might be due to invalid IL or missing references)
		//IL_03e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_03f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_03f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0451: Unknown result type (might be due to invalid IL or missing references)
		//IL_05fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0604: Expected O, but got Unknown
		//IL_061d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0627: Unknown result type (might be due to invalid IL or missing references)
		//IL_062c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0642: Unknown result type (might be due to invalid IL or missing references)
		//IL_064c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0651: Unknown result type (might be due to invalid IL or missing references)
		//IL_0668: Unknown result type (might be due to invalid IL or missing references)
		//IL_066d: Unknown result type (might be due to invalid IL or missing references)
		//IL_067e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0683: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = Resources.Load<GameObject>("Valuables/05 Wide/Valuable Manor Piano");
		if ((Object)(object)val == (Object)null)
		{
			Plugin.Log.LogError((object)"'Valuables/05 Wide/Valuable Manor Piano' not found; the A-Bomb can't be built.");
			return null;
		}
		MeshLibrary.Model model = MeshLibrary.Get("nuke.mesh", "Nuke");
		if (model == null)
		{
			return null;
		}
		if ((Object)(object)holder == (Object)null)
		{
			holder = new GameObject("HatterValuablesPack.PrefabHolder");
			holder.SetActive(false);
			Object.DontDestroyOnLoad((Object)(object)holder);
			((Object)holder).hideFlags = (HideFlags)61;
		}
		GameObject val2 = Object.Instantiate<GameObject>(val, holder.transform);
		((Object)val2).name = "Valuable Hatter A-Bomb";
		Transform transform = val2.transform;
		Bounds val3 = LocalMeshBounds(transform);
		Plugin.Log.LogInfo((object)string.Format("{0}: the piano measures {1:0.00} x {2:0.00} x {3:0.00} m (centre {4}).", "A-Bomb", ((Bounds)(ref val3)).size.x, ((Bounds)(ref val3)).size.y, ((Bounds)(ref val3)).size.z, ((Bounds)(ref val3)).center));
		LogComponents(val2);
		MusicalValuableLogic[] componentsInChildren = val2.GetComponentsInChildren<MusicalValuableLogic>(true);
		for (int i = 0; i < componentsInChildren.Length; i++)
		{
			Object.DestroyImmediate((Object)(object)componentsInChildren[i]);
		}
		PhysGrabObjectGrabArea[] componentsInChildren2 = val2.GetComponentsInChildren<PhysGrabObjectGrabArea>(true);
		for (int i = 0; i < componentsInChildren2.Length; i++)
		{
			Object.DestroyImmediate((Object)(object)componentsInChildren2[i]);
		}
		AudioSource[] componentsInChildren3 = val2.GetComponentsInChildren<AudioSource>(true);
		for (int i = 0; i < componentsInChildren3.Length; i++)
		{
			((Behaviour)componentsInChildren3[i]).enabled = false;
		}
		Material val4 = null;
		Renderer[] componentsInChildren4 = val2.GetComponentsInChildren<Renderer>(true);
		foreach (Renderer val5 in componentsInChildren4)
		{
			if ((Object)(object)val4 == (Object)null && val5 is MeshRenderer && (Object)(object)val5.sharedMaterial != (Object)null)
			{
				val4 = val5.sharedMaterial;
			}
			val5.enabled = false;
		}
		bool flag = ((Bounds)(ref val3)).size.z > ((Bounds)(ref val3)).size.x;
		float num = Mathf.Max(((Bounds)(ref val3)).size.x, ((Bounds)(ref val3)).size.z);
		if (num < 0.3f)
		{
			num = 1.6f;
			Plugin.Log.LogWarning((object)"A-Bomb: couldn't measure the piano; assuming 1.6 m.");
		}
		float num2 = Settings.NukeSizeVsPiano.Value * num / 2.25f;
		Transform transform2 = new GameObject("A-Bomb Model").transform;
		transform2.SetParent(transform, false);
		((Component)transform2).gameObject.layer = val2.layer;
		transform2.localPosition = new Vector3(((Bounds)(ref val3)).center.x, ((Bounds)(ref val3)).min.y, ((Bounds)(ref val3)).center.z);
		transform2.localRotation = (flag ? Quaternion.Euler(0f, 90f, 0f) : Quaternion.identity);
		transform2.localScale = Vector3.one * num2;
		MeshLibrary.Attach(model, transform2, "A-Bomb Mesh", val4).layer = val2.layer;
		Plugin.Log.LogInfo((object)string.Format("{0}: {1:0.00} m long (scale {2:0.000}), {3}; material from '{4}'.", "A-Bomb", 2.25f * num2, num2, flag ? "along Z" : "along X", ((Object)(object)val4 != (Object)null) ? (((Object)val4).name + " (" + ((Object)val4.shader).name + ")") : "none"));
		(Vector3, Quaternion, Vector3)[] array = new(Vector3, Quaternion, Vector3)[ModelBoxes.Length];
		for (int j = 0; j < ModelBoxes.Length; j++)
		{
			array[j] = (transform2.localPosition + transform2.localRotation * (ModelBoxes[j].centre * num2), transform2.localRotation, ModelBoxes[j].size * num2);
		}
		ReplaceColliders(transform, array);
		ValuableObject component = val2.GetComponent<ValuableObject>();
		if ((Object)(object)component == (Object)null)
		{
			Plugin.Log.LogError((object)"A-Bomb: the piano has no ValuableObject.");
			return null;
		}
		component.volumeType = (Type)4;
		Value val6 = ScriptableObject.CreateInstance<Value>();
		((Object)val6).name = "Valuable Hatter A-Bomb Value";
		val6.valueMin = Mathf.Min(Settings.NukeValueMin.Value, Settings.NukeValueMax.Value);
		val6.valueMax = Mathf.Max(Settings.NukeValueMin.Value, Settings.NukeValueMax.Value);
		component.valuePreset = val6;
		PhysAttribute val7 = ScriptableObject.CreateInstance<PhysAttribute>();
		((Object)val7).name = "Valuable Hatter A-Bomb Weight";
		float num3 = (((Object)(object)component.physAttributePreset != (Object)null) ? component.physAttributePreset.mass : 0f);
		val7.mass = ((num3 > 0f) ? num3 : 10f) * Settings.NukeWeightVsPiano.Value;
		component.physAttributePreset = val7;
		Durability val8 = ScriptableObject.CreateInstance<Durability>();
		((Object)val8).name = "Valuable Hatter A-Bomb Durability";
		val8.durability = 100f;
		val8.fragility = (((Object)(object)component.durabilityPreset != (Object)null) ? component.durabilityPreset.fragility : 50f);
		component.durabilityPreset = val8;
		PhysAudio val9 = null;
		string text = null;
		string[] metalSoundFrom = MetalSoundFrom;
		foreach (string text2 in metalSoundFrom)
		{
			GameObject obj = Resources.Load<GameObject>(text2);
			ValuableObject val10 = ((obj != null) ? obj.GetComponent<ValuableObject>() : null);
			if ((Object)(object)val10 != (Object)null && (Object)(object)val10.audioPreset != (Object)null)
			{
				val9 = val10.audioPreset;
				text = text2;
				break;
			}
		}
		if ((Object)(object)val9 != (Object)null)
		{
			component.audioPreset = val9;
			component.audioPresetPitch = 0.75f;
		}
		else
		{
			Plugin.Log.LogWarning((object)"A-Bomb: no metal impact sound found; it keeps the piano's.");
		}
		Gradient val11 = new Gradient();
		val11.SetKeys((GradientColorKey[])(object)new GradientColorKey[2]
		{
			new GradientColorKey(new Color(0.2f, 0.21f, 0.18f), 0f),
			new GradientColorKey(new Color(0.45f, 0.45f, 0.43f), 1f)
		}, (GradientAlphaKey[])(object)new GradientAlphaKey[2]
		{
			new GradientAlphaKey(1f, 0f),
			new GradientAlphaKey(1f, 1f)
		});
		component.particleColors = val11;
		val2.AddComponent<Nuke>().modelRoot = transform2;
		Plugin.Log.LogInfo((object)string.Format("{0}: ${1:0}–{2:0}, {3:0.0} kg (piano {4:0.0}), impact sound from '{5}'.", "A-Bomb", val6.valueMin, val6.valueMax, val7.mass, num3, text ?? "the piano"));
		return val2;
	}

	internal static Bounds LocalMeshBounds(Transform root)
	{
		//IL_0004: 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_0010: 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_005b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0076: Unknown result type (might be due to invalid IL or missing references)
		//IL_007b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0084: 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_00b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
		bool flag = false;
		Bounds result = default(Bounds);
		Matrix4x4 worldToLocalMatrix = root.worldToLocalMatrix;
		MeshFilter[] componentsInChildren = ((Component)root).GetComponentsInChildren<MeshFilter>(true);
		foreach (MeshFilter val in componentsInChildren)
		{
			if ((Object)(object)val.sharedMesh == (Object)null)
			{
				continue;
			}
			MeshRenderer component = ((Component)val).GetComponent<MeshRenderer>();
			if ((Object)(object)component == (Object)null || !((Renderer)component).enabled)
			{
				continue;
			}
			Matrix4x4 val2 = worldToLocalMatrix * ((Component)val).transform.localToWorldMatrix;
			Bounds bounds = val.sharedMesh.bounds;
			for (int j = 0; j < 8; j++)
			{
				Vector3 val3 = ((Bounds)(ref bounds)).center + Vector3.Scale(((Bounds)(ref bounds)).extents, new Vector3((float)(((j & 1) != 0) ? 1 : (-1)), (float)(((j & 2) != 0) ? 1 : (-1)), (float)(((j & 4) != 0) ? 1 : (-1))));
				Vector3 val4 = ((Matrix4x4)(ref val2)).MultiplyPoint3x4(val3);
				if (!flag)
				{
					((Bounds)(ref result))..ctor(val4, Vector3.zero);
					flag = true;
				}
				else
				{
					((Bounds)(ref result)).Encapsulate(val4);
				}
			}
		}
		return result;
	}

	internal static void LogComponents(GameObject go, string label = "A-Bomb", string source = "the piano")
	{
		StringBuilder stringBuilder = new StringBuilder(label + ": " + source + "'s parts:");
		Transform[] componentsInChildren = go.GetComponentsInChildren<Transform>(true);
		foreach (Transform val in componentsInChildren)
		{
			List<string> list = new List<string>();
			Component[] components = ((Component)val).GetComponents<Component>();
			foreach (Component val2 in components)
			{
				if ((Object)(object)val2 != (Object)null && !(val2 is Transform))
				{
					list.Add(((object)val2).GetType().Name);
				}
			}
			stringBuilder.Append("\n  " + ((Object)val).name + ": " + string.Join(", ", list));
		}
		Plugin.Log.LogInfo((object)stringBuilder.ToString());
	}

	internal static void ReplaceColliders(Transform root, (Vector3 centre, Quaternion rotation, Vector3 size)[] boxes, string label = "A-Bomb", string source = "the piano")
	{
		//IL_02ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_02cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_02dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f4: Unknown result type (might be due to invalid IL or missing references)
		//IL_0306: Unknown