Decompiled source of Cats v1.11.2

Cats.dll

Decompiled 12 hours 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.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using ExitGames.Client.Photon;
using HarmonyLib;
using Photon.Pun;
using Photon.Realtime;
using REPOLib.Modules;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("0.0.0.0")]
namespace Cats;

public enum Rarity
{
	Common,
	Uncommon,
	Rare,
	Custom
}
public class MaterialVariants : MonoBehaviour
{
	public Material[] variants;

	[HideInInspector]
	public int currentVariant;
}
public class CatRarity : MonoBehaviour
{
	public Rarity rarity;

	public bool museumOnly;

	public bool noDisplayName;

	public string defaultName;
}
public class YarnBallDuctTaped : MonoBehaviour
{
	[CompilerGenerated]
	private sealed class <ActivateNextFrame>d__17 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public GameObject go;

		public int activatorViewId;

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

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

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

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

		private bool MoveNext()
		{
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: 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)
			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 ((Object)(object)go == (Object)null)
				{
					return false;
				}
				ItemToggle component3 = go.GetComponent<ItemToggle>();
				if ((Object)(object)component3 != (Object)null)
				{
					component3.ToggleItem(true, activatorViewId);
				}
				<>2__current = null;
				<>1__state = 2;
				return true;
			}
			case 2:
			{
				<>1__state = -1;
				if ((Object)(object)go == (Object)null)
				{
					return false;
				}
				PhysGrabObject component = go.GetComponent<PhysGrabObject>();
				if ((Object)(object)component != (Object)null)
				{
					_clientNonKinField?.SetValue(component, true);
				}
				Rigidbody component2 = go.GetComponent<Rigidbody>();
				if ((Object)(object)component2 != (Object)null)
				{
					component2.isKinematic = false;
					Vector3 val = Quaternion.Euler((float)Random.Range(-30, 30), (float)Random.Range(-180, 180), 0f) * Vector3.forward;
					component2.velocity = val * Random.Range(4f, 8f);
					component2.angularVelocity = Random.insideUnitSphere * Random.Range(3f, 6f);
				}
				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 GameObject grenadePrefab;

	public int spawnCount = 3;

	public Sound soundExplosion;

	public Sound soundExplosionGlobal;

	private ParticleScriptExplosion particleScriptExplosion;

	private PhotonView photonView;

	private ItemGrenade itemGrenade;

	private string _networkPath;

	private static readonly FieldInfo _activatorField = AccessTools.Field(typeof(ItemGrenade), "activatorPlayerAvatar");

	private static readonly FieldInfo _clientNonKinField = AccessTools.Field(typeof(PhysGrabObject), "clientNonKinematic");

	private static readonly FieldInfo _isSpawnedField = AccessTools.Field(typeof(ItemGrenade), "isSpawnedGrenade");

	private static readonly FieldInfo _tickTimeField = AccessTools.Field(typeof(ItemGrenade), "tickTime");

	private static readonly MethodInfo _setActivatorMethod = AccessTools.Method(typeof(ItemGrenade), "SetActivator", (Type[])null, (Type[])null);

	private static readonly FieldInfo _causingHurtField = AccessTools.Field(typeof(ParticleScriptExplosion), "playerCausingHurtOverride");

	private static readonly FieldInfo _fullRuckusField = AccessTools.Field(typeof(ParticleScriptExplosion), "playerHitFullRuckusOverride");

	private void Start()
	{
		particleScriptExplosion = ((Component)this).GetComponent<ParticleScriptExplosion>();
		photonView = ((Component)this).GetComponent<PhotonView>();
		itemGrenade = ((Component)this).GetComponent<ItemGrenade>();
		foreach (KeyValuePair<string, GameObject> prefab in NetworkPrefabs.Prefabs)
		{
			if ((Object)(object)prefab.Value != (Object)null && ((Object)prefab.Value).name.Contains("Yarn Ball Grenade"))
			{
				_networkPath = prefab.Key;
				break;
			}
		}
	}

	public void Explosion()
	{
		//IL_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_0085: Unknown result type (might be due to invalid IL or missing references)
		//IL_0086: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0209: Unknown result type (might be due to invalid IL or missing references)
		//IL_0234: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d0: 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_01dd: Unknown result type (might be due to invalid IL or missing references)
		PlayerAvatar val = (PlayerAvatar)(((Object)(object)itemGrenade != (Object)null) ? /*isinst with value type is only supported in some contexts*/: null);
		int activatorViewId = (((Object)(object)val != (Object)null) ? val.photonView.ViewID : (-1));
		Vector3 val2 = default(Vector3);
		for (int i = 0; i < spawnCount; i++)
		{
			((Vector3)(ref val2))..ctor(Random.Range(-0.3f, 0.3f), 0.2f * (float)i, Random.Range(-0.3f, 0.3f));
			Vector3 val3 = ((Component)this).transform.position + val2;
			GameObject val4 = null;
			if (!SemiFunc.IsMultiplayer())
			{
				if ((Object)(object)grenadePrefab != (Object)null)
				{
					val4 = Object.Instantiate<GameObject>(grenadePrefab, val3, Quaternion.identity);
				}
			}
			else if (SemiFunc.IsMasterClient() && _networkPath != null)
			{
				val4 = PhotonNetwork.Instantiate(_networkPath, val3, Quaternion.identity, (byte)0, (object[])null);
			}
			if ((Object)(object)val4 == (Object)null)
			{
				continue;
			}
			ItemGrenade component = val4.GetComponent<ItemGrenade>();
			if ((Object)(object)component != (Object)null)
			{
				_isSpawnedField?.SetValue(component, true);
				_tickTimeField?.SetValue(component, Random.Range(1.5f, 3f));
				if ((Object)(object)val != (Object)null)
				{
					_setActivatorMethod?.Invoke(component, new object[1] { val });
				}
			}
			((MonoBehaviour)CatsPlugin.Instance).StartCoroutine(ActivateNextFrame(val4, activatorViewId));
		}
		if ((Object)(object)particleScriptExplosion != (Object)null)
		{
			if ((Object)(object)val != (Object)null)
			{
				_causingHurtField?.SetValue(particleScriptExplosion, val);
			}
			_fullRuckusField?.SetValue(particleScriptExplosion, true);
			particleScriptExplosion.Spawn(((Component)this).transform.position, 0.6f, 30, 60, 2f, false, true, 1f);
		}
		soundExplosion.Play(((Component)this).transform.position, 1f, 1f, 1f, 1f);
		soundExplosionGlobal.Play(((Component)this).transform.position, 1f, 1f, 1f, 1f);
	}

	[IteratorStateMachine(typeof(<ActivateNextFrame>d__17))]
	private static IEnumerator ActivateNextFrame(GameObject go, int activatorViewId)
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <ActivateNextFrame>d__17(0)
		{
			go = go,
			activatorViewId = activatorViewId
		};
	}
}
public class StrungUp : MonoBehaviour
{
	public float slowMultiplier = 0.3f;

	public float slowDuration = 3f;

	public float enemySlowSpeed = 0.5f;

	private ParticleSystem _ps;

	private List<ParticleCollisionEvent> _events = new List<ParticleCollisionEvent>();

	private void Awake()
	{
		_ps = ((Component)this).GetComponent<ParticleSystem>();
	}

	private void OnParticleCollision(GameObject other)
	{
		ParticlePhysicsExtensions.GetCollisionEvents(_ps, other, _events);
		PlayerController componentInParent = other.GetComponentInParent<PlayerController>();
		if ((Object)(object)componentInParent != (Object)null)
		{
			componentInParent.OverrideSpeed(slowMultiplier, slowDuration);
			return;
		}
		EnemyNavMeshAgent val = other.GetComponentInParent<EnemyNavMeshAgent>();
		if ((Object)(object)val == (Object)null)
		{
			EnemyRigidbody componentInParent2 = other.GetComponentInParent<EnemyRigidbody>();
			if ((Object)(object)componentInParent2 != (Object)null && (Object)(object)componentInParent2.enemy != (Object)null)
			{
				val = ((Component)componentInParent2.enemy).GetComponentInChildren<EnemyNavMeshAgent>();
			}
		}
		if ((Object)(object)val != (Object)null)
		{
			val.OverrideAgent(enemySlowSpeed, 8f, slowDuration);
		}
	}
}
public class ScriptYarnString : MonoBehaviour
{
	public ParticleSystem[] particles;

	public Material[] particleMaterials;

	public void Explosion()
	{
		Material val = null;
		MaterialVariants componentInChildren = ((Component)this).GetComponentInChildren<MaterialVariants>();
		if ((Object)(object)componentInChildren != (Object)null && particleMaterials != null && componentInChildren.currentVariant < particleMaterials.Length)
		{
			val = particleMaterials[componentInChildren.currentVariant];
		}
		ParticleSystem[] array = particles;
		foreach (ParticleSystem val2 in array)
		{
			((Component)val2).transform.SetParent((Transform)null);
			((Component)val2).gameObject.SetActive(true);
			if ((Object)(object)val != (Object)null)
			{
				((Renderer)((Component)val2).GetComponent<ParticleSystemRenderer>()).material = val;
			}
			val2.Play();
			Object.Destroy((Object)(object)((Component)val2).gameObject, 3f);
		}
	}
}
public class BestExtractingDevice : MonoBehaviour
{
	public float healRate = 3f;

	public int healAmount = 5;

	public int batteryDrainPerHeal = 10;

	private static readonly FieldInfo _isTumbling = AccessTools.Field(typeof(PlayerAvatar), "isTumbling");

	private static readonly FieldInfo _tumble = AccessTools.Field(typeof(PlayerAvatar), "tumble");

	private static readonly FieldInfo _tumblePhysGrabObject = AccessTools.Field(typeof(PlayerTumble), "physGrabObject");

	private static readonly FieldInfo _health = AccessTools.Field(typeof(PlayerHealth), "health");

	private static readonly FieldInfo _maxHealth = AccessTools.Field(typeof(PlayerHealth), "maxHealth");

	private ItemBattery itemBattery;

	private PhotonView photonView;

	private Transform inCart;

	private float healTimer;

	private void Start()
	{
		itemBattery = ((Component)this).GetComponent<ItemBattery>();
		photonView = ((Component)this).GetComponent<PhotonView>();
		inCart = ((Component)this).transform.Find("In Cart");
	}

	[PunRPC]
	private void RemoveBatteryBars(int bars)
	{
		if (SemiFunc.IsMasterClientOrSingleplayer())
		{
			itemBattery.RemoveFullBar(bars);
		}
	}

	private void Update()
	{
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_007e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fd: Expected O, but got Unknown
		//IL_0116: Unknown result type (might be due to invalid IL or missing references)
		//IL_011d: Expected O, but got Unknown
		//IL_012e: Unknown result type (might be due to invalid IL or missing references)
		if (!SemiFunc.IsMasterClientOrSingleplayer() || SemiFunc.RunIsShop() || (Object)(object)inCart == (Object)null || (Object)(object)itemBattery == (Object)null || itemBattery.batteryLife <= 0f)
		{
			return;
		}
		healTimer += Time.deltaTime;
		if (healTimer < healRate)
		{
			return;
		}
		healTimer = 0f;
		Bounds val = default(Bounds);
		((Bounds)(ref val))..ctor(inCart.position, inCart.localScale);
		foreach (PlayerAvatar player in GameDirector.instance.PlayerList)
		{
			if (!(bool)_isTumbling.GetValue(player))
			{
				continue;
			}
			int num = (int)_health.GetValue(player.playerHealth);
			int num2 = (int)_maxHealth.GetValue(player.playerHealth);
			if (num >= num2)
			{
				continue;
			}
			PlayerTumble val2 = (PlayerTumble)_tumble.GetValue(player);
			if ((Object)(object)val2 == (Object)null)
			{
				continue;
			}
			PhysGrabObject val3 = (PhysGrabObject)_tumblePhysGrabObject.GetValue(val2);
			if (!((Object)(object)val3 == (Object)null) && ((Bounds)(ref val)).Contains(val3.centerPoint))
			{
				player.playerHealth.HealOther(healAmount, true);
				int num3 = Mathf.Max(1, Mathf.RoundToInt((float)batteryDrainPerHeal / (100f / (float)itemBattery.batteryBars)));
				if (SemiFunc.IsMultiplayer())
				{
					photonView.RPC("RemoveBatteryBars", (RpcTarget)2, new object[1] { num3 });
				}
				else
				{
					itemBattery.RemoveFullBar(num3);
				}
			}
		}
	}
}
[BepInPlugin("eberk30.cats", "Cats", "1.8.7")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class CatsPlugin : BaseUnityPlugin
{
	[CompilerGenerated]
	private sealed class <AssignCatNames>d__37 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		private float <waited>5__2;

		private int <expected>5__3;

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

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

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

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

		private bool MoveNext()
		{
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0232: Unknown result type (might be due to invalid IL or missing references)
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				<>2__current = null;
				<>1__state = 1;
				return true;
			case 1:
			{
				<>1__state = -1;
				int num = PhotonNetwork.PlayerList.Length - 1;
				Log.LogDebug((object)$"[Cats] requesting configs from {num} other player(s)");
				RequestConfigsEvent.RaiseEvent((object)"", NetworkingEvents.RaiseOthers, SendOptions.SendReliable);
				<waited>5__2 = 0f;
				<expected>5__3 = PhotonNetwork.PlayerList.Length;
				break;
			}
			case 2:
				<>1__state = -1;
				<waited>5__2 += Time.deltaTime;
				break;
			}
			if (_receivedConfigs.Count < <expected>5__3 && <waited>5__2 < 8f)
			{
				<>2__current = null;
				<>1__state = 2;
				return true;
			}
			if (<waited>5__2 >= 8f)
			{
				Log.LogWarning((object)$"[Cats] timed out waiting for name configs ({_receivedConfigs.Count}/{<expected>5__3})");
			}
			StringBuilder stringBuilder = new StringBuilder();
			ValuableObject[] array = Object.FindObjectsOfType<ValuableObject>();
			foreach (ValuableObject val in array)
			{
				string catType = GetCatType(((Object)((Component)val).gameObject).name);
				if (catType == null)
				{
					continue;
				}
				PhotonView component = ((Component)val).GetComponent<PhotonView>();
				if ((Object)(object)component == (Object)null)
				{
					continue;
				}
				List<string> list = new List<string>();
				foreach (string value2 in _receivedConfigs.Values)
				{
					list.AddRange(GetNames(value2, catType));
				}
				if (list.Count != 0)
				{
					string value = list[Random.Range(0, list.Count)];
					AssignedNames[component.ViewID] = value;
					if (stringBuilder.Length > 0)
					{
						stringBuilder.Append('|');
					}
					stringBuilder.Append(component.ViewID).Append('=').Append(value);
				}
			}
			if (stringBuilder.Length > 0)
			{
				AssignNamesEvent.RaiseEvent((object)stringBuilder.ToString(), NetworkingEvents.RaiseAll, SendOptions.SendReliable);
			}
			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();
		}
	}

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

		private object <>2__current;

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

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

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

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

		private bool MoveNext()
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				break;
			case 1:
				<>1__state = -1;
				break;
			}
			if (Valuables.RegisteredValuables.Count == 0)
			{
				<>2__current = (object)new WaitForSeconds(0.5f);
				<>1__state = 1;
				return true;
			}
			BakeItemAttributesIntoCatPrefabs();
			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 CatsPlugin Instance;

	internal static ManualLogSource Log;

	public static ConfigEntry<bool> ControlledSpawning;

	public static ConfigEntry<int> SpawnCount;

	public static ConfigEntry<int> CommonWeight;

	public static ConfigEntry<int> UncommonWeight;

	public static ConfigEntry<int> RareWeight;

	public static ConfigEntry<int> CustomWeight;

	internal static readonly Dictionary<string, ConfigEntry<string>> DisplayNames = new Dictionary<string, ConfigEntry<string>>();

	internal static readonly Dictionary<string, string> DefaultNames = new Dictionary<string, string>();

	internal static readonly HashSet<string> CatPrefabNames = new HashSet<string>();

	private static readonly string[] _displayNameCats = new string[19]
	{
		"Alien Cat", "Black Cat", "Blue Point", "Calico", "Cyberpunk Cat", "Galaxy Cat", "Gray Tabby", "Munchkin", "Orange Tabby", "Pallas Cat",
		"Photosynthesis Cat", "Pink Cat", "Russian Blue", "Scottish Fold", "Siamese", "Sphynx", "Tortoise", "Tuxedo", "White Cat"
	};

	private static bool _genesisPresent;

	public static NetworkedEvent ShareNamesEvent;

	public static NetworkedEvent AssignNamesEvent;

	public static NetworkedEvent RequestConfigsEvent;

	public static NetworkedEvent AssignVariantsEvent;

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

	internal static readonly Dictionary<int, string> AssignedNames = new Dictionary<int, string>();

	internal static readonly Dictionary<int, int> AssignedVariants = new Dictionary<int, int>();

	private static Dictionary<string, HashSet<int>> _prevLevelVariants = new Dictionary<string, HashSet<int>>();

	private static Dictionary<string, HashSet<int>> _thisLevelVariants = new Dictionary<string, HashSet<int>>();

	private static bool _sentThisLevel = false;

	private static string _lastLevel = "";

	private void Awake()
	{
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_0072: Expected O, but got Unknown
		//IL_009b: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a5: Expected O, but got Unknown
		//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d8: Expected O, but got Unknown
		//IL_0101: Unknown result type (might be due to invalid IL or missing references)
		//IL_010b: Expected O, but got Unknown
		//IL_0134: Unknown result type (might be due to invalid IL or missing references)
		//IL_013e: Expected O, but got Unknown
		//IL_019d: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a7: Expected O, but got Unknown
		//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c2: Expected O, but got Unknown
		//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01dd: Expected O, but got Unknown
		//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f8: Expected O, but got Unknown
		//IL_020d: Unknown result type (might be due to invalid IL or missing references)
		Instance = this;
		Log = ((BaseUnityPlugin)this).Logger;
		_genesisPresent = Chainloader.PluginInfos.ContainsKey("eberk30.genesis");
		ControlledSpawning = ((BaseUnityPlugin)this).Config.Bind<bool>("Controlled Spawning", "Controlled Spawning", false, "Take over spawning. On = Control spawning using count/weight settings below; Off = let the game spawn cats normally.");
		SpawnCount = ((BaseUnityPlugin)this).Config.Bind<int>("Controlled Spawning", "Spawn Count", 3, new ConfigDescription("How many cats appear per level.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 20), Array.Empty<object>()));
		CommonWeight = ((BaseUnityPlugin)this).Config.Bind<int>("Controlled Spawning", "Common Weight", 90, new ConfigDescription("Relative spawn weight for Common rarity cats. Higher = more frequent.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
		UncommonWeight = ((BaseUnityPlugin)this).Config.Bind<int>("Controlled Spawning", "Uncommon Weight", 60, new ConfigDescription("Relative spawn weight for Uncommon rarity cats. Higher = more frequent.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
		RareWeight = ((BaseUnityPlugin)this).Config.Bind<int>("Controlled Spawning", "Rare Weight", 20, new ConfigDescription("Relative spawn weight for Rare rarity cats. Higher = more frequent.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
		CustomWeight = ((BaseUnityPlugin)this).Config.Bind<int>("Controlled Spawning", "Custom Weight", 50, new ConfigDescription("Relative spawn weight for Custom rarity cats. Higher = more frequent.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
		string[] displayNameCats = _displayNameCats;
		foreach (string text in displayNameCats)
		{
			DisplayNames[text] = ((BaseUnityPlugin)this).Config.Bind<string>("Cat Names", text, "", "Name shown when holding " + text + ". Comma-separate for random pick: Bob, Bill. Leave blank for no name.");
		}
		ShareNamesEvent = new NetworkedEvent("ShareNames", (Action<EventData>)OnShareNames);
		AssignNamesEvent = new NetworkedEvent("AssignNames", (Action<EventData>)OnAssignNames);
		RequestConfigsEvent = new NetworkedEvent("RequestConfigs", (Action<EventData>)OnRequestConfigs);
		AssignVariantsEvent = new NetworkedEvent("AssignVariants", (Action<EventData>)OnAssignVariants);
		((MonoBehaviour)Instance).StartCoroutine(BakeWhenReady());
		new Harmony("eberk30.cats").PatchAll();
	}

	[IteratorStateMachine(typeof(<BakeWhenReady>d__13))]
	private static IEnumerator BakeWhenReady()
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <BakeWhenReady>d__13(0);
	}

	internal static void BakeItemAttributesIntoCatPrefabs()
	{
		//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e0: Expected O, but got Unknown
		foreach (PrefabRef registeredValuable in Valuables.RegisteredValuables)
		{
			if (!NetworkPrefabs.Prefabs.TryGetValue(((PrefabRef<GameObject>)(object)registeredValuable).ResourcePath, out var value) || (Object)(object)value == (Object)null)
			{
				continue;
			}
			CatRarity component = value.GetComponent<CatRarity>();
			if ((Object)(object)component == (Object)null || (_genesisPresent && ((PrefabRef<GameObject>)(object)registeredValuable).PrefabName == "Genesis") || !CatPrefabNames.Add(((PrefabRef<GameObject>)(object)registeredValuable).PrefabName))
			{
				continue;
			}
			if ((Object)(object)value.GetComponent<ItemAttributes>() == (Object)null)
			{
				value.AddComponent<ItemAttributes>();
			}
			if (!component.noDisplayName)
			{
				if (!string.IsNullOrEmpty(component.defaultName))
				{
					DefaultNames[((PrefabRef<GameObject>)(object)registeredValuable).PrefabName] = component.defaultName;
					((BaseUnityPlugin)Instance).Config.Remove(new ConfigDefinition("Cat Names", ((PrefabRef<GameObject>)(object)registeredValuable).PrefabName));
					DisplayNames.Remove(((PrefabRef<GameObject>)(object)registeredValuable).PrefabName);
				}
				else
				{
					DisplayNames[((PrefabRef<GameObject>)(object)registeredValuable).PrefabName] = ((BaseUnityPlugin)Instance).Config.Bind<string>("Cat Names", ((PrefabRef<GameObject>)(object)registeredValuable).PrefabName, "", "Name shown when holding " + ((PrefabRef<GameObject>)(object)registeredValuable).PrefabName + ". Comma-separate for random pick: Bob, Bill. Leave blank for no name.");
				}
			}
			Log.LogDebug((object)$"[Cats] baked {((PrefabRef<GameObject>)(object)registeredValuable).PrefabName} rarity={component.rarity}");
		}
	}

	internal static string GetCatType(string name)
	{
		foreach (string catPrefabName in CatPrefabNames)
		{
			if (name.Contains(catPrefabName))
			{
				return catPrefabName;
			}
		}
		return null;
	}

	internal static bool IsCat(string name)
	{
		return GetCatType(name) != null;
	}

	internal static int PickVariant(string typeKey, int count)
	{
		HashSet<int> exclude = new HashSet<int>();
		if (_prevLevelVariants.TryGetValue(typeKey, out var value))
		{
			exclude.UnionWith(value);
		}
		if (_thisLevelVariants.TryGetValue(typeKey, out var value2))
		{
			exclude.UnionWith(value2);
		}
		int[] array = ((exclude.Count >= count) ? Enumerable.Range(0, count).ToArray() : (from i in Enumerable.Range(0, count)
			where !exclude.Contains(i)
			select i).ToArray());
		int num = array[Random.Range(0, array.Length)];
		if (!_thisLevelVariants.TryGetValue(typeKey, out var value3))
		{
			value3 = (_thisLevelVariants[typeKey] = new HashSet<int>());
		}
		value3.Add(num);
		return num;
	}

	private static void OnShareNames(EventData photonEvent)
	{
		if (photonEvent.CustomData is string text)
		{
			_receivedConfigs[photonEvent.Sender] = text;
			Log.LogDebug((object)$"[Cats] got config from actor {photonEvent.Sender} ({text.Length} bytes)");
		}
	}

	private static void OnRequestConfigs(EventData photonEvent)
	{
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		Log.LogDebug((object)$"[Cats] received config request (isMaster={SemiFunc.IsMasterClientOrSingleplayer()})");
		if (!SemiFunc.IsMasterClientOrSingleplayer())
		{
			ShareNamesEvent.RaiseEvent((object)PackConfig(), NetworkingEvents.RaiseMasterClient, SendOptions.SendReliable);
			Log.LogDebug((object)"[Cats] replied with config");
		}
	}

	private static void OnAssignNames(EventData photonEvent)
	{
		if (!(photonEvent.CustomData is string text))
		{
			return;
		}
		string[] array = text.Split(new char[1] { '|' });
		foreach (string text2 in array)
		{
			int num = text2.IndexOf('=');
			if (num >= 0)
			{
				if (!int.TryParse(text2.Substring(0, num), out var result))
				{
					Log.LogWarning((object)("[Cats] couldn't parse viewID: " + text2));
				}
				else
				{
					AssignedNames[result] = text2.Substring(num + 1);
				}
			}
		}
		ValuableObject[] array2 = Object.FindObjectsOfType<ValuableObject>();
		foreach (ValuableObject val in array2)
		{
			PhotonView component = ((Component)val).GetComponent<PhotonView>();
			if (!((Object)(object)component == (Object)null) && AssignedNames.TryGetValue(component.ViewID, out var value))
			{
				ItemAttributes component2 = ((Component)val).GetComponent<ItemAttributes>();
				if ((Object)(object)component2 != (Object)null && (Object)(object)component2.item != (Object)null)
				{
					component2.item.itemName = value;
				}
			}
		}
	}

	private static void OnAssignVariants(EventData photonEvent)
	{
		if (!(photonEvent.CustomData is string text))
		{
			return;
		}
		string[] array = text.Split(new char[1] { '|' });
		foreach (string text2 in array)
		{
			int num = text2.IndexOf('=');
			if (num >= 0 && int.TryParse(text2.Substring(0, num), out var result) && int.TryParse(text2.Substring(num + 1), out var result2))
			{
				AssignedVariants[result] = result2;
			}
		}
		ItemAttributes[] array2 = Object.FindObjectsOfType<ItemAttributes>();
		foreach (ItemAttributes val in array2)
		{
			MaterialVariants componentInChildren = ((Component)val).GetComponentInChildren<MaterialVariants>();
			if ((Object)(object)componentInChildren == (Object)null)
			{
				continue;
			}
			PhotonView component = ((Component)val).GetComponent<PhotonView>();
			if ((Object)(object)component == (Object)null || !AssignedVariants.TryGetValue(component.ViewID, out var value) || componentInChildren.variants == null || value >= componentInChildren.variants.Length)
			{
				continue;
			}
			MeshRenderer[] componentsInChildren = ((Component)val).GetComponentsInChildren<MeshRenderer>();
			if (componentsInChildren.Length == 0)
			{
				continue;
			}
			MeshRenderer[] array3 = componentsInChildren;
			for (int j = 0; j < array3.Length; j++)
			{
				((Renderer)array3[j]).material = componentInChildren.variants[value];
			}
			if (componentInChildren.variants[value].HasProperty("_FresnelScale"))
			{
				continue;
			}
			ItemLight[] componentsInChildren2 = ((Component)val).GetComponentsInChildren<ItemLight>();
			foreach (ItemLight val2 in componentsInChildren2)
			{
				array3 = componentsInChildren;
				foreach (MeshRenderer item in array3)
				{
					val2.meshRenderers.Remove(item);
				}
			}
		}
	}

	private static string PackConfig()
	{
		return string.Join("|", DisplayNames.Select((KeyValuePair<string, ConfigEntry<string>> kvp) => kvp.Key + "=" + kvp.Value.Value));
	}

	internal static void TrySendConfig()
	{
		//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
		RunManager instance = RunManager.instance;
		object obj;
		if (instance == null)
		{
			obj = null;
		}
		else
		{
			Level levelCurrent = instance.levelCurrent;
			obj = ((levelCurrent != null) ? ((Object)levelCurrent).name : null);
		}
		if (obj == null)
		{
			obj = "";
		}
		Room currentRoom = PhotonNetwork.CurrentRoom;
		string text = (string?)obj + "|" + ((currentRoom != null) ? currentRoom.Name : null);
		if (text != _lastLevel)
		{
			_lastLevel = text;
			_sentThisLevel = false;
			AssignedNames.Clear();
			AssignedVariants.Clear();
			if (SemiFunc.IsMasterClientOrSingleplayer())
			{
				_receivedConfigs.Clear();
				_prevLevelVariants = _thisLevelVariants;
				_thisLevelVariants = new Dictionary<string, HashSet<int>>();
			}
		}
		if (!_sentThisLevel && PhotonNetwork.InRoom)
		{
			_sentThisLevel = true;
			if (SemiFunc.IsMasterClientOrSingleplayer())
			{
				_receivedConfigs[PhotonNetwork.LocalPlayer.ActorNumber] = PackConfig();
				Log.LogDebug((object)"[Cats] host stored own config");
			}
			else
			{
				ShareNamesEvent.RaiseEvent((object)PackConfig(), NetworkingEvents.RaiseMasterClient, SendOptions.SendReliable);
				Log.LogDebug((object)"[Cats] client sent config to master");
			}
		}
	}

	private static List<string> GetNames(string serialized, string catType)
	{
		List<string> list = new List<string>();
		string text = catType + "=";
		string[] array = serialized.Split(new char[1] { '|' });
		foreach (string text2 in array)
		{
			if (!text2.StartsWith(text))
			{
				continue;
			}
			string[] array2 = text2.Substring(text.Length).Split(new char[1] { ',' });
			for (int j = 0; j < array2.Length; j++)
			{
				string text3 = array2[j].Trim();
				if (text3.Length > 0)
				{
					list.Add(text3);
				}
			}
			break;
		}
		return list;
	}

	[IteratorStateMachine(typeof(<AssignCatNames>d__37))]
	internal IEnumerator AssignCatNames()
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <AssignCatNames>d__37(0);
	}
}
[HarmonyPatch(typeof(ValuableObject), "Start")]
internal static class AttributesPatch
{
	[HarmonyPostfix]
	private static void Postfix(ValuableObject __instance)
	{
		if (CatsPlugin.IsCat(((Object)((Component)__instance).gameObject).name) && !((Object)(object)((Component)__instance).gameObject.GetComponent<ItemAttributes>() != (Object)null))
		{
			((Component)__instance).gameObject.AddComponent<ItemAttributes>();
		}
	}
}
[HarmonyPatch(typeof(ItemAttributes), "Awake")]
internal static class AwakePatch
{
	[HarmonyPostfix]
	private static void Postfix(ItemAttributes __instance)
	{
		//IL_025c: Unknown result type (might be due to invalid IL or missing references)
		if (CatsPlugin.CatPrefabNames.Count == 0)
		{
			CatsPlugin.BakeItemAttributesIntoCatPrefabs();
		}
		string catType = CatsPlugin.GetCatType(((Object)((Component)__instance).gameObject).name);
		if (catType != null)
		{
			CatsPlugin.TrySendConfig();
			if ((Object)(object)__instance.item == (Object)null)
			{
				Item val = ScriptableObject.CreateInstance<Item>();
				val.value = ScriptableObject.CreateInstance<Value>();
				PhotonView component = ((Component)__instance).GetComponent<PhotonView>();
				string value2;
				if ((Object)(object)component != (Object)null && CatsPlugin.AssignedNames.TryGetValue(component.ViewID, out var value))
				{
					val.itemName = value;
				}
				else if (CatsPlugin.DefaultNames.TryGetValue(catType, out value2))
				{
					val.itemName = value2;
				}
				else
				{
					ConfigEntry<string> value3;
					string[] array = (from s in (CatsPlugin.DisplayNames.TryGetValue(catType, out value3) ? value3.Value : "").Split(new char[1] { ',' })
						select s.Trim() into s
						where s.Length > 0
						select s).ToArray();
					val.itemName = ((array.Length != 0) ? array[Random.Range(0, array.Length)] : "");
				}
				__instance.item = val;
			}
		}
		PhotonView component2 = ((Component)__instance).GetComponent<PhotonView>();
		if ((Object)(object)component2 == (Object)null)
		{
			return;
		}
		MaterialVariants componentInChildren = ((Component)__instance).GetComponentInChildren<MaterialVariants>();
		if ((Object)(object)componentInChildren == (Object)null || componentInChildren.variants == null || componentInChildren.variants.Length == 0)
		{
			return;
		}
		MeshRenderer[] componentsInChildren = ((Component)__instance).GetComponentsInChildren<MeshRenderer>();
		if (componentsInChildren.Length == 0)
		{
			return;
		}
		bool flag = false;
		if (CatsPlugin.AssignedVariants.TryGetValue(component2.ViewID, out var value4))
		{
			MeshRenderer[] array2 = componentsInChildren;
			for (int i = 0; i < array2.Length; i++)
			{
				((Renderer)array2[i]).material = componentInChildren.variants[value4];
			}
			flag = true;
		}
		else if (SemiFunc.IsMasterClientOrSingleplayer())
		{
			value4 = CatsPlugin.PickVariant(catType ?? ((Object)((Component)__instance).gameObject).name, componentInChildren.variants.Length);
			CatsPlugin.AssignedVariants[component2.ViewID] = value4;
			MeshRenderer[] array2 = componentsInChildren;
			for (int i = 0; i < array2.Length; i++)
			{
				((Renderer)array2[i]).material = componentInChildren.variants[value4];
			}
			CatsPlugin.AssignVariantsEvent.RaiseEvent((object)(component2.ViewID + "=" + value4), NetworkingEvents.RaiseOthers, SendOptions.SendReliable);
			flag = true;
		}
		if (flag)
		{
			componentInChildren.currentVariant = value4;
			string text = ((Object)((Component)__instance).gameObject).name.Replace("(Clone)", "").ToLowerInvariant();
			string path = Path.Combine(Application.persistentDataPath, "Cache", "Icons", "Items", text + ".png");
			if (File.Exists(path))
			{
				File.Delete(path);
			}
		}
	}
}
[HarmonyPatch(typeof(ItemAttributes), "Start")]
internal static class StartPatch
{
	[HarmonyPrefix]
	private static void Prefix(ItemAttributes __instance)
	{
		if (CatsPlugin.GetCatType(((Object)((Component)__instance).gameObject).name) != null)
		{
			CatsPlugin.TrySendConfig();
			if (!((Object)(object)__instance.item != (Object)null))
			{
				Item val = ScriptableObject.CreateInstance<Item>();
				val.value = ScriptableObject.CreateInstance<Value>();
				val.itemName = "";
				__instance.item = val;
			}
		}
	}

	[HarmonyPostfix]
	private static void Postfix(ItemAttributes __instance)
	{
		if (CatsPlugin.GetCatType(((Object)((Component)__instance).gameObject).name) != null)
		{
			ItemManager instance = ItemManager.instance;
			if ((Object)(object)instance != (Object)null)
			{
				instance.spawnedItems.Remove(__instance);
			}
		}
	}
}
[HarmonyPatch(typeof(BatteryVisualLogic), "BatteryBarsSet")]
internal static class BatteryBarsPatch
{
	[HarmonyPrefix]
	private static bool Prefix(BatteryVisualLogic __instance)
	{
		if ((Object)(object)__instance.batteryBarPrefab != (Object)null)
		{
			return true;
		}
		BatteryVisualLogic[] array = Object.FindObjectsOfType<BatteryVisualLogic>();
		foreach (BatteryVisualLogic val in array)
		{
			if ((Object)(object)val != (Object)(object)__instance && (Object)(object)val.batteryBarPrefab != (Object)null)
			{
				__instance.batteryBarPrefab = val.batteryBarPrefab;
				return true;
			}
		}
		return false;
	}
}
[HarmonyPatch(typeof(ItemBattery), "BatteryChargeStartRPC")]
internal static class ItemBatteryChargePatch
{
	private static readonly FieldInfo _bvl = AccessTools.Field(typeof(ItemBattery), "batteryVisualLogic");

	private static readonly FieldInfo _isCharging = AccessTools.Field(typeof(ItemBattery), "isCharging");

	[HarmonyPostfix]
	private static void Postfix(ItemBattery __instance)
	{
		if (_bvl.GetValue(__instance) == null)
		{
			_isCharging.SetValue(__instance, false);
		}
	}
}
[HarmonyPatch(typeof(ItemAttributes), "ShowingInfo")]
internal static class CatNamePatch
{
	private static readonly FieldInfo _promptName = AccessTools.Field(typeof(ItemAttributes), "promptName");

	[HarmonyPostfix]
	private static void Postfix(ItemAttributes __instance)
	{
		if ((Object)(object)__instance.item == (Object)null)
		{
			return;
		}
		string name = ((Object)((Component)__instance).gameObject).name;
		foreach (string catPrefabName in CatsPlugin.CatPrefabNames)
		{
			if (name.Contains(catPrefabName))
			{
				_promptName.SetValue(__instance, __instance.item.itemName);
				break;
			}
		}
	}
}
[HarmonyPatch(typeof(ItemToggle), "ToggleItemLogic")]
internal static class SoundPatch
{
	[HarmonyPostfix]
	private static void Postfix(ItemToggle __instance, bool toggle)
	{
		if (!toggle || !CatsPlugin.IsCat(((Object)((Component)__instance).gameObject).name))
		{
			return;
		}
		PhysGrabObject component = ((Component)__instance).GetComponent<PhysGrabObject>();
		if (!((Object)(object)component == (Object)null) && component.grabbedLocal)
		{
			AudioSource component2 = ((Component)__instance).GetComponent<AudioSource>();
			if ((Object)(object)component2 != (Object)null)
			{
				component2.Play();
			}
		}
	}
}
[HarmonyPatch(typeof(ValuableDirector), "SetupHost")]
internal static class SpawnPatch
{
	[CompilerGenerated]
	private sealed class <>c__DisplayClass3_0
	{
		public bool isMuseum;

		public List<Vector3> occupied;

		public int geoMask;

		public int geoSkipped;

		public Predicate<Tuple<Vector3, Quaternion>> <>9__1;

		internal bool <SpawnCats>b__0(PrefabRef v)
		{
			if (CatsPlugin.CatPrefabNames.Contains(((PrefabRef<GameObject>)(object)v).PrefabName))
			{
				if (!isMuseum && !((Object)(object)((PrefabRef<GameObject>)(object)v).Prefab == (Object)null))
				{
					return !((PrefabRef<GameObject>)(object)v).Prefab.GetComponent<CatRarity>().museumOnly;
				}
				return true;
			}
			return false;
		}

		internal bool <SpawnCats>b__1(Tuple<Vector3, Quaternion> v)
		{
			//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_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			Vector3 item = v.Item1;
			for (int i = 0; i < occupied.Count; i++)
			{
				Vector3 val = occupied[i] - item;
				if (((Vector3)(ref val)).sqrMagnitude < 1f)
				{
					return true;
				}
			}
			return false;
		}
	}

	[CompilerGenerated]
	private sealed class <>c__DisplayClass3_1
	{
		public Vector3 s;

		public <>c__DisplayClass3_0 CS$<>8__locals1;

		internal bool <SpawnCats>b__2(Tuple<Vector3, Quaternion> v)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_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)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			if (Physics.OverlapBox(v.Item1 + v.Item2 * Vector3.forward * (s.z / 2f) + v.Item2 * Vector3.up * (s.y / 2f) + Vector3.up * 0.01f, s / 2f, v.Item2, CS$<>8__locals1.geoMask, (QueryTriggerInteraction)1).Length != 0)
			{
				int geoSkipped = CS$<>8__locals1.geoSkipped;
				CS$<>8__locals1.geoSkipped = geoSkipped + 1;
				return true;
			}
			return false;
		}
	}

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

		private object <>2__current;

		private <>c__DisplayClass3_0 <>8__1;

		public Dictionary<Type, List<Tuple<Vector3, Quaternion>>> volumesByType;

		public ValuableDirector director;

		private int <prev>5__2;

		private int <stable>5__3;

		private float <waited>5__4;

		private List<PrefabRef> <pool>5__5;

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

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

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

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<>8__1 = null;
			<pool>5__5 = null;
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Expected O, but got Unknown
			//IL_022a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Expected O, but got Unknown
			//IL_030b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0310: Unknown result type (might be due to invalid IL or missing references)
			//IL_0315: Unknown result type (might be due to invalid IL or missing references)
			//IL_056c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0596: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_05f6: Unknown result type (might be due to invalid IL or missing references)
			ValuableObject[] array;
			int num2;
			ValuableObject[] array2;
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				<>8__1 = new <>c__DisplayClass3_0();
				CatsPlugin.Log.LogDebug((object)"[Cats] SpawnCats coroutine started");
				if (CatsPlugin.CatPrefabNames.Count == 0)
				{
					CatsPlugin.BakeItemAttributesIntoCatPrefabs();
				}
				<prev>5__2 = -1;
				<stable>5__3 = 0;
				<waited>5__4 = 0f;
				goto IL_00d0;
			case 1:
			{
				<>1__state = -1;
				<waited>5__4 += 0.2f;
				int num = Object.FindObjectsOfType<ValuableObject>().Length;
				if (num == <prev>5__2)
				{
					<stable>5__3++;
				}
				else
				{
					<stable>5__3 = 0;
					<prev>5__2 = num;
				}
				goto IL_00d0;
			}
			case 2:
				{
					<>1__state = -1;
					array = Object.FindObjectsOfType<ValuableObject>();
					break;
				}
				IL_00d0:
				if (<stable>5__3 < 3 || <waited>5__4 < 1f)
				{
					<>2__current = (object)new WaitForSeconds(0.2f);
					<>1__state = 1;
					return true;
				}
				CatsPlugin.Log.LogDebug((object)$"[Cats] stability check done — {<prev>5__2} valuables in scene");
				<>8__1.isMuseum = ((Object)RunManager.instance.levelCurrent).name == "Level - Museum";
				<pool>5__5 = Valuables.RegisteredValuables.Where((PrefabRef v) => CatsPlugin.CatPrefabNames.Contains(((PrefabRef<GameObject>)(object)v).PrefabName) && (<>8__1.isMuseum || (Object)(object)((PrefabRef<GameObject>)(object)v).Prefab == (Object)null || !((PrefabRef<GameObject>)(object)v).Prefab.GetComponent<CatRarity>().museumOnly)).ToList();
				if (<pool>5__5.Count == 0)
				{
					CatsPlugin.Log.LogWarning((object)"[Cats] cat pool is empty, nothing to spawn");
					return false;
				}
				array = Object.FindObjectsOfType<ValuableObject>();
				num2 = 0;
				array2 = array;
				foreach (ValuableObject val in array2)
				{
					if (CatsPlugin.IsCat(((Object)((Component)val).gameObject).name))
					{
						PhotonNetwork.Destroy(((Component)val).gameObject);
						num2++;
					}
				}
				if (num2 > 0)
				{
					CatsPlugin.Log.LogDebug((object)$"[Cats] removed {num2} naturally spawned cats");
					<>2__current = (object)new WaitForSeconds(0.1f);
					<>1__state = 2;
					return true;
				}
				break;
			}
			<>8__1.occupied = new List<Vector3>();
			array2 = array;
			foreach (ValuableObject val2 in array2)
			{
				<>8__1.occupied.Add(((Component)val2).transform.position);
			}
			foreach (List<Tuple<Vector3, Quaternion>> value6 in volumesByType.Values)
			{
				value6.RemoveAll(delegate(Tuple<Vector3, Quaternion> v)
				{
					//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_0012: Unknown result type (might be due to invalid IL or missing references)
					//IL_0017: Unknown result type (might be due to invalid IL or missing references)
					//IL_0018: Unknown result type (might be due to invalid IL or missing references)
					//IL_001d: Unknown result type (might be due to invalid IL or missing references)
					Vector3 item = v.Item1;
					for (int j = 0; j < <>8__1.occupied.Count; j++)
					{
						Vector3 val5 = <>8__1.occupied[j] - item;
						if (((Vector3)(ref val5)).sqrMagnitude < 1f)
						{
							return true;
						}
					}
					return false;
				});
			}
			<>8__1.geoMask = LayerMask.GetMask(new string[1] { "Default" });
			<>8__1.geoSkipped = 0;
			foreach (KeyValuePair<Type, List<Tuple<Vector3, Quaternion>>> item2 in volumesByType)
			{
				<>c__DisplayClass3_1 CS$<>8__locals0 = new <>c__DisplayClass3_1
				{
					CS$<>8__locals1 = <>8__1,
					s = _volSizes[item2.Key]
				};
				item2.Value.RemoveAll(delegate(Tuple<Vector3, Quaternion> v)
				{
					//IL_0001: Unknown result type (might be due to invalid IL or missing references)
					//IL_0007: Unknown result type (might be due to invalid IL or missing references)
					//IL_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_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)
					//IL_0032: Unknown result type (might be due to invalid IL or missing references)
					//IL_0037: Unknown result type (might be due to invalid IL or missing references)
					//IL_003c: Unknown result type (might be due to invalid IL or missing references)
					//IL_0052: Unknown result type (might be due to invalid IL or missing references)
					//IL_0057: Unknown result type (might be due to invalid IL or missing references)
					//IL_005c: Unknown result type (might be due to invalid IL or missing references)
					//IL_0066: Unknown result type (might be due to invalid IL or missing references)
					//IL_006b: Unknown result type (might be due to invalid IL or missing references)
					//IL_0071: Unknown result type (might be due to invalid IL or missing references)
					//IL_007b: Unknown result type (might be due to invalid IL or missing references)
					//IL_0081: Unknown result type (might be due to invalid IL or missing references)
					if (Physics.OverlapBox(v.Item1 + v.Item2 * Vector3.forward * (CS$<>8__locals0.s.z / 2f) + v.Item2 * Vector3.up * (CS$<>8__locals0.s.y / 2f) + Vector3.up * 0.01f, CS$<>8__locals0.s / 2f, v.Item2, CS$<>8__locals0.CS$<>8__locals1.geoMask, (QueryTriggerInteraction)1).Length != 0)
					{
						int geoSkipped = CS$<>8__locals0.CS$<>8__locals1.geoSkipped;
						CS$<>8__locals0.CS$<>8__locals1.geoSkipped = geoSkipped + 1;
						return true;
					}
					return false;
				});
			}
			if (<>8__1.geoSkipped > 0)
			{
				CatsPlugin.Log.LogDebug((object)$"[Cats] {<>8__1.geoSkipped} volumes blocked by geometry");
			}
			int num3 = CatsPlugin.CommonWeight.Value + CatsPlugin.UncommonWeight.Value + CatsPlugin.RareWeight.Value + CatsPlugin.CustomWeight.Value;
			if (num3 <= 0)
			{
				CatsPlugin.Log.LogWarning((object)"[Cats] all weights are 0, nothing to spawn");
				return false;
			}
			List<PrefabRef> list = new List<PrefabRef>();
			List<PrefabRef> list2 = new List<PrefabRef>();
			List<PrefabRef> list3 = new List<PrefabRef>();
			List<PrefabRef> list4 = new List<PrefabRef>();
			foreach (PrefabRef item3 in <pool>5__5)
			{
				switch (((PrefabRef<GameObject>)(object)item3).Prefab.GetComponent<CatRarity>().rarity)
				{
				case Rarity.Common:
					list.Add(item3);
					break;
				case Rarity.Uncommon:
					list2.Add(item3);
					break;
				case Rarity.Rare:
					list3.Add(item3);
					break;
				case Rarity.Custom:
					list4.Add(item3);
					break;
				}
			}
			int value = CatsPlugin.SpawnCount.Value;
			int num4 = 0;
			int num5 = 0;
			while (num4 < value && num5 < 60)
			{
				num5++;
				int num6 = Random.Range(0, num3);
				int value2 = CatsPlugin.CommonWeight.Value;
				int value3 = CatsPlugin.UncommonWeight.Value;
				int value4 = CatsPlugin.RareWeight.Value;
				Rarity rarity = ((num6 >= value2) ? ((num6 < value2 + value3) ? Rarity.Uncommon : ((num6 >= value2 + value3 + value4) ? Rarity.Custom : Rarity.Rare)) : Rarity.Common);
				List<PrefabRef> list5 = rarity switch
				{
					Rarity.Rare => list3, 
					Rarity.Uncommon => list2, 
					Rarity.Common => list, 
					_ => list4, 
				};
				if (list5.Count == 0)
				{
					CatsPlugin.Log.LogDebug((object)$"[Cats] rolled {rarity} but that pool is empty");
					continue;
				}
				PrefabRef val3 = list5[Random.Range(0, list5.Count)];
				ValuableObject val4 = (((Object)(object)((PrefabRef<GameObject>)(object)val3).Prefab != (Object)null) ? ((PrefabRef<GameObject>)(object)val3).Prefab.GetComponent<ValuableObject>() : null);
				if (!((Object)(object)val4 == (Object)null))
				{
					if (!volumesByType.TryGetValue(val4.volumeType, out var value5) || value5.Count == 0)
					{
						CatsPlugin.Log.LogDebug((object)$"[Cats] no volumes left for {((PrefabRef<GameObject>)(object)val3).PrefabName} (type {val4.volumeType})");
						continue;
					}
					int num7 = Random.Range(0, value5.Count);
					CatsPlugin.Log.LogInfo((object)$"[Cats] spawning {((PrefabRef<GameObject>)(object)val3).PrefabName} at volume slot {num7}");
					Valuables.SpawnValuable(val3, value5[num7].Item1, value5[num7].Item2);
					value5.RemoveAt(num7);
					num4++;
				}
			}
			CatsPlugin.Log.LogInfo((object)$"[Cats] spawned {num4}/{value} cats ({num5} attempts)");
			if (num4 > 0)
			{
				((MonoBehaviour)director).StartCoroutine(CatsPlugin.Instance.AssignCatNames());
			}
			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();
		}
	}

	private static readonly Dictionary<Type, Vector3> _volSizes = new Dictionary<Type, Vector3>
	{
		{
			(Type)0,
			new Vector3(0.25f, 0.25f, 0.25f)
		},
		{
			(Type)1,
			new Vector3(0.5f, 0.5f, 0.5f)
		},
		{
			(Type)2,
			new Vector3(0.826f, 1f, 0.826f)
		},
		{
			(Type)3,
			new Vector3(1.25f, 1.5f, 1.25f)
		},
		{
			(Type)4,
			new Vector3(3f, 2.4f, 1.2f)
		},
		{
			(Type)5,
			new Vector3(2.4f, 3f, 1.2f)
		},
		{
			(Type)6,
			new Vector3(1.25f, 3.5f, 1.25f)
		}
	};

	[HarmonyPostfix]
	private static void Postfix(ValuableDirector __instance)
	{
		try
		{
			PostfixBody(__instance);
		}
		catch (Exception arg)
		{
			CatsPlugin.Log.LogError((object)$"[Cats] SpawnPatch failed: {arg}");
		}
	}

	private static void PostfixBody(ValuableDirector __instance)
	{
		//IL_0085: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b7: 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_0094: Unknown result type (might be due to invalid IL or missing references)
		if (!SemiFunc.IsMasterClientOrSingleplayer())
		{
			return;
		}
		RunManager instance = RunManager.instance;
		Level levelCurrent = instance.levelCurrent;
		if ((Object)(object)levelCurrent == (Object)(object)instance.levelMainMenu || (Object)(object)levelCurrent == (Object)(object)instance.levelLobbyMenu || (Object)(object)levelCurrent == (Object)(object)instance.levelLobby || !PhotonNetwork.InRoom)
		{
			return;
		}
		CatsPlugin.TrySendConfig();
		if (!CatsPlugin.ControlledSpawning.Value)
		{
			((MonoBehaviour)__instance).StartCoroutine(CatsPlugin.Instance.AssignCatNames());
			return;
		}
		Dictionary<Type, List<Tuple<Vector3, Quaternion>>> dictionary = new Dictionary<Type, List<Tuple<Vector3, Quaternion>>>();
		ValuableVolume[] array = Object.FindObjectsOfType<ValuableVolume>();
		foreach (ValuableVolume val in array)
		{
			if (!dictionary.ContainsKey(val.VolumeType))
			{
				dictionary[val.VolumeType] = new List<Tuple<Vector3, Quaternion>>();
			}
			dictionary[val.VolumeType].Add(Tuple.Create<Vector3, Quaternion>(((Component)val).transform.position, ((Component)val).transform.rotation));
		}
		CatsPlugin.Log.LogDebug((object)$"[Cats] captured {dictionary.Values.Sum((List<Tuple<Vector3, Quaternion>> l) => l.Count)} volumes across {dictionary.Count} types");
		((MonoBehaviour)__instance).StartCoroutine(SpawnCats(__instance, dictionary));
	}

	[IteratorStateMachine(typeof(<SpawnCats>d__3))]
	private static IEnumerator SpawnCats(ValuableDirector director, Dictionary<Type, List<Tuple<Vector3, Quaternion>>> volumesByType)
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <SpawnCats>d__3(0)
		{
			director = director,
			volumesByType = volumesByType
		};
	}
}