Decompiled source of SonicScrewdriver v0.5.0

sonic.dll

Decompiled 2 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text.RegularExpressions;
using BepInEx;
using HarmonyLib;
using Photon.Pun;
using TARDISMod;
using UnityEngine;
using UnityEngine.Audio;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("sonic")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("sonic")]
[assembly: AssemblyCopyright("Copyright ©  2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("98f6da0c-f28e-4d99-a81d-92f0e99ae946")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
[BepInPlugin("com.feralelf.sonic", "sonic", "1.0.0")]
public class TARDISModPlugin : BaseUnityPlugin
{
	private void Awake()
	{
		SonicShopInjection.Initialize();
		((BaseUnityPlugin)this).Logger.LogInfo((object)"sonic Initialized!");
	}
}
public static class SonicShopInjection
{
	[HarmonyPatch]
	public static class Patch_DefaultPool_Sonic
	{
		[HarmonyPatch(typeof(DefaultPool), "Instantiate", new Type[]
		{
			typeof(string),
			typeof(Vector3),
			typeof(Quaternion)
		})]
		[HarmonyPrefix]
		public static bool PrefixInstantiate(string prefabId, Vector3 position, Quaternion rotation, ref GameObject __result)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			if (prefabId == "TARDISMod/SonicScrewdriver" && (Object)(object)sonicScrewdriverPrefab != (Object)null)
			{
				__result = Object.Instantiate<GameObject>(sonicScrewdriverPrefab, position, rotation);
				return false;
			}
			return true;
		}
	}

	[HarmonyPatch]
	public static class Patch_StatsManager_RunStartStats
	{
		private static MethodBase TargetMethod()
		{
			return FindTypeBySimpleName("StatsManager")?.GetMethod("RunStartStats", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
		}

		private static void Postfix()
		{
			RegisterItemStatsKeys();
		}
	}

	[HarmonyPatch]
	public static class Patch_ItemAttributes_Awake
	{
		private static MethodBase TargetMethod()
		{
			return FindTypeBySimpleName("ItemAttributes")?.GetMethod("Awake", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
		}

		private static void Prefix(object __instance)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			if (__instance == null)
			{
				return;
			}
			RegisterItem();
			Component val = (Component)__instance;
			if (((Object)val.gameObject).name.Contains("SonicScrewdriver"))
			{
				Type type = __instance.GetType();
				FieldInfo field = type.GetField("item", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (field != null && (Object)(object)sonicItemDefinition != (Object)null)
				{
					field.SetValue(__instance, sonicItemDefinition);
				}
				FieldInfo field2 = type.GetField("value", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (field2 != null)
				{
					field2.SetValue(__instance, 15000);
				}
			}
		}
	}

	[HarmonyPatch]
	public static class Patch_RunManager_Awake
	{
		private static MethodBase TargetMethod()
		{
			return FindTypeBySimpleName("RunManager")?.GetMethod("Awake", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
		}

		private static void Postfix(object __instance)
		{
			RegisterItem();
			if (!((Object)(object)sonicScrewdriverPrefab != (Object)null))
			{
				return;
			}
			FieldInfo field = __instance.GetType().GetField("singleplayerPool", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field != null)
			{
				object value = field.GetValue(__instance);
				if (value is Dictionary<string, GameObject> dictionary && !dictionary.ContainsKey("TARDISMod/SonicScrewdriver"))
				{
					dictionary.Add("TARDISMod/SonicScrewdriver", sonicScrewdriverPrefab);
					Debug.Log((object)"[sonic] Prefab injected into RunManager Singleplayer Pool using key: TARDISMod/SonicScrewdriver");
				}
			}
		}
	}

	[HarmonyPatch]
	public static class Patch_ShopManager_GetAllItems
	{
		private static MethodBase TargetMethod()
		{
			return FindTypeBySimpleName("ShopManager")?.GetMethod("GetAllItemsFromStatsManager", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
		}

		private static void Postfix(object __instance)
		{
			RegisterItem();
			FieldInfo field = __instance.GetType().GetField("potentialItems", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (!(field != null))
			{
				return;
			}
			object value = field.GetValue(__instance);
			if (!(value is IList list))
			{
				return;
			}
			Type type = FindTypeBySimpleName("StatsManager");
			object obj = type?.GetField("instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(null);
			object obj2 = type?.GetField("itemDictionary", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(obj);
			if (obj2 is IDictionary dictionary && dictionary.Contains("SonicScrewdriver"))
			{
				object obj3 = dictionary["SonicScrewdriver"];
				if (obj3 != null && !list.Contains(obj3))
				{
					list.Add(obj3);
					Debug.Log((object)"[sonic] Sonic Screwdriver added to Shop potential items.");
				}
			}
		}
	}

	public static ScriptableObject sonicItemDefinition;

	private static AssetBundle assetBundle;

	public static GameObject sonicScrewdriverPrefab;

	public static AudioClip sonicSound;

	public static GameObject arcticDoorBlockedPrefab;

	public static GameObject manorDoorBlockedPrefab;

	public static GameObject wizardDoorBlockedPrefab;

	public static AudioClip heavyLockSound;

	public static AudioClip arcticLockSound;

	public const string SONIC_PREFAB_PATH = "TARDISMod/SonicScrewdriver";

	public static void Initialize()
	{
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Expected O, but got Unknown
		LoadAssets();
		Harmony val = new Harmony("com.feralelf.sonic");
		val.PatchAll();
	}

	public static void LoadAssets()
	{
		if ((Object)(object)assetBundle != (Object)null)
		{
			return;
		}
		string text = Path.Combine(Paths.PluginPath, "FeralElf-Dr_Who-0.5.2", "sonic");
		if (!File.Exists(text))
		{
			string[] files = Directory.GetFiles(Paths.PluginPath, "sonic", SearchOption.AllDirectories);
			if (files.Length != 0)
			{
				text = files[0];
			}
		}
		assetBundle = AssetBundle.GetAllLoadedAssetBundles().FirstOrDefault((Func<AssetBundle, bool>)((AssetBundle b) => ((Object)b).name == "sonic"));
		if ((Object)(object)assetBundle == (Object)null && File.Exists(text))
		{
			assetBundle = AssetBundle.LoadFromFile(text);
		}
		if ((Object)(object)assetBundle == (Object)null)
		{
			Debug.LogError((object)("[sonic] Failed to load AssetBundle from " + text));
			return;
		}
		sonicSound = assetBundle.LoadAsset<AudioClip>("sonic");
		sonicScrewdriverPrefab = assetBundle.LoadAsset<GameObject>("SonicScrewdriver");
		arcticDoorBlockedPrefab = assetBundle.LoadAsset<GameObject>("Arctic Door Blocked");
		manorDoorBlockedPrefab = assetBundle.LoadAsset<GameObject>("Manor Door Blocked");
		wizardDoorBlockedPrefab = assetBundle.LoadAsset<GameObject>("Wizard Door Blocked");
		heavyLockSound = assetBundle.LoadAsset<AudioClip>("Heavy lock");
		arcticLockSound = assetBundle.LoadAsset<AudioClip>("Very heavy");
		if ((Object)(object)sonicScrewdriverPrefab != (Object)null && (Object)(object)sonicScrewdriverPrefab.GetComponent<GrabReact>() == (Object)null)
		{
			sonicScrewdriverPrefab.AddComponent<GrabReact>();
		}
		if ((Object)(object)sonicScrewdriverPrefab.GetComponent<PhotonView>() == (Object)null)
		{
			sonicScrewdriverPrefab.AddComponent<PhotonView>();
		}
		Debug.Log((object)"[sonic] Assets loaded successfully.");
	}

	public static Type FindTypeBySimpleName(string simpleName)
	{
		Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
		foreach (Assembly assembly in assemblies)
		{
			try
			{
				Type type = assembly.GetTypes().FirstOrDefault((Type x) => x.Name == simpleName || (x.FullName?.EndsWith("." + simpleName) ?? false));
				if (type != null)
				{
					return type;
				}
			}
			catch
			{
			}
		}
		return null;
	}

	public static void RegisterItem()
	{
		//IL_016e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0178: Expected O, but got Unknown
		if ((Object)(object)sonicScrewdriverPrefab == (Object)null)
		{
			return;
		}
		Type type = FindTypeBySimpleName("StatsManager");
		if (type == null)
		{
			return;
		}
		object obj = type.GetField("instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(null);
		if (obj == null)
		{
			return;
		}
		if (type.GetField("itemDictionary", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(obj) is IDictionary dictionary && !dictionary.Contains("SonicScrewdriver"))
		{
			Item val = ScriptableObject.CreateInstance<Item>();
			((Object)val).name = "SonicScrewdriver";
			FieldInfo[] fields = typeof(Item).GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			fields.FirstOrDefault((FieldInfo f) => f.Name == "itemType")?.SetValue(val, 1);
			fields.FirstOrDefault((FieldInfo f) => f.Name == "price")?.SetValue(val, 3750);
			val.itemName = "Sonic Screwdriver";
			val.description = "A multi-purpose tool for doors and lights.";
			val.physicalItem = true;
			val.maxAmountInShop = 1;
			val.prefab = new PrefabRef();
			val.prefab.SetPrefab(sonicScrewdriverPrefab, "TARDISMod/SonicScrewdriver");
			fields.FirstOrDefault((FieldInfo f) => f.Name == "price")?.SetValue(val, 15000);
			Value val2 = ScriptableObject.CreateInstance<Value>();
			val2.valueMin = 3750f;
			val2.valueMax = 3750f;
			val.value = val2;
			dictionary.Add("SonicScrewdriver", val);
			sonicItemDefinition = (ScriptableObject)(object)val;
			if (type.GetField("allItems", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(obj) is IList list && !list.Contains(val))
			{
				list.Add(val);
			}
		}
		string[] array = new string[4] { "itemsPurchased", "itemsFound", "itemAmountDict", "itemsUpgradesPurchased" };
		string[] array2 = array;
		foreach (string text in array2)
		{
			FieldInfo field = type.GetField(text, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field != null && field.GetValue(obj) is IDictionary dictionary2 && !dictionary2.Contains("SonicScrewdriver"))
			{
				dictionary2.Add("SonicScrewdriver", 0);
				Debug.Log((object)("[sonic] Initialized 'SonicScrewdriver' key in " + text));
			}
		}
	}

	public static void RegisterItemStatsKeys()
	{
		Type type = FindTypeBySimpleName("StatsManager");
		if (type == null)
		{
			return;
		}
		object obj = type.GetField("instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(null);
		if (obj == null)
		{
			return;
		}
		string[] array = new string[9] { "itemsPurchased", "itemsFound", "itemAmountDict", "itemsUpgradesPurchased", "itemsPurchasedTotal", "itemBatteryUpgrades", "item", "itemStatBattery", "itemsSold" };
		string[] array2 = array;
		foreach (string name in array2)
		{
			FieldInfo field = type.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field != null && field.GetValue(obj) is IDictionary dictionary && !dictionary.Contains("SonicScrewdriver"))
			{
				dictionary.Add("SonicScrewdriver", 0);
			}
		}
	}
}
[HarmonyPatch]
public static class Patch_TruckDoor_Toggle
{
	[CompilerGenerated]
	private sealed class <AnimateTruckDoorDown>d__1 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public MonoBehaviour truckDoor;

		private Type <type>5__1;

		private BindingFlags <flags>5__2;

		private FieldInfo <startYField>5__3;

		private FieldInfo <doorCurveField>5__4;

		private FieldInfo <doorEvalField>5__5;

		private float <startY>5__6;

		private AnimationCurve <curve>5__7;

		private float <timer>5__8;

		private float <eval>5__9;

		object IEnumerator<object>.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		object IEnumerator.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		[DebuggerHidden]
		public <AnimateTruckDoorDown>d__1(int <>1__state)
		{
			this.<>1__state = <>1__state;
		}

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<type>5__1 = null;
			<startYField>5__3 = null;
			<doorCurveField>5__4 = null;
			<doorEvalField>5__5 = null;
			<curve>5__7 = null;
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Expected O, but got Unknown
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b8: 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_0208: Unknown result type (might be due to invalid IL or missing references)
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				<type>5__1 = ((object)truckDoor).GetType();
				<flags>5__2 = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
				<startYField>5__3 = <type>5__1.GetField("startYPosition", <flags>5__2);
				<doorCurveField>5__4 = <type>5__1.GetField("doorCurve", <flags>5__2);
				<doorEvalField>5__5 = <type>5__1.GetField("doorEval", <flags>5__2);
				<startY>5__6 = (float)<startYField>5__3.GetValue(truckDoor);
				<curve>5__7 = (AnimationCurve)<doorCurveField>5__4.GetValue(truckDoor);
				<timer>5__8 = 1f;
				break;
			case 1:
				<>1__state = -1;
				break;
			}
			if (<timer>5__8 > 0f)
			{
				<timer>5__8 -= Time.deltaTime * 1.5f;
				<eval>5__9 = <curve>5__7.Evaluate(<timer>5__8);
				((Component)truckDoor).transform.position = new Vector3(((Component)truckDoor).transform.position.x, <startY>5__6 + 2.5f * <eval>5__9, ((Component)truckDoor).transform.position.z);
				<>2__current = null;
				<>1__state = 1;
				return true;
			}
			((Component)truckDoor).transform.position = new Vector3(((Component)truckDoor).transform.position.x, <startY>5__6, ((Component)truckDoor).transform.position.z);
			<doorEvalField>5__5.SetValue(truckDoor, 0f);
			if ((Object)(object)SonicShopInjection.heavyLockSound != (Object)null)
			{
				AudioSource.PlayClipAtPoint(SonicShopInjection.heavyLockSound, ((Component)truckDoor).transform.position, 1f);
			}
			return false;
		}

		bool IEnumerator.MoveNext()
		{
			//ILSpy generated this explicit interface implementation from .override directive in MoveNext
			return this.MoveNext();
		}

		[DebuggerHidden]
		void IEnumerator.Reset()
		{
			throw new NotSupportedException();
		}
	}

	public static void ToggleDoor(MonoBehaviour truckDoor)
	{
		Type type = ((object)truckDoor).GetType();
		BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
		FieldInfo field = type.GetField("doorEval", bindingAttr);
		FieldInfo field2 = type.GetField("fullyOpen", bindingAttr);
		FieldInfo field3 = type.GetField("doorOpen", bindingAttr);
		FieldInfo field4 = type.GetField("doorDelay", bindingAttr);
		float num = (float)field.GetValue(truckDoor);
		if (num >= 0.5f)
		{
			field4.SetValue(truckDoor, 99999f);
			field2.SetValue(truckDoor, false);
			field3.SetValue(truckDoor, false);
			truckDoor.StartCoroutine(AnimateTruckDoorDown(truckDoor));
		}
		else
		{
			field4.SetValue(truckDoor, 0f);
			field.SetValue(truckDoor, 0f);
			field2.SetValue(truckDoor, false);
			field3.SetValue(truckDoor, false);
		}
	}

	[IteratorStateMachine(typeof(<AnimateTruckDoorDown>d__1))]
	private static IEnumerator AnimateTruckDoorDown(MonoBehaviour truckDoor)
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <AnimateTruckDoorDown>d__1(0)
		{
			truckDoor = truckDoor
		};
	}
}
[HarmonyPatch(typeof(ExtractionPoint))]
public static class Patch_ExtractionPoint_Unlock
{
	[HarmonyPatch("Update")]
	[HarmonyPostfix]
	private static void Postfix(ExtractionPoint __instance)
	{
		//IL_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_00da: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e1: Expected O, but got Unknown
		//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
		if (!__instance.isLocked || !SemiFunc.IsMasterClientOrSingleplayer())
		{
			return;
		}
		Collider[] array = Physics.OverlapSphere(((Component)__instance).transform.position, 1.5f, -5, (QueryTriggerInteraction)2);
		Collider[] array2 = array;
		foreach (Collider val in array2)
		{
			GrabReact componentInParent = ((Component)val).GetComponentInParent<GrabReact>();
			if ((Object)(object)componentInParent != (Object)null && componentInParent.isActive)
			{
				Debug.Log((object)("[Sonic] Unlocking Extraction Point: " + ((Object)((Component)__instance).gameObject).name));
				__instance.isLocked = false;
				((Component)__instance).SendMessage("StateSet", (object)(State)1, (SendMessageOptions)1);
				FieldInfo field = typeof(ExtractionPoint).GetField("soundButton", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (field != null)
				{
					Sound val2 = (Sound)field.GetValue(__instance);
					val2.Play(((Component)__instance).transform.position, 1f, 1f, 1f, 1f);
				}
				break;
			}
		}
	}
}
[HarmonyPatch]
public static class Patch_UniversalTrap_Sonic
{
	[HarmonyPatch(typeof(Trap), "Update")]
	[HarmonyPostfix]
	private static void Postfix(Trap __instance)
	{
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		if (!SemiFunc.IsMasterClientOrSingleplayer() || __instance.trapTriggered)
		{
			return;
		}
		Collider[] array = Physics.OverlapSphere(((Component)__instance).transform.position, 0.8f);
		Collider[] array2 = array;
		foreach (Collider val in array2)
		{
			GrabReact componentInParent = ((Component)val).GetComponentInParent<GrabReact>();
			if (!((Object)(object)componentInParent != (Object)null) || !componentInParent.isActive)
			{
				continue;
			}
			Debug.Log((object)("[Sonic] Universal Trigger: Activating " + ((Object)((Component)__instance).gameObject).name));
			BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
			bool flag = false;
			MethodInfo method = ((object)__instance).GetType().GetMethod("TouchNose", bindingAttr);
			if (method != null)
			{
				method.Invoke(__instance, null);
				flag = true;
			}
			if (!flag)
			{
				method = ((object)__instance).GetType().GetMethod("MusicBoxStart", bindingAttr);
				if (method != null)
				{
					method.Invoke(__instance, null);
					flag = true;
				}
			}
			if (!flag)
			{
				method = ((object)__instance).GetType().GetMethod("SetStateRPC", bindingAttr);
				if (method != null)
				{
					method.Invoke(__instance, new object[1] { 1 });
					flag = true;
				}
			}
			if (!flag)
			{
				FieldInfo field = typeof(Trap).GetField("trapStart", bindingAttr);
				if (field != null)
				{
					field.SetValue(__instance, true);
					flag = true;
				}
				if (!flag)
				{
					((object)__instance).GetType().GetMethod("TrapActivate", bindingAttr)?.Invoke(__instance, null);
				}
			}
			break;
		}
	}
}
[HarmonyPatch]
public static class Patch_Grenade_Sonic
{
	[HarmonyPatch(typeof(ItemGrenade), "Update")]
	[HarmonyPostfix]
	private static void Postfix(ItemGrenade __instance)
	{
		//IL_005a: Unknown result type (might be due to invalid IL or missing references)
		FieldInfo field = typeof(ItemGrenade).GetField("isActive", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
		if (field == null || (bool)field.GetValue(__instance) || !SemiFunc.IsMasterClientOrSingleplayer())
		{
			return;
		}
		Collider[] array = Physics.OverlapSphere(((Component)__instance).transform.position, 0.8f);
		Collider[] array2 = array;
		foreach (Collider val in array2)
		{
			GrabReact componentInParent = ((Component)val).GetComponentInParent<GrabReact>();
			if (!((Object)(object)componentInParent != (Object)null) || !componentInParent.isActive)
			{
				continue;
			}
			Debug.Log((object)("[Sonic] Triggering grenade: " + ((Object)((Component)__instance).gameObject).name));
			FieldInfo field2 = typeof(ItemGrenade).GetField("itemToggle", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (!(field2 != null))
			{
				break;
			}
			object value = field2.GetValue(__instance);
			if (value != null)
			{
				FieldInfo field3 = value.GetType().GetField("toggleState", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (field3 != null)
				{
					field3.SetValue(value, true);
				}
			}
			break;
		}
	}
}
[HarmonyPatch(typeof(ValuableFlashlight), "Update")]
public static class Patch_Flashlight_Sonic
{
	[HarmonyPostfix]
	private static void Postfix(ValuableFlashlight __instance)
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		Collider[] array = Physics.OverlapSphere(((Component)__instance).transform.position, 0.5f);
		Collider[] array2 = array;
		foreach (Collider val in array2)
		{
			GrabReact componentInParent = ((Component)val).GetComponentInParent<GrabReact>();
			if ((Object)(object)componentInParent != (Object)null && componentInParent.isActive)
			{
				__instance.ImpactFlicker();
				break;
			}
		}
	}
}
[HarmonyPatch]
public static class Patch_PrefabRef_Intercept
{
	private static MethodBase TargetMethod()
	{
		return SonicShopInjection.FindTypeBySimpleName("PrefabRef")?.GetProperty("Prefab")?.GetGetMethod();
	}

	[HarmonyPrefix]
	private static bool Prefix(object __instance, ref GameObject __result)
	{
		string text = __instance.GetType().GetField("resourcePath", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(__instance) as string;
		if (!string.IsNullOrEmpty(text) && text == "TARDISMod/SonicScrewdriver" && (Object)(object)SonicShopInjection.sonicScrewdriverPrefab != (Object)null)
		{
			__result = SonicShopInjection.sonicScrewdriverPrefab;
			return false;
		}
		return true;
	}
}
namespace TARDISMod;

public class GrabReact : MonoBehaviourPun
{
	private class DoorData
	{
		public Vector3 InitialPosition;

		public Quaternion InitialRotation;

		public string DoorType;

		public GameObject BlockedInstance;

		public Renderer[] OriginalRenderers;

		public Collider[] OriginalColliders;
	}

	[CompilerGenerated]
	private sealed class <PlaySonicSound>d__31 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public GrabReact <>4__this;

		object IEnumerator<object>.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		object IEnumerator.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		[DebuggerHidden]
		public <PlaySonicSound>d__31(int <>1__state)
		{
			this.<>1__state = <>1__state;
		}

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Invalid comparison between Unknown and I4
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Invalid comparison between Unknown and I4
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				<>2__current = null;
				<>1__state = 1;
				return true;
			case 1:
				<>1__state = -1;
				if ((int)<>4__this.audioSource.clip.loadState == 2)
				{
					break;
				}
				<>4__this.audioSource.clip.LoadAudioData();
				goto IL_0091;
			case 2:
				{
					<>1__state = -1;
					goto IL_0091;
				}
				IL_0091:
				if ((int)<>4__this.audioSource.clip.loadState == 1)
				{
					<>2__current = null;
					<>1__state = 2;
					return true;
				}
				break;
			}
			<>4__this.audioSource.volume = 1f;
			<>4__this.audioSource.pitch = 1f;
			<>4__this.audioSource.mute = false;
			<>4__this.audioSource.Play();
			Debug.Log((object)$"[sonic] Sonic Sound playing via Coroutine: {<>4__this.audioSource.isPlaying}");
			return false;
		}

		bool IEnumerator.MoveNext()
		{
			//ILSpy generated this explicit interface implementation from .override directive in MoveNext
			return this.MoveNext();
		}

		[DebuggerHidden]
		void IEnumerator.Reset()
		{
			throw new NotSupportedException();
		}
	}

	public PhysGrabObject physGrabObject;

	private AudioSource audioSource;

	public Sound clickOn;

	public Sound clickOff;

	public KeyCode activationKey = (KeyCode)101;

	public float toggleCooldown = 0.5f;

	public float posTolerance = 0.2f;

	public float rotTolerance = 0.001f;

	private GameObject audioHost;

	private List<CapsuleCollider> capsuleColliders = new List<CapsuleCollider>();

	private List<Light> localLights = new List<Light>();

	private List<Renderer> localRenderers = new List<Renderer>();

	private GameObject emissionSphereObj;

	public bool isActive = false;

	private float cooldownTimer = 0f;

	private Coroutine audioCoroutine;

	private Dictionary<Material, Color> originalEmissionColors = new Dictionary<Material, Color>();

	private static Dictionary<GameObject, DoorData> trackedDoors = new Dictionary<GameObject, DoorData>();

	private static bool doorsScanned = false;

	private static string lastSceneName = "";

	private static bool levelScanDone = false;

	private bool isScanning = false;

	private static readonly Dictionary<string, string> doorTypeMap = new Dictionary<string, string>
	{
		{ "Arctic Door", "Arctic" },
		{ "Manor Door", "Manor" },
		{ "Wizard Door", "Wizard" },
		{ "Wizard Double Door", "Wizard" },
		{ "Door", "Manor" },
		{ "door", "Manor" }
	};

	private void Awake()
	{
		//IL_0117: Unknown result type (might be due to invalid IL or missing references)
		//IL_0121: Expected O, but got Unknown
		//IL_0143: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)SonicShopInjection.sonicScrewdriverPrefab == (Object)null)
		{
			SonicShopInjection.Initialize();
		}
		Debug.Log((object)("[sonic] --- Debugging Audio for " + ((Object)((Component)this).gameObject).name + " ---"));
		AudioSource[] componentsInChildren = ((Component)this).GetComponentsInChildren<AudioSource>(true);
		Debug.Log((object)$"[sonic] Found {componentsInChildren.Length} AudioSource(s) on this object.");
		for (int i = 0; i < componentsInChildren.Length; i++)
		{
			string text = (((Object)(object)componentsInChildren[i].clip != (Object)null) ? ((Object)componentsInChildren[i].clip).name : "NULL");
			Debug.Log((object)$"[sonic] Source {i}: GameObject({((Object)((Component)componentsInChildren[i]).gameObject).name}), Clip({text}), Muted({componentsInChildren[i].mute})");
		}
		physGrabObject = ((Component)this).GetComponent<PhysGrabObject>();
		if ((Object)(object)physGrabObject == (Object)null)
		{
			physGrabObject = ((Component)this).gameObject.AddComponent<PhysGrabObject>();
		}
		audioHost = new GameObject("SonicAudioHost");
		audioHost.transform.SetParent(((Component)this).transform);
		audioHost.transform.localPosition = Vector3.zero;
		audioSource = audioHost.AddComponent<AudioSource>();
		audioSource.playOnAwake = false;
		audioSource.loop = true;
		AudioMixerGroup[] source = Resources.FindObjectsOfTypeAll<AudioMixerGroup>();
		audioSource.outputAudioMixerGroup = ((IEnumerable<AudioMixerGroup>)source).FirstOrDefault((Func<AudioMixerGroup, bool>)((AudioMixerGroup g) => ((Object)g).name.Contains("SFX") || ((Object)g).name.Contains("Master")));
		audioSource.spatialBlend = 1f;
		audioSource.minDistance = 1f;
		audioSource.maxDistance = 15f;
		audioSource.volume = 1f;
		audioSource.priority = 0;
		if ((Object)(object)SonicShopInjection.sonicSound != (Object)null)
		{
			audioSource.clip = SonicShopInjection.sonicSound;
			audioSource.clip.LoadAudioData();
		}
		capsuleColliders = ((Component)this).GetComponentsInChildren<CapsuleCollider>(true).ToList();
		localLights = ((Component)this).GetComponentsInChildren<Light>(true).ToList();
		localRenderers = ((Component)this).GetComponentsInChildren<Renderer>(true).ToList();
		Transform val = ((IEnumerable<Transform>)((Component)this).GetComponentsInChildren<Transform>(true)).FirstOrDefault((Func<Transform, bool>)((Transform t) => ((Object)t).name == "Sphere"));
		if ((Object)(object)val != (Object)null)
		{
			emissionSphereObj = ((Component)val).gameObject;
		}
		else
		{
			Debug.LogWarning((object)"[sonic] Could not find 'Sphere' in children!");
		}
		localLights = ((Component)this).GetComponentsInChildren<Light>(true).ToList();
		LogAllWizardObjects();
		SetLocalVisuals(state: false);
		SetColliders(state: false);
		if (!doorsScanned)
		{
			ScanForDoors();
			doorsScanned = true;
		}
	}

	private void ScanForDoors()
	{
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_020c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0211: Unknown result type (might be due to invalid IL or missing references)
		//IL_0219: Unknown result type (might be due to invalid IL or missing references)
		//IL_021e: Unknown result type (might be due to invalid IL or missing references)
		trackedDoors.Clear();
		Scene activeScene = SceneManager.GetActiveScene();
		GameObject[] rootGameObjects = ((Scene)(ref activeScene)).GetRootGameObjects();
		GameObject[] array = rootGameObjects;
		foreach (GameObject val in array)
		{
			Transform[] componentsInChildren = val.GetComponentsInChildren<Transform>(true);
			foreach (Transform val2 in componentsInChildren)
			{
				Transform val3 = val2;
				string name = ((Object)val3).name;
				if (name.Contains("Wizard Door Double"))
				{
					Transform parent = val3.parent;
					if ((Object)(object)parent != (Object)null && ((Object)parent).name == "Wizard Door")
					{
						if (trackedDoors.ContainsKey(((Component)parent).gameObject))
						{
							continue;
						}
						val3 = parent;
						name = ((Object)val3).name;
					}
				}
				string text = GetDoorTypeFromName(name);
				if (text == null)
				{
					string text2 = name.ToLower();
					if (text2.Contains("door") && (text2.Contains("frame") || text2.Contains("wall") || text2.Contains("car")))
					{
						Debug.Log((object)("<color=yellow>[Sonic Scan] Ignoring non-door object:</color> " + name));
					}
					continue;
				}
				if (text == "Generic")
				{
					text = "Manor";
					Transform parent2 = val2.parent;
					while ((Object)(object)parent2 != (Object)null)
					{
						if (((Object)parent2).name.Contains("Arctic"))
						{
							text = "Arctic";
							break;
						}
						if (((Object)parent2).name.Contains("Wizard"))
						{
							text = "Wizard";
							break;
						}
						if (((Object)parent2).name.Contains("Manor"))
						{
							text = "Manor";
							break;
						}
						parent2 = parent2.parent;
					}
				}
				if (!trackedDoors.ContainsKey(((Component)val3).gameObject))
				{
					trackedDoors[((Component)val3).gameObject] = new DoorData
					{
						InitialPosition = val3.position,
						InitialRotation = val3.rotation,
						DoorType = text,
						OriginalRenderers = ((Component)val3).GetComponentsInChildren<Renderer>(true),
						OriginalColliders = ((Component)val3).GetComponentsInChildren<Collider>(true)
					};
				}
			}
		}
	}

	private string GetDoorTypeFromName(string name)
	{
		string format = "^({0})(\\s\\(\\d+\\))?$";
		if (name == "Wizard Door")
		{
			return "Wizard";
		}
		if (Regex.IsMatch(name, string.Format(format, "Arctic Door")))
		{
			return "Arctic";
		}
		if (Regex.IsMatch(name, string.Format(format, "Wizard Door")))
		{
			return "Wizard";
		}
		if (Regex.IsMatch(name, string.Format(format, "Wizard Door Double")))
		{
			return "Wizard";
		}
		if (Regex.IsMatch(name, string.Format(format, "Wizard Door Double (1)")))
		{
			return "Wizard";
		}
		if (Regex.IsMatch(name, string.Format(format, "Manor Door")))
		{
			return "Manor";
		}
		if (Regex.IsMatch(name, string.Format(format, "Door")))
		{
			return "Manor";
		}
		if (Regex.IsMatch(name, string.Format(format, "Hinge")))
		{
			return "Manor";
		}
		if (Regex.IsMatch(name, string.Format(format, "Door")))
		{
			return "Generic";
		}
		return null;
	}

	private void PlayOneShot(AudioClip clip, Vector3 position)
	{
		//IL_000f: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)clip == (Object)null))
		{
			AudioSource.PlayClipAtPoint(clip, position, 1f);
		}
	}

	private void Update()
	{
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)physGrabObject == (Object)null))
		{
			if (cooldownTimer > 0f)
			{
				cooldownTimer -= Time.deltaTime;
			}
			bool flag = physGrabObject.grabbed && Input.GetKey(activationKey);
			if (flag && !isActive)
			{
				isActive = true;
				Activate();
			}
			else if (!flag && isActive)
			{
				isActive = false;
				Deactivate();
			}
			UpdateDoorScanner();
			if (isActive && (Object)(object)audioSource != (Object)null && !audioSource.isPlaying)
			{
				audioSource.Play();
			}
		}
	}

	private void UpdateDoorScanner()
	{
		LevelGenerator instance = LevelGenerator.Instance;
		if ((Object)(object)instance == (Object)null)
		{
			levelScanDone = false;
			trackedDoors.Clear();
		}
		else if (instance.Generated && !levelScanDone && !isScanning)
		{
			LogAllWizardObjects();
			ScanForDoors();
			levelScanDone = true;
		}
		else if (!instance.Generated)
		{
			levelScanDone = false;
			trackedDoors.Clear();
		}
	}

	private void Activate()
	{
		if ((Object)(object)audioSource != (Object)null && (Object)(object)audioSource.clip != (Object)null)
		{
			audioSource.volume = 1f;
			audioSource.mute = false;
			if (!audioSource.isPlaying)
			{
				audioSource.Play();
				Debug.Log((object)$"[sonic] Sonic Sound Triggered on Child Object: {audioSource.isPlaying}");
			}
		}
		if ((Object)(object)emissionSphereObj != (Object)null)
		{
			emissionSphereObj.SetActive(true);
		}
		SetLocalVisuals(state: true);
		SetColliders(state: true);
	}

	[IteratorStateMachine(typeof(<PlaySonicSound>d__31))]
	private IEnumerator PlaySonicSound()
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <PlaySonicSound>d__31(0)
		{
			<>4__this = this
		};
	}

	private void ScanModuleForDoors(Transform moduleRoot)
	{
		//IL_011d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0122: Unknown result type (might be due to invalid IL or missing references)
		//IL_012a: 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)
		string text = "Generic";
		if (((Object)moduleRoot).name.IndexOf("Manor", StringComparison.OrdinalIgnoreCase) >= 0)
		{
			text = "Manor";
		}
		else if (((Object)moduleRoot).name.IndexOf("Arctic", StringComparison.OrdinalIgnoreCase) >= 0)
		{
			text = "Arctic";
		}
		else if (((Object)moduleRoot).name.IndexOf("Wizard", StringComparison.OrdinalIgnoreCase) >= 0)
		{
			text = "Wizard";
		}
		Transform[] componentsInChildren = ((Component)moduleRoot).GetComponentsInChildren<Transform>(true);
		foreach (Transform val in componentsInChildren)
		{
			string name = ((Object)val).name;
			if (name.Contains("Blocked"))
			{
				continue;
			}
			string text2 = GetDoorTypeFromName(name);
			if (text2 == "Generic")
			{
				text2 = text;
			}
			if (text2 != null && !trackedDoors.ContainsKey(((Component)val).gameObject))
			{
				if (text2 == "Generic")
				{
					text2 = text;
				}
				trackedDoors[((Component)val).gameObject] = new DoorData
				{
					InitialPosition = val.position,
					InitialRotation = val.rotation,
					DoorType = text2,
					OriginalRenderers = ((Component)val).GetComponentsInChildren<Renderer>(true),
					OriginalColliders = ((Component)val).GetComponentsInChildren<Collider>(true)
				};
				Debug.Log((object)("[TARDISMod] Tracked Module Door: " + name + " as " + text2));
			}
		}
	}

	private void Deactivate()
	{
		if ((Object)(object)audioSource != (Object)null && audioSource.isPlaying)
		{
			audioSource.Stop();
		}
		if ((Object)(object)emissionSphereObj != (Object)null)
		{
			emissionSphereObj.SetActive(false);
		}
		SetLocalVisuals(state: false);
		SetColliders(state: false);
	}

	private void ReplaceWizardDoorParent(GameObject hitObject)
	{
		//IL_012a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0135: Unknown result type (might be due to invalid IL or missing references)
		Transform val = hitObject.transform;
		while ((Object)(object)val.parent != (Object)null && (((Object)val.parent).name.StartsWith("Wizard Door") || ((Object)val.parent).name.Contains("Door")))
		{
			val = val.parent;
		}
		GameObject gameObject = ((Component)val).gameObject;
		Transform val2 = val.Find(((Object)gameObject).name + " Blocked");
		if ((Object)(object)val2 != (Object)null)
		{
			Object.Destroy((Object)(object)((Component)val2).gameObject);
			Renderer[] componentsInChildren = gameObject.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val3 in componentsInChildren)
			{
				val3.enabled = true;
			}
			Collider[] componentsInChildren2 = gameObject.GetComponentsInChildren<Collider>(true);
			foreach (Collider val4 in componentsInChildren2)
			{
				val4.enabled = true;
			}
			Debug.Log((object)("[Sonic] Restored entire assembly: " + ((Object)gameObject).name));
			return;
		}
		GameObject wizardDoorBlockedPrefab = SonicShopInjection.wizardDoorBlockedPrefab;
		if (!((Object)(object)wizardDoorBlockedPrefab != (Object)null))
		{
			return;
		}
		GameObject val5 = Object.Instantiate<GameObject>(wizardDoorBlockedPrefab, gameObject.transform.position, gameObject.transform.rotation);
		((Object)val5).name = ((Object)gameObject).name + " Blocked";
		val5.transform.SetParent(gameObject.transform);
		Renderer[] componentsInChildren3 = gameObject.GetComponentsInChildren<Renderer>(true);
		Collider[] componentsInChildren4 = gameObject.GetComponentsInChildren<Collider>(true);
		Renderer[] array = componentsInChildren3;
		foreach (Renderer val6 in array)
		{
			if (!((Component)val6).transform.IsChildOf(val5.transform))
			{
				val6.enabled = false;
			}
		}
		Collider[] array2 = componentsInChildren4;
		foreach (Collider val7 in array2)
		{
			if (!((Component)val7).transform.IsChildOf(val5.transform))
			{
				val7.enabled = false;
			}
		}
		Debug.Log((object)("[Sonic] Nuked parent and all children for: " + ((Object)gameObject).name));
	}

	private void OnTriggerEnter(Collider other)
	{
		//IL_0232: Unknown result type (might be due to invalid IL or missing references)
		//IL_0237: Unknown result type (might be due to invalid IL or missing references)
		//IL_023c: 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_0247: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a0: Unknown result type (might be due to invalid IL or missing references)
		if (!isActive || cooldownTimer > 0f)
		{
			return;
		}
		TruckDoor componentInParent = ((Component)other).GetComponentInParent<TruckDoor>();
		if ((Object)(object)componentInParent != (Object)null)
		{
			if ((Object)(object)((MonoBehaviourPun)this).photonView != (Object)null && ((MonoBehaviourPun)this).photonView.IsMine)
			{
				PhotonView component = ((Component)componentInParent).GetComponent<PhotonView>();
				if ((Object)(object)component != (Object)null)
				{
					((MonoBehaviourPun)this).photonView.RPC("RPC_ToggleTruckDoor", (RpcTarget)0, new object[1] { component.ViewID });
					cooldownTimer = toggleCooldown;
				}
			}
			else if (!SemiFunc.IsMultiplayer())
			{
				Patch_TruckDoor_Toggle.ToggleDoor((MonoBehaviour)(object)componentInParent);
				cooldownTimer = toggleCooldown;
			}
			return;
		}
		bool flag = false;
		Transform val = ((Component)other).transform;
		while ((Object)(object)val != (Object)null)
		{
			if (((Object)val).name.Contains("Wizard Door"))
			{
				if (SemiFunc.IsMasterClientOrSingleplayer())
				{
					CheckAndReplaceDoor(((Component)val).gameObject);
					flag = true;
				}
				break;
			}
			if (trackedDoors.TryGetValue(((Component)val).gameObject, out var _))
			{
				if (SemiFunc.IsMasterClientOrSingleplayer())
				{
					CheckAndReplaceDoor(((Component)val).gameObject);
					flag = true;
				}
				break;
			}
			val = val.parent;
		}
		Collider val2 = ((Component)this).GetComponent<Collider>();
		if ((Object)(object)val2 == (Object)null && capsuleColliders.Count > 0)
		{
			val2 = (Collider)(object)capsuleColliders[0];
		}
		if ((Object)(object)val2 != (Object)null)
		{
			Light[] array = Object.FindObjectsOfType<Light>();
			foreach (Light val3 in array)
			{
				bool flag2 = false;
				if (localLights != null)
				{
					foreach (Light localLight in localLights)
					{
						if ((Object)(object)val3 == (Object)(object)localLight)
						{
							flag2 = true;
						}
					}
				}
				if (flag2)
				{
					continue;
				}
				Vector3 val4 = val2.ClosestPoint(((Component)val3).transform.position);
				if (Vector3.Distance(val4, ((Component)val3).transform.position) < 0.1f)
				{
					if ((Object)(object)((MonoBehaviourPun)this).photonView != (Object)null && ((MonoBehaviourPun)this).photonView.IsMine)
					{
						((MonoBehaviourPun)this).photonView.RPC("RPC_ToggleLight", (RpcTarget)0, new object[1] { ((Component)val3).transform.position });
					}
					else if (!SemiFunc.IsMultiplayer())
					{
						((Behaviour)val3).enabled = !((Behaviour)val3).enabled;
						ToggleEmission(((Component)val3).transform, ((Behaviour)val3).enabled);
						ToggleFireObjects(((Component)val3).transform, ((Behaviour)val3).enabled);
						ToggleCandleFlames(((Component)val3).transform, ((Behaviour)val3).enabled);
					}
					flag = true;
				}
			}
		}
		if (flag)
		{
			cooldownTimer = toggleCooldown;
		}
	}

	[PunRPC]
	private void RPC_ToggleDoor(Vector3 targetPos, string doorType)
	{
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = null;
		float num = 999f;
		foreach (KeyValuePair<GameObject, DoorData> trackedDoor in trackedDoors)
		{
			float num2 = Vector3.Distance(trackedDoor.Value.InitialPosition, targetPos);
			if (num2 < num)
			{
				num = num2;
				val = trackedDoor.Key;
			}
		}
		if ((Object)(object)val != (Object)null && num < 1f)
		{
			ApplyDoorVisuals(val, doorType);
		}
	}

	private void ApplyDoorVisuals(GameObject doorObj, string doorType)
	{
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_0131: 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_0231: Unknown result type (might be due to invalid IL or missing references)
		//IL_0255: Unknown result type (might be due to invalid IL or missing references)
		if (!trackedDoors.TryGetValue(doorObj, out var value))
		{
			return;
		}
		float num = Vector3.Distance(doorObj.transform.position, value.InitialPosition);
		if (num >= posTolerance)
		{
			return;
		}
		if ((Object)(object)value.BlockedInstance != (Object)null)
		{
			Object.Destroy((Object)(object)value.BlockedInstance);
			value.BlockedInstance = null;
			Renderer[] componentsInChildren = doorObj.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren)
			{
				val.enabled = true;
			}
			Collider[] componentsInChildren2 = doorObj.GetComponentsInChildren<Collider>(true);
			foreach (Collider val2 in componentsInChildren2)
			{
				val2.enabled = true;
			}
			return;
		}
		GameObject val3 = null;
		switch (doorType)
		{
		case "Arctic":
			val3 = SonicShopInjection.arcticDoorBlockedPrefab;
			break;
		case "Manor":
			val3 = SonicShopInjection.manorDoorBlockedPrefab;
			break;
		case "Wizard":
			val3 = SonicShopInjection.wizardDoorBlockedPrefab;
			break;
		}
		if (!((Object)(object)val3 != (Object)null))
		{
			return;
		}
		GameObject val4 = Object.Instantiate<GameObject>(val3, value.InitialPosition, value.InitialRotation);
		((Object)val4).name = ((Object)doorObj).name + " Blocked";
		val4.transform.SetParent(doorObj.transform);
		value.BlockedInstance = val4;
		Renderer[] componentsInChildren3 = doorObj.GetComponentsInChildren<Renderer>(true);
		foreach (Renderer val5 in componentsInChildren3)
		{
			if (!((Component)val5).transform.IsChildOf(val4.transform))
			{
				val5.enabled = false;
			}
		}
		Collider[] componentsInChildren4 = doorObj.GetComponentsInChildren<Collider>(true);
		foreach (Collider val6 in componentsInChildren4)
		{
			if (!((Component)val6).transform.IsChildOf(val4.transform))
			{
				val6.enabled = false;
			}
		}
		if (doorType == "Arctic" && (Object)(object)SonicShopInjection.arcticLockSound != (Object)null)
		{
			AudioSource.PlayClipAtPoint(SonicShopInjection.arcticLockSound, value.InitialPosition);
		}
		else if ((Object)(object)SonicShopInjection.heavyLockSound != (Object)null)
		{
			AudioSource.PlayClipAtPoint(SonicShopInjection.heavyLockSound, value.InitialPosition);
		}
	}

	[PunRPC]
	private void RPC_ToggleLight(Vector3 targetPos)
	{
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		Light val = null;
		float num = 0.5f;
		Light[] array = Object.FindObjectsOfType<Light>();
		foreach (Light val2 in array)
		{
			float num2 = Vector3.Distance(((Component)val2).transform.position, targetPos);
			if (num2 < num)
			{
				num = num2;
				val = val2;
			}
		}
		if ((Object)(object)val != (Object)null)
		{
			((Behaviour)val).enabled = !((Behaviour)val).enabled;
			ToggleEmission(((Component)val).transform, ((Behaviour)val).enabled);
			ToggleFireObjects(((Component)val).transform, ((Behaviour)val).enabled);
			ToggleCandleFlames(((Component)val).transform, ((Behaviour)val).enabled);
		}
	}

	[PunRPC]
	private void RPC_ToggleTruckDoor(int viewID)
	{
		PhotonView val = PhotonView.Find(viewID);
		if ((Object)(object)val != (Object)null)
		{
			TruckDoor component = ((Component)val).GetComponent<TruckDoor>();
			if ((Object)(object)component != (Object)null)
			{
				Patch_TruckDoor_Toggle.ToggleDoor((MonoBehaviour)(object)component);
			}
		}
	}

	private void LogAllWizardObjects()
	{
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		Debug.Log((object)"<color=cyan>[Sonic Diagnostics] Level Generated! Scanning for Wizard Doors...</color>");
		Scene activeScene = SceneManager.GetActiveScene();
		GameObject[] rootGameObjects = ((Scene)(ref activeScene)).GetRootGameObjects();
		int num = 0;
		GameObject[] array = rootGameObjects;
		foreach (GameObject val in array)
		{
			Transform[] componentsInChildren = val.GetComponentsInChildren<Transform>(true);
			foreach (Transform val2 in componentsInChildren)
			{
				if (((Object)val2).name.IndexOf("Wizard Door", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					num++;
					string text = (((Object)(object)val2.parent != (Object)null) ? ((Object)val2.parent).name : "ROOT");
					string text2 = (((Object)val2).name.Contains("Double") ? "cyan" : "lime");
					Debug.Log((object)$"<b>[Found {num}]</b> <color={text2}>{((Object)val2).name}</color> | Parent: <color=yellow>{text}</color>");
				}
			}
		}
		if (num == 0)
		{
			Debug.LogWarning((object)"[Sonic Diagnostics] Level is generated, but zero 'Wizard Door' objects were found. Check naming conventions!");
		}
	}

	private void ToggleEmission(Transform target, bool isOn)
	{
		//IL_0113: Unknown result type (might be due to invalid IL or missing references)
		//IL_0142: Unknown result type (might be due to invalid IL or missing references)
		//IL_012e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_0090: Unknown result type (might be due to invalid IL or missing references)
		Transform val = (((Object)(object)target.parent != (Object)null) ? target.parent : target);
		Renderer[] componentsInChildren = ((Component)val).GetComponentsInChildren<Renderer>();
		Renderer[] array = componentsInChildren;
		foreach (Renderer val2 in array)
		{
			Material[] materials = val2.materials;
			foreach (Material val3 in materials)
			{
				if (!val3.HasProperty("_EmissionColor"))
				{
					continue;
				}
				if (!isOn)
				{
					if (!originalEmissionColors.ContainsKey(val3))
					{
						originalEmissionColors.Add(val3, val3.GetColor("_EmissionColor"));
					}
					val3.SetColor("_EmissionColor", Color.black);
					val3.DisableKeyword("_EMISSION");
				}
				else if (originalEmissionColors.ContainsKey(val3))
				{
					val3.SetColor("_EmissionColor", originalEmissionColors[val3]);
					val3.EnableKeyword("_EMISSION");
				}
			}
			DynamicGI.SetEmissive(val2, isOn ? (originalEmissionColors.ContainsKey(val2.material) ? originalEmissionColors[val2.material] : Color.white) : Color.black);
		}
	}

	private void ToggleCandleFlames(Transform target, bool isOn)
	{
		Transform val = (((Object)(object)target.parent != (Object)null) ? target.parent : target);
		Transform[] componentsInChildren = ((Component)val).GetComponentsInChildren<Transform>(true);
		foreach (Transform val2 in componentsInChildren)
		{
			if (((Object)val2).name.Equals("Candle Flame Mesh", StringComparison.OrdinalIgnoreCase))
			{
				((Component)val2).gameObject.SetActive(isOn);
			}
		}
	}

	private void ToggleFireObjects(Transform target, bool isOn)
	{
		Transform val = (((Object)(object)target.parent != (Object)null) ? target.parent : target);
		Transform[] componentsInChildren = ((Component)val).GetComponentsInChildren<Transform>(true);
		foreach (Transform val2 in componentsInChildren)
		{
			if (((Object)val2).name.IndexOf("Fire", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				((Component)val2).gameObject.SetActive(isOn);
			}
		}
	}

	private void SetLocalVisuals(bool state)
	{
		if ((Object)(object)emissionSphereObj != (Object)null)
		{
			emissionSphereObj.SetActive(state);
		}
		if (localLights == null)
		{
			return;
		}
		foreach (Light localLight in localLights)
		{
			if ((Object)(object)localLight != (Object)null)
			{
				((Behaviour)localLight).enabled = state;
			}
		}
	}

	private void SetColliders(bool state)
	{
		foreach (CapsuleCollider capsuleCollider in capsuleColliders)
		{
			((Collider)capsuleCollider).enabled = state;
		}
	}

	private void ToggleSpecialChildren(GameObject obj, bool state)
	{
		Transform[] componentsInChildren = obj.GetComponentsInChildren<Transform>(true);
		foreach (Transform val in componentsInChildren)
		{
			if (((Object)val).name.IndexOf("Fire", StringComparison.OrdinalIgnoreCase) >= 0 || ((Object)val).name.IndexOf("Flame", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				((Component)val).gameObject.SetActive(state);
			}
		}
	}

	private void CheckAndReplaceDoor(GameObject doorObj)
	{
		//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0100: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_0289: 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_0215: Unknown result type (might be due to invalid IL or missing references)
		//IL_0244: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = null;
		DoorData doorData = null;
		Transform val2 = doorObj.transform;
		while ((Object)(object)val2 != (Object)null)
		{
			if (trackedDoors.ContainsKey(((Component)val2).gameObject))
			{
				val = ((Component)val2).gameObject;
				doorData = trackedDoors[val];
				break;
			}
			string format = "^({0})(\\s\\(\\d+\\))?$";
			if (((Object)doorObj).name.Contains("Wizard Door"))
			{
				ReplaceWizardDoorParent(doorObj);
			}
			if (Regex.IsMatch(((Object)this).name, string.Format(format, "Wizard Door")))
			{
				val = ((Component)val2).gameObject;
				break;
			}
			val2 = val2.parent;
		}
		if ((Object)(object)val == (Object)null)
		{
			Debug.LogWarning((object)("[Sonic] Could not find a valid Door Root for " + ((Object)doorObj).name));
			return;
		}
		Transform obj = val.transform.Find(((Object)val).name + " Blocked");
		GameObject val3 = ((obj != null) ? ((Component)obj).gameObject : null);
		Vector3 position = val.transform.position;
		if ((Object)(object)val3 != (Object)null || (doorData != null && (Object)(object)doorData.BlockedInstance != (Object)null))
		{
			GameObject val4 = val3 ?? doorData.BlockedInstance;
			Object.Destroy((Object)(object)val4);
			if (doorData != null)
			{
				doorData.BlockedInstance = null;
			}
			Renderer[] componentsInChildren = val.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val5 in componentsInChildren)
			{
				val5.enabled = true;
			}
			Collider[] componentsInChildren2 = val.GetComponentsInChildren<Collider>(true);
			foreach (Collider val6 in componentsInChildren2)
			{
				val6.enabled = true;
			}
			return;
		}
		GameObject val7 = null;
		if (doorData != null)
		{
			if (doorData.DoorType == "Arctic")
			{
				val7 = SonicShopInjection.arcticDoorBlockedPrefab;
				PlayOneShot(SonicShopInjection.arcticLockSound, position);
			}
			else if (doorData.DoorType == "Manor")
			{
				val7 = SonicShopInjection.manorDoorBlockedPrefab;
				PlayOneShot(SonicShopInjection.heavyLockSound, position);
			}
			else if (doorData.DoorType == "Wizard")
			{
				val7 = SonicShopInjection.wizardDoorBlockedPrefab;
				PlayOneShot(SonicShopInjection.heavyLockSound, position);
			}
		}
		else if (((Object)val).name.Contains("Wizard"))
		{
			val7 = SonicShopInjection.wizardDoorBlockedPrefab;
		}
		if (!((Object)(object)val7 != (Object)null))
		{
			return;
		}
		GameObject val8 = Object.Instantiate<GameObject>(val7, val.transform.position, val.transform.rotation);
		((Object)val8).name = ((Object)val).name + " Blocked";
		val8.transform.SetParent(val.transform);
		if (doorData != null)
		{
			doorData.BlockedInstance = val8;
		}
		Renderer[] componentsInChildren3 = val.GetComponentsInChildren<Renderer>(true);
		foreach (Renderer val9 in componentsInChildren3)
		{
			if (!((Object)(object)((Component)val9).transform == (Object)(object)val8.transform) && !((Component)val9).transform.IsChildOf(val8.transform))
			{
				val9.enabled = false;
			}
		}
		Collider[] componentsInChildren4 = val.GetComponentsInChildren<Collider>(true);
		foreach (Collider val10 in componentsInChildren4)
		{
			if (!((Object)(object)((Component)val10).transform == (Object)(object)val8.transform) && !((Component)val10).transform.IsChildOf(val8.transform))
			{
				val10.enabled = false;
			}
		}
		Debug.Log((object)("[Sonic] Successfully replaced the entire assembly: " + ((Object)val).name));
	}
}