Decompiled source of Christmas Gifts v2.0.1

EmpressPresents.dll

Decompiled a month 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 BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using ExitGames.Client.Photon;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using Photon.Realtime;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Empress")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("4.6.0.0")]
[assembly: AssemblyInformationalVersion("4.6.0")]
[assembly: AssemblyProduct("EmpressPresents")]
[assembly: AssemblyTitle("EmpressPresents")]
[assembly: AssemblyVersion("4.6.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Empress.Presents
{
	[BepInPlugin("empress.repo.empresspresents", "Empress Presents", "4.6.0")]
	public sealed class EmpressPresentsPlugin : BaseUnityPlugin
	{
		public const string PluginGuid = "empress.repo.empresspresents";

		public const string PluginName = "Empress Presents";

		public const string PluginVersion = "4.6.0";

		internal static EmpressPresentsPlugin Instance { get; private set; }

		internal static ManualLogSource Log { get; private set; }

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

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

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

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

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

		internal static ConfigEntry<bool> SkipStartRoom { get; private set; }

		private void Awake()
		{
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Expected O, but got Unknown
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			ExplosionChance = ((BaseUnityPlugin)this).Config.Bind<float>("Gameplay", "ExplosionChance", 0.2f, "Chance from 0 to 1 for a present to explode instead of dropping loot.");
			MinSpawnItems = ((BaseUnityPlugin)this).Config.Bind<int>("Gameplay", "MinSpawnItems", 1, "Minimum loot drops from a present.");
			MaxSpawnItems = ((BaseUnityPlugin)this).Config.Bind<int>("Gameplay", "MaxSpawnItems", 6, "Maximum loot drops from a present.");
			MinPresents = ((BaseUnityPlugin)this).Config.Bind<int>("Spawning", "MinPresents", 1, "Minimum presents per level.");
			MaxPresents = ((BaseUnityPlugin)this).Config.Bind<int>("Spawning", "MaxPresents", 3, "Maximum presents per level.");
			SkipStartRoom = ((BaseUnityPlugin)this).Config.Bind<bool>("Spawning", "SkipStartRoom", true, "Skip the closest path points to the truck.");
			GameObject val = new GameObject("Empress_Presents_Controller");
			Object.DontDestroyOnLoad((Object)val);
			((Object)val).hideFlags = (HideFlags)52;
			val.AddComponent<PresentEventRouter>();
			Log.LogInfo((object)"Empress Presents 4.6.0 loaded.");
		}

		internal static bool IsHostOrOffline()
		{
			if (PhotonNetwork.InRoom)
			{
				return PhotonNetwork.IsMasterClient;
			}
			return true;
		}

		internal static bool IsHost()
		{
			if (PhotonNetwork.InRoom)
			{
				return PhotonNetwork.IsMasterClient;
			}
			return false;
		}

		internal static bool IsOffline()
		{
			return !PhotonNetwork.InRoom;
		}
	}
	internal static class PresentAssetLoader
	{
		private static AssetBundle? bundle;

		private static GameObject? cachedTreat;

		internal static GameObject? LoadTreatPrefab()
		{
			try
			{
				if ((Object)(object)cachedTreat != (Object)null)
				{
					return cachedTreat;
				}
				if ((Object)(object)bundle == (Object)null)
				{
					string? path = Path.GetDirectoryName(typeof(EmpressPresentsPlugin).Assembly.Location) ?? string.Empty;
					string text = Path.Combine(path, "trick");
					string text2 = Path.Combine(path, "Empress", "trick");
					string text3 = (File.Exists(text) ? text : text2);
					if (!File.Exists(text3))
					{
						return null;
					}
					bundle = AssetBundle.LoadFromFile(text3);
					if ((Object)(object)bundle == (Object)null)
					{
						return null;
					}
				}
				cachedTreat = bundle.LoadAsset<GameObject>("treat");
				return cachedTreat;
			}
			catch
			{
				return null;
			}
		}
	}
	internal sealed class PresentEventRouter : MonoBehaviour, IOnEventCallback
	{
		internal enum Ev : byte
		{
			Create = 61,
			Interact,
			TreatFX,
			ExplodeFX,
			Destroy
		}

		private static readonly Dictionary<string, GameObject> Active = new Dictionary<string, GameObject>();

		private static bool spawnRoutineRunning;

		private static bool spawnedThisScene;

		private bool callbackHooked;

		private void OnEnable()
		{
			SceneManager.sceneLoaded += OnSceneLoaded;
		}

		private void OnDisable()
		{
			SceneManager.sceneLoaded -= OnSceneLoaded;
			RemoveCallbackHooked();
		}

		public void OnEvent(EventData photonEvent)
		{
			//IL_0048: 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)
			try
			{
				switch ((Ev)photonEvent.Code)
				{
				case Ev.Create:
					ReceiveCreate(photonEvent.CustomData);
					break;
				case Ev.Interact:
					ReceiveInteract(photonEvent.CustomData);
					break;
				case Ev.TreatFX:
					PlayFXLocal(Ev.TreatFX, (Vector3)photonEvent.CustomData);
					break;
				case Ev.ExplodeFX:
					PlayFXLocal(Ev.ExplodeFX, (Vector3)photonEvent.CustomData);
					break;
				case Ev.Destroy:
					LocalDestroy(photonEvent.CustomData as string);
					break;
				}
			}
			catch
			{
			}
		}

		internal static void Raise(Ev code, object payload, ReceiverGroup receivers)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: 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_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			if (PhotonNetwork.InRoom && PhotonNetwork.IsConnectedAndReady)
			{
				PhotonNetwork.RaiseEvent((byte)code, payload, new RaiseEventOptions
				{
					Receivers = receivers
				}, SendOptions.SendReliable);
				return;
			}
			try
			{
				switch (code)
				{
				case Ev.TreatFX:
					PresentInteraction.SpawnExplosionPrefab((Vector3)payload, 0.5f, 0, 0, 0f, disableSound: true);
					break;
				case Ev.ExplodeFX:
					PresentInteraction.SpawnExplosionPrefab((Vector3)payload, 1.2f, 75, 160, 4f, disableSound: false);
					break;
				case Ev.Destroy:
					LocalDestroy(payload as string);
					break;
				case Ev.Create:
					if (payload is object[] array && array.Length >= 3)
					{
						CreateLocalPresent(array[0] as string, (Vector3)array[1], (Quaternion)array[2]);
					}
					break;
				case Ev.Interact:
					break;
				}
			}
			catch
			{
			}
		}

		internal static void CreateLocalPresent(string? id, Vector3 position, Quaternion rotation)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (!string.IsNullOrEmpty(id) && !Active.ContainsKey(id))
				{
					GameObject value = PresentPrefabBuilder.Build(id, position, rotation);
					Active[id] = value;
				}
			}
			catch
			{
			}
		}

		internal static void LocalDestroy(string? id)
		{
			try
			{
				if (!string.IsNullOrEmpty(id))
				{
					if (Active.TryGetValue(id, out GameObject value) && (Object)(object)value != (Object)null)
					{
						Object.Destroy((Object)(object)value);
					}
					Active.Remove(id);
				}
			}
			catch
			{
			}
		}

		internal static void PlayFXLocal(Ev code, Vector3 position)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				switch (code)
				{
				case Ev.TreatFX:
					PresentInteraction.SpawnExplosionPrefab(position, 0.5f, 0, 0, 0f, disableSound: true);
					break;
				case Ev.ExplodeFX:
					PresentInteraction.SpawnExplosionPrefab(position, 1.2f, 75, 160, 4f, disableSound: false);
					break;
				}
			}
			catch
			{
			}
		}

		internal static void RequestInteract(string id, Vector3 position)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			if (EmpressPresentsPlugin.IsHostOrOffline())
			{
				PresentSpawner.HostResolveInteraction(id, position);
				return;
			}
			Raise(Ev.Interact, new object[2] { id, position }, (ReceiverGroup)2);
		}

		private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			spawnRoutineRunning = false;
			spawnedThisScene = false;
			Active.Clear();
			if (IsMenuScene())
			{
				RemoveCallbackHooked();
			}
			else
			{
				TrySpawnIfRealLevel();
			}
		}

		private void EnsureCallbackHooked()
		{
			if (!callbackHooked && PhotonNetwork.InRoom && PhotonNetwork.IsConnectedAndReady)
			{
				PhotonNetwork.AddCallbackTarget((object)this);
				callbackHooked = true;
			}
		}

		private void RemoveCallbackHooked()
		{
			if (callbackHooked)
			{
				PhotonNetwork.RemoveCallbackTarget((object)this);
				callbackHooked = false;
			}
		}

		private void TrySpawnIfRealLevel()
		{
			if (!spawnRoutineRunning && !spawnedThisScene && !IsMenuScene())
			{
				((MonoBehaviour)this).StartCoroutine(WaitForLevelThenSpawn());
			}
		}

		private IEnumerator WaitForLevelThenSpawn()
		{
			spawnRoutineRunning = true;
			float timer = 0f;
			while (((Object)(object)LevelGenerator.Instance == (Object)null || !LevelGenerator.Instance.Generated) && timer < 20f)
			{
				timer += Time.deltaTime;
				yield return null;
			}
			if ((Object)(object)LevelGenerator.Instance != (Object)null && LevelGenerator.Instance.Generated && !IsMenuScene())
			{
				EnsureCallbackHooked();
				yield return (object)new WaitForSeconds(0.5f);
				if (EmpressPresentsPlugin.IsHostOrOffline() && !spawnedThisScene && !IsMenuScene())
				{
					PresentSpawner.HostSpawnPresents();
					spawnedThisScene = true;
				}
			}
			spawnRoutineRunning = false;
		}

		private static bool IsMenuScene()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			Scene activeScene = SceneManager.GetActiveScene();
			string text = ((Scene)(ref activeScene)).name ?? string.Empty;
			if (text.IndexOf("Lobby", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("Menu", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("Splash", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				return true;
			}
			try
			{
				return (Object)(object)RunManager.instance != (Object)null && SemiFunc.MenuLevel();
			}
			catch
			{
				return false;
			}
		}

		private static void ReceiveCreate(object customData)
		{
			//IL_0024: 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)
			if (!EmpressPresentsPlugin.IsHost() && customData is object[] array && array.Length >= 3)
			{
				CreateLocalPresent(array[0] as string, (Vector3)array[1], (Quaternion)array[2]);
			}
		}

		private static void ReceiveInteract(object customData)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			if (EmpressPresentsPlugin.IsHostOrOffline() && customData is object[] array && array.Length >= 2)
			{
				PresentSpawner.HostResolveInteraction((array[0] as string) ?? string.Empty, (Vector3)array[1]);
			}
		}
	}
	internal sealed class PresentInteraction : MonoBehaviour
	{
		private const string AnimationBool = "Present";

		private const string AnimationStateName = "Open Present";

		private const float AnimationDelaySeconds = 2f;

		private const float CooldownSeconds = 0.6f;

		private const float UseRange = 2f;

		private static FieldRef<ParticlePrefabExplosion, float> explosionSizeRef;

		private static FieldRef<ParticlePrefabExplosion, int> explosionDamageRef;

		private static FieldRef<ParticlePrefabExplosion, int> explosionDamageEnemyRef;

		private static FieldRef<ParticlePrefabExplosion, float> forceMultiplierRef;

		private static bool fieldRefsReady;

		private static bool fieldRefsFailed;

		private bool armed;

		private float nextUse;

		internal string Id { get; set; } = string.Empty;


		private IEnumerator Start()
		{
			yield return null;
			armed = true;
			try
			{
				Animator componentInChildren = ((Component)this).GetComponentInChildren<Animator>(true);
				if ((Object)(object)componentInChildren != (Object)null)
				{
					componentInChildren.cullingMode = (AnimatorCullingMode)0;
					componentInChildren.updateMode = (AnimatorUpdateMode)0;
					componentInChildren.Rebind();
					componentInChildren.Update(0f);
				}
			}
			catch
			{
			}
		}

		private void Update()
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			if (armed && !string.IsNullOrEmpty(Id) && !(Time.time < nextUse) && TryGetPlayerPosition(out var position) && !(Vector3.Distance(position, ((Component)this).transform.position) > 2f))
			{
				SemiFunc.UIFocusText("Press <color=yellow>E</color> to open", Color.white, Color.yellow, 3f);
				if (SemiFunc.InputDown((InputKey)2))
				{
					nextUse = Time.time + 0.6f;
					armed = false;
					DisableInteractionCollider();
					((MonoBehaviour)this).StartCoroutine(PlayAnimationThenResolve());
				}
			}
		}

		internal static bool SpawnExplosionPrefab(Vector3 position, float size, int damage, int enemyDamage, float forceMultiplier, bool disableSound)
		{
			//IL_001c: 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)
			try
			{
				GameObject val = Resources.Load<GameObject>("Effects/Part Prefab Explosion");
				if ((Object)(object)val == (Object)null)
				{
					return false;
				}
				GameObject val2 = Object.Instantiate<GameObject>(val, position, Quaternion.identity);
				ParticlePrefabExplosion component = val2.GetComponent<ParticlePrefabExplosion>();
				if ((Object)(object)component != (Object)null)
				{
					EnsureFieldRefs();
					if (fieldRefsReady)
					{
						explosionSizeRef.Invoke(component) = Mathf.Max(0.01f, size);
						explosionDamageRef.Invoke(component) = Mathf.Max(0, damage);
						explosionDamageEnemyRef.Invoke(component) = Mathf.Max(0, enemyDamage);
						forceMultiplierRef.Invoke(component) = Mathf.Max(0f, forceMultiplier);
					}
					if (disableSound)
					{
						AudioSource[] componentsInChildren = val2.GetComponentsInChildren<AudioSource>(true);
						for (int i = 0; i < componentsInChildren.Length; i++)
						{
							componentsInChildren[i].mute = true;
						}
					}
				}
				return true;
			}
			catch
			{
				return false;
			}
		}

		private static void EnsureFieldRefs()
		{
			if (fieldRefsReady || fieldRefsFailed)
			{
				return;
			}
			try
			{
				explosionSizeRef = AccessTools.FieldRefAccess<ParticlePrefabExplosion, float>("explosionSize");
				explosionDamageRef = AccessTools.FieldRefAccess<ParticlePrefabExplosion, int>("explosionDamage");
				explosionDamageEnemyRef = AccessTools.FieldRefAccess<ParticlePrefabExplosion, int>("explosionDamageEnemy");
				forceMultiplierRef = AccessTools.FieldRefAccess<ParticlePrefabExplosion, float>("forceMultiplier");
				fieldRefsReady = true;
			}
			catch
			{
				fieldRefsFailed = true;
			}
		}

		private IEnumerator PlayAnimationThenResolve()
		{
			Animator animator = null;
			bool usedBool = false;
			try
			{
				animator = ((Component)this).GetComponentInChildren<Animator>(true);
				if ((Object)(object)animator != (Object)null)
				{
					for (int i = 0; i < animator.layerCount; i++)
					{
						animator.SetLayerWeight(i, 1f);
					}
					if (HasAnimationBool(animator))
					{
						animator.SetBool("Present", true);
						usedBool = true;
					}
					else
					{
						int num = Animator.StringToHash("Open Present");
						if (animator.HasState(0, num))
						{
							animator.CrossFade(num, 0.05f, 0, 0f);
						}
					}
					animator.Update(0f);
				}
			}
			catch
			{
			}
			yield return (object)new WaitForSeconds(2f);
			if (usedBool && (Object)(object)animator != (Object)null)
			{
				try
				{
					animator.SetBool("Present", false);
				}
				catch
				{
				}
			}
			PresentEventRouter.RequestInteract(Id, ((Component)this).transform.position);
		}

		private static bool HasAnimationBool(Animator animator)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Invalid comparison between Unknown and I4
			try
			{
				AnimatorControllerParameter[] parameters = animator.parameters;
				for (int i = 0; i < parameters.Length; i++)
				{
					if ((int)parameters[i].type == 4 && parameters[i].name == "Present")
					{
						return true;
					}
				}
			}
			catch
			{
			}
			return false;
		}

		private static bool TryGetPlayerPosition(out Vector3 position)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			PlayerController instance = PlayerController.instance;
			if ((Object)(object)instance != (Object)null)
			{
				position = ((Component)instance).transform.position;
				return true;
			}
			if ((Object)(object)Camera.main != (Object)null)
			{
				position = ((Component)Camera.main).transform.position;
				return true;
			}
			position = default(Vector3);
			return false;
		}

		private void DisableInteractionCollider()
		{
			try
			{
				Transform obj = ((Component)this).transform.Find("InteractCollider");
				Collider val = ((obj != null) ? ((Component)obj).GetComponent<Collider>() : null);
				if ((Object)(object)val != (Object)null)
				{
					val.enabled = false;
				}
			}
			catch
			{
			}
		}
	}
	internal static class PresentPrefabBuilder
	{
		internal static GameObject Build(string id, Vector3 position, Quaternion rotation)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Expected O, but got Unknown
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: 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_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = position + Vector3.up * 0.5f;
			RaycastHit val2 = default(RaycastHit);
			if (Physics.Raycast(val, Vector3.down, ref val2, 2f, -1, (QueryTriggerInteraction)1))
			{
				val = ((RaycastHit)(ref val2)).point + Vector3.up * 0.05f;
				rotation = Quaternion.FromToRotation(Vector3.up, ((RaycastHit)(ref val2)).normal) * rotation;
			}
			GameObject val3 = new GameObject("EmpressPresent_" + id);
			val3.transform.position = val;
			val3.transform.rotation = rotation;
			Rigidbody obj = val3.AddComponent<Rigidbody>();
			obj.useGravity = false;
			obj.isKinematic = false;
			obj.collisionDetectionMode = (CollisionDetectionMode)0;
			obj.interpolation = (RigidbodyInterpolation)0;
			obj.constraints = (RigidbodyConstraints)126;
			GameObject val4 = new GameObject("InteractCollider");
			val4.transform.SetParent(val3.transform, false);
			BoxCollider obj2 = val4.AddComponent<BoxCollider>();
			obj2.size = new Vector3(0.45f, 0.35f, 0.45f);
			obj2.center = new Vector3(0f, 0.175f, 0f);
			((Collider)obj2).isTrigger = true;
			val3.AddComponent<PresentVisualBinder>();
			val3.AddComponent<PresentInteraction>().Id = id;
			return val3;
		}
	}
	internal static class PresentSpawner
	{
		internal static void HostSpawnPresents()
		{
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				LevelGenerator instance = LevelGenerator.Instance;
				if ((Object)(object)instance == (Object)null || !instance.Generated)
				{
					return;
				}
				List<LevelPoint> list = ((instance.LevelPathPoints != null) ? instance.LevelPathPoints.Where((LevelPoint point) => (Object)(object)point != (Object)null).ToList() : new List<LevelPoint>());
				if (list.Count == 0)
				{
					return;
				}
				if (EmpressPresentsPlugin.SkipStartRoom.Value && (Object)(object)instance.LevelPathTruck != (Object)null)
				{
					Vector3 truckPosition = ((Component)instance.LevelPathTruck).transform.position;
					list = list.OrderBy((LevelPoint point) => Vector3.Distance(truckPosition, ((Component)point).transform.position)).Skip(3).ToList();
					if (list.Count == 0)
					{
						list = instance.LevelPathPoints.Where((LevelPoint point) => (Object)(object)point != (Object)null).ToList();
					}
				}
				int num = Mathf.Clamp(EmpressPresentsPlugin.MinPresents.Value, 0, 1000);
				int num2 = Mathf.Max(num, EmpressPresentsPlugin.MaxPresents.Value);
				int count = Mathf.Min(Random.Range(num, num2 + 1), list.Count);
				Random random = new Random((int)(DateTime.UtcNow.Ticks & 0x7FFFFFFF));
				foreach (LevelPoint item in list.OrderBy((LevelPoint _) => random.Next()).Take(count))
				{
					Vector3 val = ((Component)item).transform.position + Vector3.up * 0.25f;
					Quaternion rotation = ((Component)item).transform.rotation;
					string text = Guid.NewGuid().ToString("N");
					PresentEventRouter.CreateLocalPresent(text, val, rotation);
					PresentEventRouter.Raise(PresentEventRouter.Ev.Create, new object[3] { text, val, rotation }, (ReceiverGroup)0);
				}
			}
			catch (Exception ex)
			{
				EmpressPresentsPlugin.Log.LogError((object)ex);
			}
		}

		internal static void HostResolveInteraction(string id, Vector3 position)
		{
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			PresentEventRouter.Ev code = PresentEventRouter.Ev.TreatFX;
			try
			{
				if (Random.value < Mathf.Clamp01(EmpressPresentsPlugin.ExplosionChance.Value))
				{
					code = PresentEventRouter.Ev.ExplodeFX;
					PresentEventRouter.PlayFXLocal(code, position);
					return;
				}
				PresentEventRouter.PlayFXLocal(code, position);
				BuildMixedSpawnPayload(out Item[] items, out PrefabRef[] valuables);
				bool flag = false;
				if (items.Length != 0)
				{
					HostSpawnItems(items, position);
					flag = true;
				}
				if (valuables.Length != 0)
				{
					HostSpawnValuables(valuables, position);
					flag = true;
				}
				if (!flag)
				{
					code = PresentEventRouter.Ev.ExplodeFX;
					PresentEventRouter.PlayFXLocal(code, position);
				}
			}
			catch (Exception ex)
			{
				EmpressPresentsPlugin.Log.LogError((object)ex);
			}
			finally
			{
				try
				{
					PresentEventRouter.Raise(code, position, (ReceiverGroup)0);
				}
				catch
				{
				}
				try
				{
					PresentEventRouter.LocalDestroy(id);
				}
				catch
				{
				}
				try
				{
					PresentEventRouter.Raise(PresentEventRouter.Ev.Destroy, id, (ReceiverGroup)0);
				}
				catch
				{
				}
			}
		}

		private static void BuildMixedSpawnPayload(out Item[] items, out PrefabRef[] valuables)
		{
			items = Array.Empty<Item>();
			valuables = Array.Empty<PrefabRef>();
			int num = Random.Range(Mathf.Max(1, EmpressPresentsPlugin.MinSpawnItems.Value), Mathf.Max(EmpressPresentsPlugin.MinSpawnItems.Value, EmpressPresentsPlugin.MaxSpawnItems.Value) + 1);
			if (num <= 0)
			{
				return;
			}
			List<Item> list = BuildItemPool();
			List<PrefabRef> list2 = BuildValuablePool();
			if (list.Count == 0 && list2.Count == 0)
			{
				return;
			}
			Random random = new Random((int)(DateTime.UtcNow.Ticks & 0x7FFFFFFF));
			List<Item> list3 = new List<Item>(num);
			List<PrefabRef> list4 = new List<PrefabRef>(num);
			for (int i = 0; i < num; i++)
			{
				bool flag = list.Count > 0;
				bool flag2 = list2.Count > 0;
				if (flag && flag2)
				{
					if (random.NextDouble() < 0.5)
					{
						list3.Add(list[random.Next(list.Count)]);
					}
					else
					{
						list4.Add(list2[random.Next(list2.Count)]);
					}
				}
				else if (flag)
				{
					list3.Add(list[random.Next(list.Count)]);
				}
				else
				{
					list4.Add(list2[random.Next(list2.Count)]);
				}
			}
			items = list3.ToArray();
			valuables = list4.ToArray();
		}

		private static List<Item> BuildItemPool()
		{
			try
			{
				List<Item> list = new List<Item>();
				ShopManager instance = ShopManager.instance;
				if ((Object)(object)instance != (Object)null)
				{
					if (instance.potentialItems != null)
					{
						list.AddRange(instance.potentialItems);
					}
					if (instance.potentialItemConsumables != null)
					{
						list.AddRange(instance.potentialItemConsumables);
					}
					if (instance.potentialItemUpgrades != null)
					{
						list.AddRange(instance.potentialItemUpgrades);
					}
				}
				if (list.Count == 0 && (Object)(object)StatsManager.instance != (Object)null && StatsManager.instance.itemDictionary != null)
				{
					list.AddRange(StatsManager.instance.itemDictionary.Values);
				}
				return list.Where((Item item) => (Object)(object)item != (Object)null && item.prefab != null && item.prefab.IsValid()).Distinct().ToList();
			}
			catch
			{
				return new List<Item>();
			}
		}

		private static List<PrefabRef> BuildValuablePool()
		{
			try
			{
				List<PrefabRef> list = new List<PrefabRef>();
				LevelGenerator instance = LevelGenerator.Instance;
				if ((Object)(object)instance == (Object)null || (Object)(object)instance.Level == (Object)null || instance.Level.ValuablePresets == null)
				{
					return list;
				}
				foreach (LevelValuables valuablePreset in instance.Level.ValuablePresets)
				{
					if (!((Object)(object)valuablePreset == (Object)null))
					{
						if (valuablePreset.tiny != null)
						{
							list.AddRange(valuablePreset.tiny);
						}
						if (valuablePreset.small != null)
						{
							list.AddRange(valuablePreset.small);
						}
						if (valuablePreset.medium != null)
						{
							list.AddRange(valuablePreset.medium);
						}
						if (valuablePreset.big != null)
						{
							list.AddRange(valuablePreset.big);
						}
						if (valuablePreset.wide != null)
						{
							list.AddRange(valuablePreset.wide);
						}
						if (valuablePreset.tall != null)
						{
							list.AddRange(valuablePreset.tall);
						}
						if (valuablePreset.veryTall != null)
						{
							list.AddRange(valuablePreset.veryTall);
						}
					}
				}
				return list.Where((PrefabRef valuable) => valuable != null && valuable.IsValid() && !string.IsNullOrEmpty(valuable.ResourcePath)).Distinct().ToList();
			}
			catch
			{
				return new List<PrefabRef>();
			}
		}

		private static void HostSpawnItems(Item[] items, Vector3 center)
		{
			//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_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: 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_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			if (!EmpressPresentsPlugin.IsHostOrOffline() || items.Length == 0)
			{
				return;
			}
			Quaternion dropRotation = GetDropRotation();
			Vector3 val = center + Vector3.up * 0.35f;
			foreach (Item val2 in items)
			{
				try
				{
					if ((Object)(object)val2 == (Object)null || val2.prefab == null || !val2.prefab.IsValid())
					{
						continue;
					}
					string resourcePath = val2.prefab.ResourcePath;
					Vector3 val3 = val + Random.insideUnitSphere * 0.4f;
					if (EmpressPresentsPlugin.IsHost())
					{
						if (!string.IsNullOrEmpty(resourcePath))
						{
							PhotonNetwork.InstantiateRoomObject(resourcePath, val3, dropRotation, (byte)0, (object[])null);
						}
					}
					else if (EmpressPresentsPlugin.IsOffline())
					{
						SpawnLocal(val2.prefab, resourcePath, val3, dropRotation);
					}
				}
				catch
				{
				}
			}
		}

		private static void HostSpawnValuables(PrefabRef[] valuables, Vector3 center)
		{
			//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_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			if (!EmpressPresentsPlugin.IsHostOrOffline() || valuables.Length == 0)
			{
				return;
			}
			Quaternion dropRotation = GetDropRotation();
			Vector3 val = center + Vector3.up * 0.35f;
			foreach (PrefabRef val2 in valuables)
			{
				try
				{
					if (val2 == null || !val2.IsValid())
					{
						continue;
					}
					string resourcePath = val2.ResourcePath;
					Vector3 val3 = val + Random.insideUnitSphere * 0.4f;
					if (EmpressPresentsPlugin.IsHost())
					{
						if (!string.IsNullOrEmpty(resourcePath))
						{
							PhotonNetwork.InstantiateRoomObject(resourcePath, val3, dropRotation, (byte)0, (object[])null);
						}
					}
					else if (EmpressPresentsPlugin.IsOffline())
					{
						SpawnLocal(val2, resourcePath, val3, dropRotation);
					}
				}
				catch
				{
				}
			}
		}

		private static Quaternion GetDropRotation()
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Transform val = (((Object)(object)ShopManager.instance != (Object)null) ? ShopManager.instance.itemRotateHelper : null);
				if ((Object)(object)val != (Object)null)
				{
					((Component)val).transform.parent = null;
					return ((Component)val).transform.rotation;
				}
			}
			catch
			{
			}
			return Quaternion.identity;
		}

		private static void SpawnLocal(PrefabRef prefabRef, string resourcePath, Vector3 position, Quaternion rotation)
		{
			//IL_0011: 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_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			GameObject prefab = prefabRef.Prefab;
			if ((Object)(object)prefab != (Object)null)
			{
				Object.Instantiate<GameObject>(prefab, position, rotation);
			}
			else if (!string.IsNullOrEmpty(resourcePath))
			{
				GameObject val = Resources.Load<GameObject>(resourcePath);
				if ((Object)(object)val != (Object)null)
				{
					Object.Instantiate<GameObject>(val, position, rotation);
				}
			}
		}
	}
	internal sealed class PresentVisualBinder : MonoBehaviour
	{
		private void Awake()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				GameObject val = PresentAssetLoader.LoadTreatPrefab();
				if (!((Object)(object)val == (Object)null))
				{
					Object.Instantiate<GameObject>(val, ((Component)this).transform.position, ((Component)this).transform.rotation).transform.SetParent(((Component)this).transform, true);
				}
			}
			catch
			{
			}
		}
	}
}