Decompiled source of Scavenging Scone v0.3.0

Wilnath.Lootations.dll

Decompiled 5 days 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.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using FistVR;
using H3MP;
using H3MP.Networking;
using H3MP.Scripts;
using H3MP.Tracking;
using HarmonyLib;
using MapGenerator;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Sodalite.Api;
using SupplyRaid;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyCompany("Wilnath/marbL-")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Library for building containers of randomized items in H3VR.")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Wilnath.Lootations")]
[assembly: AssemblyTitle("Lootations")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace BepInEx
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class BepInAutoPluginAttribute : Attribute
	{
		public BepInAutoPluginAttribute(string id = null, string name = null, string version = null)
		{
		}
	}
}
namespace BepInEx.Preloader.Core.Patching
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class PatcherAutoPluginAttribute : Attribute
	{
		public PatcherAutoPluginAttribute(string id = null, string name = null, string version = null)
		{
		}
	}
}
namespace Lootations
{
	public class ActiveOnTrigger : MonoBehaviour
	{
		public GameObject TriggerOwner;

		public GameObject[] ToActivate;

		public GameObject[] ToDeactivate;

		public void Start()
		{
			if ((Object)(object)TriggerOwner == (Object)null)
			{
				TriggerOwner = ((Component)this).gameObject;
			}
			ILootTrigger component = TriggerOwner.GetComponent<ILootTrigger>();
			if (component == null)
			{
				Lootations.Logger.LogError((object)"ActiveOnTrigger could not find a trigger on specified GameObject.");
			}
			else
			{
				component.OnTriggered += Triggered;
			}
		}

		private void Triggered(ILootTrigger _)
		{
			GameObject[] toActivate = ToActivate;
			foreach (GameObject val in toActivate)
			{
				val.SetActive(true);
			}
			GameObject[] toDeactivate = ToDeactivate;
			foreach (GameObject val2 in toDeactivate)
			{
				val2.SetActive(false);
			}
		}
	}
	public class AudioEventOnTrigger : MonoBehaviour
	{
		public GameObject TriggerOwner;

		public AudioEvent TriggerAudioEvent;

		public void Awake()
		{
			if ((Object)(object)TriggerOwner == (Object)null)
			{
				TriggerOwner = ((Component)this).gameObject;
			}
			ILootTrigger component = TriggerOwner.GetComponent<ILootTrigger>();
			if (component == null)
			{
				Lootations.Logger.LogError((object)"AudioEvent missing trigger");
			}
			else
			{
				component.OnTriggered += Triggered;
			}
		}

		public void Triggered(ILootTrigger _)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			SM.PlayGenericSound(TriggerAudioEvent, ((Component)this).gameObject.transform.position);
		}
	}
	public class EnemySpawn : MonoBehaviour
	{
		private class SpawnParameters
		{
			public int IFF = 0;

			public SosigEnemyID[] pool = (SosigEnemyID[])(object)new SosigEnemyID[1] { (SosigEnemyID)160 };

			public int squadSize = 3;
		}

		public bool LimitSpawns = false;

		public int SpawnAmountLimit = 1;

		public bool UseGlobalSpawnSettings = true;

		public Vector3 SpawnRandomization = new Vector3(0f, 0f, 0f);

		public float PlayerDistanceToDespawn = 350f;

		public float PlayerDistanceToSpawn = 250f;

		public float PlayerSpawnGrace = 75f;

		private List<Sosig> spawnedSosigs = new List<Sosig>();

		private bool spawned = false;

		public void Awake()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: 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_006f: Unknown result type (might be due to invalid IL or missing references)
			if (Utilities.PlayerWithinDistance(((Component)this).transform.position, PlayerSpawnGrace))
			{
				Lootations.Logger.LogDebug((object)"Skipped enemy spawn to grace: player");
				spawned = true;
			}
			else if (((Behaviour)SR_Manager.instance).isActiveAndEnabled)
			{
				Vector3 position = SR_Manager.instance.supplyPoints[SR_Manager.instance.playerSupplyID].respawn.position;
				if (Utilities.PositionsWithinDistance(position, ((Component)this).transform.position, PlayerSpawnGrace))
				{
					Lootations.Logger.LogDebug((object)"Skipped enemy spawn to grace: station");
					spawned = true;
				}
			}
		}

		public void Update()
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			if (Lootations.h3mpEnabled && Networking.IsClient())
			{
				spawned = true;
			}
			else if (!spawned && Utilities.PlayerWithinDistance(((Component)this).transform.position, PlayerDistanceToSpawn))
			{
				Spawn();
				spawned = true;
			}
		}

		private SpawnParameters GetSpawnParameters()
		{
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Expected I4, but got Unknown
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Expected I4, but got Unknown
			SpawnParameters spawnParameters = new SpawnParameters();
			if (((Behaviour)SR_Manager.instance).isActiveAndEnabled)
			{
				FactionLevel factionLevel = SR_Manager.GetFactionLevel();
				spawnParameters.IFF = 1;
				spawnParameters.squadSize = Random.Range(factionLevel.squadSizeMin, factionLevel.squadSizeMax);
				spawnParameters.pool = factionLevel.squadPool.sosigEnemyID;
				return spawnParameters;
			}
			if (((Behaviour)GM.TNH_Manager).isActiveAndEnabled)
			{
				List<Patrol> patrols = GM.TNH_Manager.m_curLevel.PatrolChallenge.Patrols;
				Patrol val = patrols[Random.Range(0, patrols.Count)];
				spawnParameters.IFF = 1;
				spawnParameters.squadSize = val.PatrolSize;
				spawnParameters.pool = (SosigEnemyID[])(object)new SosigEnemyID[2]
				{
					(SosigEnemyID)(int)val.EType,
					(SosigEnemyID)(int)val.LType
				};
				return spawnParameters;
			}
			return spawnParameters;
		}

		public void Spawn()
		{
			//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)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Expected O, but got Unknown
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			SpawnParameters spawnParameters = GetSpawnParameters();
			Vector3 val = default(Vector3);
			((Vector3)(ref val))..ctor(Random.Range(0f, SpawnRandomization.x), Random.Range(0f, SpawnRandomization.y), Random.Range(0f, SpawnRandomization.z));
			Vector3 sosigTargetPosition = ((Component)this).transform.position + val;
			SpawnOptions val2 = new SpawnOptions
			{
				SpawnActivated = true,
				SpawnState = (SosigOrder)1,
				IFF = spawnParameters.IFF,
				SpawnWithFullAmmo = true,
				EquipmentMode = (EquipmentSlots)7,
				SosigTargetPosition = sosigTargetPosition,
				SosigTargetRotation = ((Component)this).transform.eulerAngles
			};
			for (int i = 0; i < spawnParameters.squadSize; i++)
			{
				if (LimitSpawns && i >= SpawnAmountLimit)
				{
					Lootations.Logger.LogDebug((object)"Hit enemy spawn limit");
					break;
				}
				SosigEnemyID randomSosigIDFromPool = SR_Global.GetRandomSosigIDFromPool(spawnParameters.pool);
				Quaternion val3 = Quaternion.Euler(0f, Random.Range(0f, 360f), 0f);
				if (!Utilities.SampleNavMesh(((Component)this).transform.position, 0.5f, out var result))
				{
					Lootations.Logger.LogDebug((object)"Could not find spawn position for EnemySpawn sosig");
					continue;
				}
				Sosig val4 = SosigAPI.Spawn(ManagerSingleton<IM>.Instance.odicSosigObjsByID[randomSosigIDFromPool], val2, result, val3);
				spawnedSosigs.Add(val4);
				if (((Behaviour)SR_Manager.instance).isActiveAndEnabled)
				{
					foreach (Sosig spawnedSosig in spawnedSosigs)
					{
						spawnedSosig.StateSightRangeMults *= SR_Manager.sosigSightMultiplier;
					}
					if (!SR_Manager.profile.sosigWeapons)
					{
						DisableSosigWeapons(val4);
					}
					SR_Manager.instance.AddCustomSosig(val4, false);
				}
				else if (((Behaviour)GM.TNH_Manager).isActiveAndEnabled)
				{
					GM.TNH_Manager.AddToMiscEnemies(((Component)val4).gameObject);
				}
			}
		}

		private void DisableSosigWeapons(Sosig sosig)
		{
			foreach (Slot slot in sosig.Inventory.Slots)
			{
				if ((Object)(object)slot.HeldObject != (Object)null)
				{
					FVRPhysicalObject component = ((Component)slot.HeldObject).GetComponent<FVRPhysicalObject>();
					if ((Object)(object)component != (Object)null)
					{
						component.IsPickUpLocked = true;
					}
				}
			}
			foreach (SosigHand hand in sosig.Hands)
			{
				if ((Object)(object)hand.HeldObject != (Object)null)
				{
					FVRPhysicalObject component2 = ((Component)hand.HeldObject).GetComponent<FVRPhysicalObject>();
					if ((Object)(object)component2 != (Object)null)
					{
						component2.IsPickUpLocked = true;
					}
				}
			}
		}

		public void OnDestroy()
		{
			foreach (Sosig spawnedSosig in spawnedSosigs)
			{
				if ((Object)(object)spawnedSosig != (Object)null)
				{
					Object.Destroy((Object)(object)spawnedSosig);
				}
			}
			spawnedSosigs.Clear();
		}

		private void OnDrawGizmosSelected()
		{
			//IL_0001: 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_001d: Unknown result type (might be due to invalid IL or missing references)
			Gizmos.color = Color.red;
			if (UseGlobalSpawnSettings)
			{
				Gizmos.DrawSphere(((Component)this).transform.position, 0.25f);
			}
			else
			{
				Gizmos.DrawSphere(((Component)this).transform.position, PlayerDistanceToSpawn);
			}
		}

		private void OnDrawGizmos()
		{
			//IL_0001: 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)
			Gizmos.color = Color.red;
			Gizmos.DrawSphere(((Component)this).transform.position, 0.1f);
		}
	}
	public static class LootManager
	{
		private static readonly int MAX_SPAWNS;

		public static int CurrentLevel;

		public static Dictionary<GameObject, LootSpawnPoint> spawnedLoot;

		private static List<LootObject> LootObjects;

		private static List<LootSpawnPoint> LootSpawns;

		private static List<LootObjectRandomizer> ObjectSpawns;

		private static Dictionary<int, ILootTrigger> LootTriggers;

		private static Dictionary<ILootTrigger, int> LootTriggerIds;

		private static int spawnPointsActivated;

		private static int LootTriggerCounter;

		public static readonly Vector2 MAG_AMOUNT_RANGE;

		public static readonly float Y_SPAWN_INCREMENT;

		static LootManager()
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Expected O, but got Unknown
			MAX_SPAWNS = -1;
			CurrentLevel = 0;
			spawnedLoot = new Dictionary<GameObject, LootSpawnPoint>();
			LootObjects = new List<LootObject>();
			LootSpawns = new List<LootSpawnPoint>();
			ObjectSpawns = new List<LootObjectRandomizer>();
			LootTriggers = new Dictionary<int, ILootTrigger>();
			LootTriggerIds = new Dictionary<ILootTrigger, int>();
			spawnPointsActivated = 0;
			LootTriggerCounter = 0;
			MAG_AMOUNT_RANGE = new Vector2(3f, 3f);
			Y_SPAWN_INCREMENT = 0.05f;
			SR_Manager.SupplyPointChangeEvent += new SupplyPointChangeDelegate(OnSupplyPointChange);
		}

		public static bool AddLootSpawn(LootSpawnPoint lootable)
		{
			LootSpawns.Add(lootable);
			return true;
		}

		public static void RemoveLootSpawn(LootSpawnPoint lootable)
		{
			if (LootSpawns.Contains(lootable))
			{
				LootSpawns.Remove(lootable);
			}
		}

		public static bool AddLootObject(LootObject obj)
		{
			LootObjects.Add(obj);
			return true;
		}

		public static ILootTrigger GetLootTriggerById(int id)
		{
			if (!LootTriggers.ContainsKey(id))
			{
				return null;
			}
			return LootTriggers[id];
		}

		public static int GetLootTriggerId(ILootTrigger trigger)
		{
			return LootTriggerIds[trigger];
		}

		public static bool AddLootTrigger(ILootTrigger trigger)
		{
			LootTriggers.Add(LootTriggerCounter, trigger);
			LootTriggerIds.Add(trigger, LootTriggerCounter);
			LootTriggerCounter++;
			return true;
		}

		public static bool RemoveLootTrigger(ILootTrigger trigger)
		{
			int key = LootTriggerIds[trigger];
			LootTriggerIds.Remove(trigger);
			LootTriggers.Remove(key);
			return true;
		}

		public static bool RemoveLootObject(LootObject obj)
		{
			if (!LootObjects.Contains(obj))
			{
				return false;
			}
			LootObjects.Remove(obj);
			return true;
		}

		public static bool AddRandomObject(LootObjectRandomizer obj)
		{
			ObjectSpawns.Add(obj);
			return true;
		}

		public static bool RemoveRandomObject(LootObjectRandomizer obj)
		{
			if (!ObjectSpawns.Contains(obj))
			{
				return false;
			}
			ObjectSpawns.Remove(obj);
			return true;
		}

		public static void OnPhysicalObjectPickup(GameObject obj)
		{
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Invalid comparison between Unknown and I4
			Networking.OnPhysicalObjectPickup(obj);
			if (!spawnedLoot.ContainsKey(obj))
			{
				return;
			}
			Lootations.Logger.LogDebug((object)"Removed object from tracked spawned loot pool.");
			spawnedLoot[obj].StopTrackingObject(obj);
			spawnedLoot.Remove(obj);
			FVRPhysicalObject[] componentsInChildren = obj.GetComponentsInChildren<FVRPhysicalObject>();
			foreach (FVRPhysicalObject val in componentsInChildren)
			{
				if (!((Object)(object)val.RootRigidbody == (Object)null))
				{
					val.RootRigidbody.constraints = (RigidbodyConstraints)126;
					if ((int)val.RootRigidbody.constraints == 126)
					{
						val.RootRigidbody.constraints = (RigidbodyConstraints)0;
					}
				}
			}
		}

		public static void OnGrabbityHandFlick(FVRPhysicalObject obj)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Invalid comparison between Unknown and I4
			if (spawnedLoot.ContainsKey(((Component)obj).gameObject) && (int)obj.RootRigidbody.constraints == 126)
			{
				obj.RootRigidbody.constraints = (RigidbodyConstraints)0;
				((Component)obj).transform.parent = null;
			}
		}

		public static void OnSceneSwitched()
		{
			Lootations.Logger.LogInfo((object)"Removing track of spawned items.");
			spawnedLoot.Clear();
			LootSpawns.Clear();
			LootObjects.Clear();
			ObjectSpawns.Clear();
			LootTriggers.Clear();
			LootTriggerIds.Clear();
			CurrentLevel = 0;
			LootTriggerCounter = 0;
		}

		public static void StopTrackingNetworkId(int trackingId)
		{
			Lootations.Logger.LogDebug((object)("Attempting to remove " + trackingId));
			if (Server.objects == null)
			{
				Lootations.Logger.LogError((object)"that stuff is null even");
				return;
			}
			if (trackingId < 0 && trackingId >= Server.objects.Length)
			{
				Lootations.Logger.LogError((object)"Clients.objects does not work like that it turns out");
				return;
			}
			TrackedObjectData val = Server.objects[trackingId];
			if (val == null)
			{
				Lootations.Logger.LogError((object)"stop tracking null check obj");
				return;
			}
			TrackedObject physical = val.physical;
			if ((Object)(object)physical == (Object)null)
			{
				Lootations.Logger.LogError((object)"stop tracking null check physical");
				return;
			}
			GameObject gameObject = ((Component)physical).gameObject;
			if ((Object)(object)gameObject == (Object)null)
			{
				Lootations.Logger.LogError((object)"stop tracking null check gameObj");
			}
			else if (spawnedLoot.ContainsKey(gameObject))
			{
				Lootations.Logger.LogDebug((object)("Stopped tracking loot with id " + trackingId));
				LootSpawnPoint lootSpawnPoint = spawnedLoot[gameObject];
				lootSpawnPoint.StopTrackingObject(gameObject);
			}
		}

		private static void ShuffleObjectRandomizers()
		{
			ObjectSpawns = ObjectSpawns.OrderBy((LootObjectRandomizer _) => Random.Range(0, int.MaxValue)).ToList();
		}

		private static void OnSupplyPointChange()
		{
			if (!SR_Manager.instance.gameCompleted)
			{
				CurrentLevel = SR_Manager.instance.CurrentCaptures;
				if (Networking.IsClient())
				{
					Lootations.Logger.LogDebug((object)"Awaiting reroll of loot as client.");
					return;
				}
				Lootations.Logger.LogDebug((object)"Rolling loot as host.");
				int frameCount = Time.frameCount;
				RerollLoot(frameCount);
			}
		}

		public static void OnTNHLevelSet(int level)
		{
			CurrentLevel = level;
			RerollLoot(Time.frameCount);
		}

		public static void RerollLoot(int seed = -1)
		{
			if (seed == -1)
			{
				seed = Time.frameCount;
			}
			Lootations.Logger.LogDebug((object)("Respawning objects with seed: " + seed));
			Random.InitState(seed);
			Networking.OnRerollLoot(seed);
			spawnPointsActivated = 0;
			ShuffleObjectRandomizers();
			spawnedLoot = new Dictionary<GameObject, LootSpawnPoint>();
			for (int i = 0; i < LootSpawns.Count; i++)
			{
				LootSpawnPoint lootSpawnPoint = LootSpawns[i];
				lootSpawnPoint.Reset();
			}
			bool flag = false;
			List<LootObjectRandomizer> list = new List<LootObjectRandomizer>();
			int j = 0;
			while (ObjectSpawns.Count != 0)
			{
				list.AddRange(ObjectSpawns);
				ObjectSpawns.Clear();
				for (; j < list.Count; j++)
				{
					if (MAX_SPAWNS != -1 && j >= MAX_SPAWNS)
					{
						ManualLogSource logger = Lootations.Logger;
						int mAX_SPAWNS = MAX_SPAWNS;
						logger.LogDebug((object)("Stopping respawn of loot objects, hit config limit of " + mAX_SPAWNS));
						flag = true;
						break;
					}
					if (((Behaviour)MG_Manager.instance).isActiveAndEnabled && MG_Manager.profile.srLootSpawns != 0 && j >= MG_Manager.profile.srLootSpawns)
					{
						Lootations.Logger.LogDebug((object)("Stopping respawn of loot objects, hit MG profile limit of " + MG_Manager.profile.srLootSpawns));
						flag = true;
						break;
					}
					LootObjectRandomizer lootObjectRandomizer = list[j];
					lootObjectRandomizer.RollAndSpawn();
					spawnPointsActivated++;
				}
			}
			ObjectSpawns = list;
			if (flag)
			{
				Lootations.Logger.LogWarning((object)"LootObject limit reached");
			}
			Lootations.Logger.LogInfo((object)("Spawned " + spawnPointsActivated + " objects."));
			for (int k = 0; k < LootObjects.Count; k++)
			{
				LootObject lootObject = LootObjects[k];
				lootObject.Reset();
			}
			int num = 0;
			if ((Object)(object)SR_Manager.instance != (Object)null && ((Behaviour)SR_Manager.instance).isActiveAndEnabled)
			{
				num = SR_Manager.instance.CurrentCaptures;
			}
		}

		public static Quaternion RandomRotation()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			return Quaternion.Euler(0f, Random.Range(0f, 360f), 0f);
		}
	}
	public class LootObject : MonoBehaviour
	{
		public delegate void TriggerResetDelegate();

		public delegate void LootObjectTriggeredDelegate();

		public GameObject[] LootSpawnPoints;

		private LootSpawnPoint[] spawnPoints;

		public bool OneShot = false;

		public bool HasResetDistanceGrace = true;

		[HideInInspector]
		public bool Triggered = false;

		public readonly float PLAYER_PROXIMITY_GRACE_DISTANCE = 25f;

		public event TriggerResetDelegate OnTriggerReset;

		public event LootObjectTriggeredDelegate LootObjectTriggered;

		public static void HookTrigger(GameObject lootObjectOwner, MonoBehaviour trigger)
		{
			LootObject lootObject = ((!((Object)(object)lootObjectOwner == (Object)null)) ? lootObjectOwner.GetComponent<LootObject>() : ((Component)trigger).GetComponent<LootObject>());
			if ((Object)(object)lootObject == (Object)null)
			{
				Lootations.Logger.LogError((object)("Cannot hook loot trigger on object without one: " + ((Object)lootObject).name));
			}
			else if (trigger is ILootTrigger)
			{
				ILootTrigger lootTrigger = trigger as ILootTrigger;
				lootObject.OnTriggerReset += lootTrigger.LootReset;
				lootTrigger.OnTriggered += lootObject.Trigger;
				LootManager.AddLootTrigger(lootTrigger);
			}
		}

		public void Awake()
		{
			if (LootSpawnPoints == null)
			{
				Lootations.Logger.LogWarning((object)"LootTrigger skipped initialization due to missing loot points.");
			}
			spawnPoints = Utilities.GameObjectsToPoints(LootSpawnPoints);
			LootManager.AddLootObject(this);
		}

		public void EnsureOwnerOfSpawnedItems()
		{
			List<GameObject> list = new List<GameObject>();
			LootSpawnPoint[] array = spawnPoints;
			foreach (LootSpawnPoint lootSpawnPoint in array)
			{
				list.AddRange(lootSpawnPoint.SpawnedLoot);
			}
			Networking.EnsureOwnerOfObjects(list);
		}

		public void Trigger(ILootTrigger trigger)
		{
			if (Triggered)
			{
				return;
			}
			Triggered = true;
			this.LootObjectTriggered?.Invoke();
			if (Lootations.h3mpEnabled && Networking.IsConnected())
			{
				Networking.SendTriggerActivated(LootManager.GetLootTriggerId(trigger));
				if (Networking.IsClient())
				{
					return;
				}
			}
			SpawnItemsAtLootSpawns();
		}

		private void SpawnItemsAtLootSpawns()
		{
			LootSpawnPoint[] array = spawnPoints;
			foreach (LootSpawnPoint lootSpawnPoint in array)
			{
				if (lootSpawnPoint == null)
				{
					Lootations.Logger.LogError((object)("Object: " + ((Object)this).name + " contained non loot spawn point!"));
				}
				else
				{
					lootSpawnPoint.Trigger();
				}
			}
		}

		public void Reset()
		{
			if (!OneShot)
			{
				Triggered = false;
				this.OnTriggerReset?.Invoke();
			}
		}

		public void OnDestroy()
		{
			LootManager.RemoveLootObject(this);
		}
	}
	public class LootObjectRandomizer : MonoBehaviour
	{
		public GameObject[] Objects = (GameObject[])(object)new GameObject[0];

		public bool RandomizeRotation = false;

		public Vector3 VisualizationSize = new Vector3(1f, 1f, 1f);

		private GameObject spawnedObject;

		public readonly float PLAYER_PROXIMITY_GRACE_DISTANCE = 35f;

		public bool ResetGrace = true;

		public void Awake()
		{
			LootManager.AddRandomObject(this);
			if (Objects.Length == 0)
			{
				Lootations.Logger.LogError((object)"LootObjectRandomizer has Objects of length 0.");
			}
		}

		public void Destroy()
		{
			if ((Object)(object)spawnedObject != (Object)null)
			{
				Object.Destroy((Object)(object)spawnedObject);
			}
			spawnedObject = null;
		}

		public void RollAndSpawn()
		{
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			if (Objects.Length == 0)
			{
				Lootations.Logger.LogWarning((object)"ObjectRandomizer told to spawn with objects of length 0.");
				return;
			}
			if ((Object)(object)spawnedObject != (Object)null)
			{
				Object.Destroy((Object)(object)spawnedObject);
			}
			int num = Random.Range(0, Objects.Length);
			spawnedObject = Objects[num];
			if ((Object)(object)spawnedObject == (Object)null)
			{
				Lootations.Logger.LogDebug((object)"ObjectRandomizer rolled null");
				return;
			}
			spawnedObject = Object.Instantiate<GameObject>(spawnedObject, ((Component)this).transform);
			if (RandomizeRotation)
			{
				spawnedObject.transform.Rotate(new Vector3(0f, Random.Range(0f, 360f), 0f));
			}
		}

		private void OnDrawGizmos()
		{
			//IL_0001: 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_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_003d: Unknown result type (might be due to invalid IL or missing references)
			Gizmos.color = Color.green;
			Gizmos.DrawCube(((Component)this).transform.position + new Vector3(0f, VisualizationSize.y / 2f, 0f), VisualizationSize);
		}
	}
	public class LootSpawnPoint : MonoBehaviour
	{
		public delegate void LootRolledDelegate(List<string> newLoot);

		public string TableName = "NONE";

		public float SpawnRadius = 0.25f;

		public bool RandomizeYRotation = true;

		[Header("Instance Settings")]
		public bool UseInstanceSettings = false;

		public float CullDistance = 250f;

		public bool RaycastDownOnSpawn = true;

		public bool LockPhysicsOnSpawn = false;

		public List<GameObject> SpawnedLoot = new List<GameObject>();

		private bool HasSpawnedLoot = false;

		private bool Culled = false;

		private float cullDistance = 50f;

		private static readonly float CULL_MIN_TIMER = 0.5f;

		private static readonly float CULL_RANDOM_DELAY_MAX = 2.5f;

		private Coroutine CullUpdateRoutine;

		private static readonly float RAYCAST_DISTANCE = 2f;

		public event LootRolledDelegate LootRolled;

		private void Awake()
		{
			bool active = LootManager.AddLootSpawn(this);
			((Component)this).gameObject.SetActive(active);
			if (Lootations.CullingEnabled.Value)
			{
				CullUpdateRoutine = ((MonoBehaviour)this).StartCoroutine(CullUpdate());
				if (UseInstanceSettings)
				{
					cullDistance = CullDistance;
				}
				else
				{
					cullDistance = Lootations.ItemCullingDistance.Value;
				}
			}
		}

		private IEnumerator CullUpdate()
		{
			while (true)
			{
				if (HasSpawnedLoot)
				{
					if (Culled)
					{
						if (Utilities.PlayerWithinDistance(((Component)this).transform.position, cullDistance))
						{
							foreach (GameObject go in SpawnedLoot)
							{
								go.SetActive(true);
							}
							Culled = false;
						}
					}
					else if (!Utilities.PlayerWithinDistance(((Component)this).transform.position, cullDistance))
					{
						foreach (GameObject go2 in SpawnedLoot)
						{
							go2.SetActive(false);
						}
						Culled = true;
					}
				}
				yield return (object)new WaitForSeconds(CULL_MIN_TIMER + Random.Range(0f, CULL_RANDOM_DELAY_MAX));
			}
		}

		public void StopTrackingObject(GameObject obj)
		{
			if (SpawnedLoot.Contains(obj))
			{
				SpawnedLoot.Remove(obj);
			}
		}

		public void Reset()
		{
			if (Lootations.h3mpEnabled && Networking.IsClient())
			{
				return;
			}
			foreach (GameObject item in SpawnedLoot)
			{
				Object.Destroy((Object)(object)item);
			}
			SpawnedLoot = new List<GameObject>();
			HasSpawnedLoot = false;
			Culled = false;
		}

		public virtual void Trigger()
		{
			((MonoBehaviour)this).StartCoroutine(SpawnLoot());
		}

		private void OnDrawGizmos()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: 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_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: 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_0087: 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)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			Gizmos.color = new Color(0f, 0.6f, 0f, 0.5f);
			Gizmos.DrawLine(((Component)this).transform.position, ((Component)this).transform.position + ((Component)this).transform.forward * SpawnRadius);
			Gizmos.color = new Color(0.6f, 0f, 0f, 0.5f);
			Gizmos.DrawLine(((Component)this).transform.position, ((Component)this).transform.position + ((Component)this).transform.forward * -1f * SpawnRadius);
			Gizmos.DrawLine(((Component)this).transform.position, ((Component)this).transform.position + ((Component)this).transform.right * SpawnRadius);
			Gizmos.DrawLine(((Component)this).transform.position, ((Component)this).transform.position + ((Component)this).transform.right * -1f * SpawnRadius);
		}

		private void OnDestroy()
		{
			LootManager.RemoveLootSpawn(this);
			if (CullUpdateRoutine != null)
			{
				((MonoBehaviour)this).StopCoroutine(CullUpdateRoutine);
			}
		}

		public GameObject ConstructAmmoBox(FVRFireArmRound baseRound)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: 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)
			Lootations.Logger.LogDebug((object)"Constructing ammo box.");
			GameObject ammoBox = AM.GetAmmoBox(baseRound.RoundType);
			ammoBox = Object.Instantiate<GameObject>(ammoBox, ((Component)this).transform.position, ((Component)this).transform.rotation);
			CartridgeBox component = ammoBox.GetComponent<CartridgeBox>();
			component.ConfigureShapeForRoundType(baseRound.RoundType, baseRound.RoundClass);
			return ammoBox;
		}

		public IEnumerator SpawnLoot()
		{
			if (Lootations.h3mpEnabled && Networking.IsClient())
			{
				yield break;
			}
			LootTable table = TableManager.GetTable(TableName);
			if (table == TableManager.NullTable)
			{
				yield break;
			}
			MetaTags tags = new MetaTags();
			List<string> objectIds = table.RollObjectId(ref tags);
			if (objectIds.Count == 0)
			{
				Lootations.Logger.LogDebug((object)"Skipped spawn due to rolling nothing.");
				yield break;
			}
			this.LootRolled?.Invoke(objectIds);
			for (int i = 0; i < objectIds.Count; i++)
			{
				string objectId = objectIds[i];
				if (!IM.OD.TryGetValue(objectId, out var obj))
				{
					Lootations.Logger.LogError((object)("No object found with id '" + objectId + "'."));
					break;
				}
				_ = ((Component)this).gameObject.transform;
				if ((Object)(object)obj != (Object)null && (int)obj.Category == 1)
				{
					FVRObject mag = ((!FirearmAPI.HasMagazine(obj)) ? obj.CompatibleSingleRounds[0] : FirearmAPI.GetSmallestMagazine(obj, (Func<FVRObject, bool>)null));
					int spawnAmount = Random.Range((int)LootManager.MAG_AMOUNT_RANGE.x, (int)LootManager.MAG_AMOUNT_RANGE.y);
					for (int j = 0; j < spawnAmount; j++)
					{
						AnvilCallback<GameObject> magCallback = ((AnvilAsset)mag).GetGameObjectAsync();
						yield return magCallback;
						SpawnItem(magCallback.Result, randomOffset: true);
						yield return null;
					}
				}
				AnvilCallback<GameObject> callback = ((AnvilAsset)obj).GetGameObjectAsync();
				yield return callback;
				FVRFireArmRound roundComponent = callback.Result.GetComponent<FVRFireArmRound>();
				GameObject spawnedObj = ((!tags.CartridgesAsAmmoBoxes || !((Object)(object)roundComponent != (Object)null)) ? SpawnItem(callback.Result) : SpawnItem(ConstructAmmoBox(roundComponent), randomOffset: false, alreadySpawnedObj: true));
				HasSpawnedLoot = true;
				tags.MagLoadRange.Apply(spawnedObj);
				yield return null;
				obj = null;
			}
		}

		private GameObject SpawnItem(GameObject obj, bool randomOffset = false, bool alreadySpawnedObj = false)
		{
			//IL_0014: 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)
			//IL_002d: 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_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0230: Unknown result type (might be due to invalid IL or missing references)
			//IL_0235: Unknown result type (might be due to invalid IL or missing references)
			//IL_0237: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_029c: Unknown result type (might be due to invalid IL or missing references)
			//IL_02aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_024b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0253: Unknown result type (might be due to invalid IL or missing references)
			//IL_0258: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0277: Unknown result type (might be due to invalid IL or missing references)
			//IL_0288: Unknown result type (might be due to invalid IL or missing references)
			//IL_028d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0292: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			Bounds val = default(Bounds);
			((Bounds)(ref val))..ctor(((Component)obj.transform.GetChild(0)).transform.position, Vector3.zero);
			LayerMask val2 = LayerMask.op_Implicit(LayerMask.NameToLayer("Default"));
			GameObject val3 = null;
			val3 = (alreadySpawnedObj ? obj : Object.Instantiate<GameObject>(obj, ((Component)this).transform.position, Quaternion.identity));
			obj.transform.rotation = Quaternion.identity;
			Renderer[] componentsInChildren = obj.GetComponentsInChildren<Renderer>();
			foreach (Renderer val4 in componentsInChildren)
			{
				if (((Component)val4).gameObject.layer == LayerMask.op_Implicit(val2) && val4.enabled)
				{
					((Bounds)(ref val)).Encapsulate(val4.bounds);
				}
			}
			Quaternion rotation = ((Component)this).transform.rotation;
			float num = 0f;
			Vector3 size = ((Bounds)(ref val)).size;
			float[] array = new float[3]
			{
				size.x * size.y,
				size.x * size.z,
				size.y * size.z
			};
			if (array[0] >= array[1] && array[0] >= array[2])
			{
				rotation = Quaternion.Euler(90f, 0f, 0f);
				num = size.z;
			}
			else if (array[1] >= array[0] && array[1] >= array[2])
			{
				rotation = Quaternion.Euler(0f, 0f, 0f);
				num = size.y;
			}
			else if (array[2] >= array[0] && array[2] >= array[1])
			{
				rotation = Quaternion.Euler(0f, 0f, 90f);
				num = size.x;
			}
			Vector3 zero = Vector3.zero;
			if (randomOffset)
			{
				((Vector3)(ref zero))..ctor(Random.Range(0f - SpawnRadius, SpawnRadius), 0f, Random.Range(0f - SpawnRadius, SpawnRadius));
			}
			Vector3 val5 = ((Component)this).transform.position + zero;
			RaycastHit val6 = default(RaycastHit);
			if (RaycastDownOnSpawn && Physics.Raycast(val5, ((Component)this).transform.TransformDirection(Vector3.down), ref val6, RAYCAST_DISTANCE, -1))
			{
				val5 = ((RaycastHit)(ref val6)).point + new Vector3(0f, num, 0f);
			}
			val3.transform.position = val5;
			val3.transform.rotation = rotation;
			if (RandomizeYRotation)
			{
				val3.transform.Rotate(Vector3.up, Random.Range(0f, 360f), (Space)0);
			}
			if (LockPhysicsOnSpawn)
			{
				val3.transform.SetParent(((Component)this).transform);
				FVRPhysicalObject[] componentsInChildren2 = val3.GetComponentsInChildren<FVRPhysicalObject>();
				foreach (FVRPhysicalObject val7 in componentsInChildren2)
				{
					val7.RootRigidbody.constraints = (RigidbodyConstraints)126;
				}
			}
			LootManager.spawnedLoot.Add(val3, this);
			SpawnedLoot.Add(val3);
			val3.SetActive(true);
			return val3;
		}
	}
	public static class H3MPNetworking
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static CustomPacketHandlerReceivedDelegate <0>__ReceiveClientPacketSync;
		}

		private static readonly string ITEM_GRAB_STRING_ID = "Lootations_ItemGrab";

		private static readonly string REROLL_LOOT_STRING_ID = "Lootations_RerollLoot";

		private static readonly string TRIGGER_ACTIVATED_STRING_ID = "Lootations_TriggerActivated";

		private static readonly string TRIGGER_DATA_STRING_ID = "Lootations_TriggerData";

		private static Dictionary<string, CustomPacketHandler> packetHandlers = new Dictionary<string, CustomPacketHandler>
		{
			{
				ITEM_GRAB_STRING_ID,
				new CustomPacketHandler(ReceiveItemGrab)
			},
			{
				REROLL_LOOT_STRING_ID,
				new CustomPacketHandler(ReceiveRerollLoot)
			},
			{
				TRIGGER_ACTIVATED_STRING_ID,
				new CustomPacketHandler(ReceiveTriggerActivated)
			},
			{
				TRIGGER_DATA_STRING_ID,
				new CustomPacketHandler(ReceiveTriggerData)
			}
		};

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

		public static void OnSceneSwitched(Scene old_scene, Scene new_scene)
		{
			InitializeNetworking();
		}

		public static void InitializeNetworking()
		{
			if (IsConnected())
			{
				SetupPacketTypes();
			}
		}

		private static void SetupPacketTypes()
		{
			//IL_0214: Unknown result type (might be due to invalid IL or missing references)
			//IL_0219: Unknown result type (might be due to invalid IL or missing references)
			//IL_021f: Expected O, but got Unknown
			Lootations.Logger.LogDebug((object)"Setting up packet types.");
			foreach (KeyValuePair<string, CustomPacketHandler> packetHandler in packetHandlers)
			{
				if (!packetIds.ContainsKey(packetHandler.Key))
				{
					Lootations.Logger.LogDebug((object)("Adding handler " + packetHandler.Key + " as default ID"));
					packetIds.Add(packetHandler.Key, -1);
				}
			}
			if (IsHost())
			{
				Lootations.Logger.LogDebug((object)"Setting up packets as host.");
				{
					foreach (KeyValuePair<string, CustomPacketHandler> packetHandler2 in packetHandlers)
					{
						Lootations.Logger.LogDebug((object)("Setting up handler " + packetHandler2.Key));
						if (Mod.registeredCustomPacketIDs.ContainsKey(packetHandler2.Key))
						{
							packetIds[packetHandler2.Key] = Mod.registeredCustomPacketIDs[packetHandler2.Key];
							Lootations.Logger.LogDebug((object)("Handler already existed as id " + packetIds[packetHandler2.Key]));
						}
						else
						{
							packetIds[packetHandler2.Key] = Server.RegisterCustomPacketType(packetHandler2.Key, 0);
							Lootations.Logger.LogDebug((object)("Handler registered as id " + packetIds[packetHandler2.Key]));
						}
						Mod.customPacketHandlers[packetIds[packetHandler2.Key]] = packetHandler2.Value;
					}
					return;
				}
			}
			if (!IsClient())
			{
				return;
			}
			Lootations.Logger.LogDebug((object)"Setting up packets as client.");
			object obj = <>O.<0>__ReceiveClientPacketSync;
			if (obj == null)
			{
				CustomPacketHandlerReceivedDelegate val = ReceiveClientPacketSync;
				<>O.<0>__ReceiveClientPacketSync = val;
				obj = (object)val;
			}
			Mod.CustomPacketHandlerReceived += (CustomPacketHandlerReceivedDelegate)obj;
			foreach (KeyValuePair<string, CustomPacketHandler> packetHandler3 in packetHandlers)
			{
				Lootations.Logger.LogDebug((object)("Processing handler " + packetHandler3.Key.ToString()));
				if (Mod.registeredCustomPacketIDs.ContainsKey(packetHandler3.Key))
				{
					packetIds[packetHandler3.Key] = Mod.registeredCustomPacketIDs[packetHandler3.Key];
					Mod.customPacketHandlers[packetIds[packetHandler3.Key]] = packetHandlers[packetHandler3.Key];
					Lootations.Logger.LogDebug((object)("Handler already registered as id " + packetIds[packetHandler3.Key]));
				}
				else
				{
					Lootations.Logger.LogDebug((object)"Registering the handler as new, awaiting ID from host.");
					ClientSend.RegisterCustomPacketType(packetHandler3.Key);
				}
			}
		}

		public static void ReceiveClientPacketSync(string ID, int index)
		{
			Lootations.Logger.LogDebug((object)("Got ClientPacketSync for HandlerID " + ID + " index: " + index));
			if (packetHandlers.ContainsKey(ID))
			{
				packetIds[ID] = index;
				Mod.customPacketHandlers[index] = packetHandlers[ID];
				Lootations.Logger.LogDebug((object)("Successfully connected handling for packet ID: " + ID));
			}
		}

		public static bool IsConnected()
		{
			return Lootations.h3mpEnabled && (Object)(object)Mod.managerObject != (Object)null;
		}

		public static bool IsClient()
		{
			return IsConnected() && !ThreadManager.host;
		}

		public static bool IsHost()
		{
			return IsConnected() && ThreadManager.host;
		}

		public static int[] GetPlayerIds()
		{
			int count = GameManager.players.Count;
			int[] array = new int[count];
			int num = 0;
			foreach (KeyValuePair<int, PlayerManager> player in GameManager.players)
			{
				array[num] = player.Key;
				num++;
			}
			return array;
		}

		public static Vector3 GetPlayerPosition(int id)
		{
			//IL_0011: 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_0019: Unknown result type (might be due to invalid IL or missing references)
			return ((Component)PlayerData.GetPlayer(id).head).transform.position;
		}

		public static void SendItemGrab(GameObject obj)
		{
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Expected O, but got Unknown
			if (!IsClient())
			{
				return;
			}
			if ((Object)(object)obj == (Object)null)
			{
				Lootations.Logger.LogDebug((object)"Obj is, somehow, null");
				return;
			}
			TrackedItem component = obj.GetComponent<TrackedItem>();
			if ((Object)(object)component == (Object)null)
			{
				Lootations.Logger.LogDebug((object)"Obj found but no TrackedItem");
				return;
			}
			TrackedObjectData data = ((TrackedObject)component).data;
			if (data == null)
			{
				Lootations.Logger.LogDebug((object)"Tried to get tracking of object that doesn't have it!");
				return;
			}
			Packet val = new Packet(packetIds[ITEM_GRAB_STRING_ID]);
			val.Write(data.trackedID);
			ClientSend.SendTCPData(val, true);
		}

		public static void ReceiveItemGrab(int clientId, Packet packet)
		{
			Lootations.Logger.LogDebug((object)"Item grab packet received");
			int trackingId = packet.ReadInt(true);
			LootManager.StopTrackingNetworkId(trackingId);
		}

		public static void SendRerollLoot(int seed)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			Packet val = new Packet(packetIds[REROLL_LOOT_STRING_ID]);
			val.Write(seed);
			ServerSend.SendTCPDataToAll(val, true);
		}

		public static void ReceiveRerollLoot(int clientId, Packet p)
		{
			int seed = p.ReadInt(true);
			if (IsHost())
			{
				Lootations.Logger.LogInfo((object)"Ignoring reroll loot packet as host.");
			}
			else
			{
				LootManager.RerollLoot(seed);
			}
		}

		public static void SendTriggerActivated(int id)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			Packet val = new Packet(packetIds[TRIGGER_ACTIVATED_STRING_ID]);
			val.Write(id);
			if (IsClient())
			{
				ClientSend.SendTCPData(val, true);
			}
			else
			{
				ServerSend.SendTCPDataToAll(val, true);
			}
		}

		public static void ReceiveTriggerActivated(int clientId, Packet packet)
		{
			int id = packet.ReadInt(true);
			ILootTrigger lootTriggerById = LootManager.GetLootTriggerById(id);
			if (lootTriggerById == null)
			{
				Lootations.Logger.LogError((object)"Got packet to trigger non-existing loot trigger!");
			}
			else
			{
				lootTriggerById.Trigger();
			}
		}

		public static void SendTriggerDataUDP(ILootTrigger trigger, List<byte> bytes)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			Packet val = new Packet(packetIds[TRIGGER_DATA_STRING_ID]);
			val.Write(LootManager.GetLootTriggerId(trigger));
			val.buffer.AddRange(bytes);
			if (IsClient())
			{
				Networking.DebugPrintDataList(val.buffer);
				ClientSend.SendUDPData(val, true);
			}
			else
			{
				Lootations.Logger.LogDebug((object)"Sending Trigger data as server");
				ServerSend.SendUDPData(GetPlayerIds().ToList(), val, 0, true, (object)null);
			}
		}

		public static void SendTriggerDataTCP(ILootTrigger trigger, List<byte> bytes)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			Packet val = new Packet(packetIds[TRIGGER_DATA_STRING_ID]);
			val.Write(LootManager.GetLootTriggerId(trigger));
			val.buffer.AddRange(bytes);
			if (IsClient())
			{
				ClientSend.SendTCPData(val, true);
			}
			else
			{
				ServerSend.SendTCPDataToAll(val, true);
			}
		}

		public static void ReceiveTriggerData(int clientId, Packet packet)
		{
			int id = packet.ReadInt(true);
			ILootTrigger lootTriggerById = LootManager.GetLootTriggerById(id);
			if (lootTriggerById == null)
			{
				Lootations.Logger.LogWarning((object)("Got packet for non-existant trigger with id: " + id));
				return;
			}
			if (clientId == 0 || IsHost())
			{
			}
			ITriggerDataReceiver triggerDataReceiver = lootTriggerById as ITriggerDataReceiver;
			List<byte> range = packet.buffer.GetRange(packet.readPos, packet.buffer.Count - packet.readPos);
			if (triggerDataReceiver != null)
			{
				triggerDataReceiver.ReceiveTriggerData(range);
			}
			else
			{
				Lootations.Logger.LogWarning((object)("Received trigger data for non data-receiver trigger with id: " + id));
			}
		}

		public static void EnsureOwnerOfObjects(List<GameObject> objects)
		{
			int iD = GameManager.ID;
			foreach (GameObject @object in objects)
			{
				TrackedObject component = @object.GetComponent<TrackedObject>();
				if (!((Object)(object)component == (Object)null) && component.data.controller != iD)
				{
					if (IsHost())
					{
						ServerSend.GiveObjectControl(component.data.trackedID, iD, (List<int>)null);
					}
					else
					{
						ClientSend.GiveObjectControl(component.data.trackedID, iD, (List<int>)null);
					}
				}
			}
		}
	}
	public static class Networking
	{
		public const bool DEBUG_PRINT_PACKETS = true;

		public static int PACKET_DUMP_NBR;

		public static bool IsConnected()
		{
			if (!Lootations.h3mpEnabled)
			{
				return false;
			}
			return H3MPIsConnected();
		}

		private static bool H3MPIsConnected()
		{
			return H3MPNetworking.IsConnected();
		}

		public static bool IsClient()
		{
			return IsConnected() && H3MPIsClient();
		}

		private static bool H3MPIsClient()
		{
			return H3MPNetworking.IsClient();
		}

		public static bool IsHost()
		{
			return IsConnected() && H3MPIsHost();
		}

		private static bool H3MPIsHost()
		{
			return H3MPNetworking.IsHost();
		}

		public static void OnSceneSwitched(Scene _oldScene, Scene _newScene)
		{
			if (Lootations.h3mpEnabled)
			{
				H3MPInitializeNetworking();
			}
		}

		private static void H3MPInitializeNetworking()
		{
			H3MPNetworking.InitializeNetworking();
		}

		public static void OnPhysicalObjectPickup(GameObject obj)
		{
			if (IsClient())
			{
				H3MPSendItemGrab(obj);
			}
		}

		private static void H3MPSendItemGrab(GameObject obj)
		{
			H3MPNetworking.SendItemGrab(obj);
		}

		public static void OnRerollLoot(int seed)
		{
			if (IsHost())
			{
				H3MPSendRerollLoot(seed);
			}
		}

		private static void H3MPSendRerollLoot(int seed)
		{
			H3MPNetworking.SendRerollLoot(seed);
		}

		public static int[] GetPlayerIds()
		{
			if (IsConnected())
			{
				return H3MPGetPlayerIds();
			}
			return new int[0];
		}

		private static int[] H3MPGetPlayerIds()
		{
			return H3MPNetworking.GetPlayerIds();
		}

		public static Vector3 GetPlayerPosition(int id)
		{
			//IL_0014: 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)
			//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_001c: Unknown result type (might be due to invalid IL or missing references)
			if (IsConnected())
			{
				return H3MPGetPlayerPosition(id);
			}
			return Vector3.zero;
		}

		private static Vector3 H3MPGetPlayerPosition(int id)
		{
			//IL_0002: 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_000a: Unknown result type (might be due to invalid IL or missing references)
			return H3MPNetworking.GetPlayerPosition(id);
		}

		public static void SendTriggerActivated(int id)
		{
			if (IsConnected())
			{
				H3MPSendTriggerActivated(id);
			}
		}

		private static void H3MPSendTriggerActivated(int id)
		{
			H3MPNetworking.SendTriggerActivated(id);
		}

		public static void SendTriggerDataTCP(ILootTrigger trigger, List<byte> data)
		{
			if (IsConnected())
			{
				H3MPSendTriggerData(trigger, data, sendTCP: true);
			}
		}

		public static void SendTriggerDataUDP(ILootTrigger trigger, List<byte> data)
		{
			if (IsConnected())
			{
				H3MPSendTriggerData(trigger, data, sendTCP: false);
			}
		}

		private static void H3MPSendTriggerData(ILootTrigger trigger, List<byte> data, bool sendTCP)
		{
			if (sendTCP)
			{
				H3MPNetworking.SendTriggerDataTCP(trigger, data);
			}
			else
			{
				H3MPNetworking.SendTriggerDataUDP(trigger, data);
			}
		}

		public static void DebugPrintDataList(List<byte> data)
		{
			bool flag = false;
			PACKET_DUMP_NBR++;
			Lootations.Logger.LogDebug((object)("STARTING PACKET DUMP #" + PACKET_DUMP_NBR));
			string text = "";
			foreach (byte datum in data)
			{
				text += datum;
				text += ",";
			}
			Lootations.Logger.LogDebug((object)text);
		}

		public static void EnsureOwnerOfObjects(List<GameObject> objects)
		{
			if (IsConnected())
			{
				H3MPEnsureOwnerOfObjects(objects);
			}
		}

		private static void H3MPEnsureOwnerOfObjects(List<GameObject> objects)
		{
			H3MPNetworking.EnsureOwnerOfObjects(objects);
		}
	}
	[HarmonyPatch(typeof(FVRViveHand), "Update")]
	public class FVRGrabLaserManipulablePatch
	{
		private static void Postfix(FVRViveHand __instance)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			if (((!__instance.IsInStreamlinedMode || !__instance.Input.BYButtonPressed) && !__instance.Input.TouchpadPressed) || (int)__instance.m_state != 0 || !((Object)(object)__instance.CurrentHoveredQuickbeltSlot == (Object)null) || !((Object)(object)((RaycastHit)(ref __instance.m_grabHit)).collider != (Object)null))
			{
				return;
			}
			if ((Object)(object)((Component)((RaycastHit)(ref __instance.m_grabHit)).collider).gameObject == (Object)null)
			{
				Lootations.Logger.LogDebug((object)"go from collider is null");
				return;
			}
			IDistantManipulable component = ((Component)((RaycastHit)(ref __instance.m_grabHit)).collider).gameObject.GetComponent<IDistantManipulable>();
			if (component == null)
			{
				return;
			}
			if (!__instance.BlueLaser.activeSelf)
			{
				__instance.BlueLaser.SetActive(true);
			}
			if (__instance.RedLaser.activeSelf)
			{
				__instance.RedLaser.SetActive(false);
			}
			if (__instance.Input.IsGrabDown)
			{
				Lootations.Logger.LogDebug((object)"Doing a distant interact");
				FVRInteractiveObject component2 = ((Component)((RaycastHit)(ref __instance.m_grabHit)).collider).gameObject.GetComponent<FVRInteractiveObject>();
				if ((Object)(object)component2 == (Object)null)
				{
					Lootations.Logger.LogDebug((object)"Could not get interactive object from distant manipulable");
					return;
				}
				__instance.CurrentInteractable = component2;
				__instance.m_state = (HandState)1;
				component2.BeginInteraction(__instance);
				component.OnDistantInteract(__instance);
				__instance.Buzz(__instance.Buzzer.Buzz_BeginInteraction);
			}
		}
	}
	[HarmonyPatch(typeof(FVRPhysicalObject), "BeginInteraction")]
	internal class FVRPhysicalObjectPatch
	{
		private static void Postfix(FVRPhysicalObject __instance)
		{
			LootManager.OnPhysicalObjectPickup(((Component)__instance).gameObject);
		}
	}
	[HarmonyPatch(typeof(FVRViveHand), "BeginFlick")]
	internal class FVRViveHandPatch
	{
		public static void Prefix(FVRPhysicalObject o)
		{
			LootManager.OnGrabbityHandFlick(o);
		}
	}
	[HarmonyPatch(typeof(IM), "GenerateItemDBs")]
	public class GenerateItemDBsPatch
	{
		public static void Postfix()
		{
			TableManager.Initialize();
		}
	}
	[HarmonyPatch(typeof(TNH_Manager), "SetLevel")]
	public class TNHManagerSetLevelHook
	{
		public static void Postfix(int level)
		{
		}
	}
	[BepInProcess("h3vr.exe")]
	[BepInPlugin("Wilnath.Lootations", "Lootations", "1.0.0")]
	public class Lootations : BaseUnityPlugin
	{
		public static bool h3mpEnabled;

		public static ConfigEntry<int> MaxRandomLootObjectSpawns;

		public static ConfigEntry<float> ProximitySpawnDistance;

		public static ConfigEntry<float> ItemCullingDistance;

		public static ConfigEntry<float> SosigSpawnDistance;

		public static ConfigEntry<float> SosigDeSpawnDistance;

		public static ConfigEntry<bool> CullingEnabled;

		public static ConfigEntry<string> DisabledModDrops;

		private static Harmony harmonyInstance;

		public const string Id = "Wilnath.Lootations";

		internal static ManualLogSource Logger { get; private set; }

		public static string Name => "Lootations";

		public static string Version => "1.0.0";

		private void Awake()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			Logger = ((BaseUnityPlugin)this).Logger;
			harmonyInstance = new Harmony("LootationsHarmonyInstance");
			harmonyInstance.PatchAll();
			SetupConfig();
			h3mpEnabled = Chainloader.PluginInfos.ContainsKey("VIP.TommySoucy.H3MP");
			SceneManager.activeSceneChanged += OnSceneSwitched;
			if (h3mpEnabled)
			{
				Logger.LogDebug((object)"H3MP Detected as enabled");
				SceneManager.activeSceneChanged += Networking.OnSceneSwitched;
			}
			else
			{
				Logger.LogDebug((object)"Starting with no H3MP");
			}
		}

		private void OnSceneSwitched(Scene old_scene, Scene new_scene)
		{
			Logger.LogDebug((object)"Scene switch occurred");
			LootManager.OnSceneSwitched();
		}

		private void SetupConfig()
		{
			MaxRandomLootObjectSpawns = ((BaseUnityPlugin)this).Config.Bind<int>("Gameplay", "MaxRandomLootObjectSpawns", 250, "The maximum amount of random loot objects that will spawn per level. -1 to disable");
			DisabledModDrops = ((BaseUnityPlugin)this).Config.Bind<string>("Gameplay", "DisabledModDrops", "", "Plugin names that should count as not being loaded for loot tables. Seperate plugin names with a colon");
			SosigSpawnDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Performance", "SosigSpawnDistance", 75f, "How far away you have to be for sausages to spawn in.");
			SosigDeSpawnDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Performance", "SosigDeSpawnDistance", 150f, "TODO");
			ProximitySpawnDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Performance", "ProximitySpawnDistance", 25f, "Distance until Proximity triggers activate, can be expensive if too far.\nNote: Some proximity triggers override this setting.");
			CullingEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Experimental", "Culling", true, "If untouched items are to be disabled after player is set distance away from the loot spawn point.");
			ItemCullingDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Experimental", "ItemCullingDistance", 50f, "The distance at which items are set to be inactive.");
		}
	}
	public class LootTable
	{
		public string Name { get; private set; }

		public string[] Meta { get; set; }

		public List<TableEntry> Entries { get; private set; } = new List<TableEntry>();

		public int TotalWeight { get; set; } = -1;

		public LootTable(string name, TableEntry[] entries)
		{
			foreach (TableEntry entry in entries)
			{
				AddEntry(entry);
			}
			Name = name;
		}

		public void AddEntry(TableEntry entry)
		{
			Entries.Add(entry);
		}

		public List<string> RollObjectId(ref MetaTags tags)
		{
			MetaTags.UpdateTags(this, ref tags);
			if (tags.LevelSwitch)
			{
				Lootations.Logger.LogDebug((object)("Loot manager says current level is " + LootManager.CurrentLevel));
				int num = Entries.Count - 1;
				int num2 = Mathf.Clamp(LootManager.CurrentLevel, 0, num);
				Lootations.Logger.LogDebug((object)("Level to be rolled as " + num2));
				foreach (TableEntry entry in Entries)
				{
					if (entry.Weight == num2)
					{
						return entry.RollObjectId(ref tags);
					}
				}
				Lootations.Logger.LogError((object)("Undefined Level Switch on current level " + num2 + " in table " + Name));
				return new List<string>();
			}
			if (TotalWeight == -1)
			{
				CalculateTotalWeight();
			}
			if (TotalWeight == 0)
			{
				Lootations.Logger.LogError((object)("Total weight calculated to be 0 in " + Name));
				return new List<string>();
			}
			int num3 = Random.Range(1, TotalWeight + 1);
			foreach (TableEntry entry2 in Entries)
			{
				if (num3 <= entry2.Weight)
				{
					return entry2.RollObjectId(ref tags);
				}
				num3 -= entry2.Weight;
			}
			Lootations.Logger.LogError((object)("Could not roll any ids in " + Name));
			return new List<string>();
		}

		public void CalculateTotalWeight()
		{
			TotalWeight = 0;
			foreach (TableEntry entry in Entries)
			{
				TotalWeight += entry.Weight;
			}
		}
	}
	public interface IValidator
	{
		bool IsValid();
	}
	public class MagLoadRangeTag
	{
		public float x = 1f;

		public float y = 1f;

		public void Apply(GameObject obj)
		{
			FVRFireArmMagazine component = obj.GetComponent<FVRFireArmMagazine>();
			if ((Object)(object)component != (Object)null)
			{
				Apply(component);
			}
		}

		public void Apply(GameObject obj, FireArmRoundClass fireArmClass)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			FVRFireArmMagazine component = obj.GetComponent<FVRFireArmMagazine>();
			if ((Object)(object)component != (Object)null)
			{
				Apply(component, fireArmClass);
			}
		}

		public void Apply(FVRFireArmMagazine mag)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			if (mag.LoadedRounds.Length == 0)
			{
				Lootations.Logger.LogError((object)"Unable to apply MagRange to dropped item: No Default Rounds");
			}
			else
			{
				Apply(mag, mag.LoadedRounds.First().LR_Class);
			}
		}

		public void Apply(FVRFireArmMagazine mag, FireArmRoundClass fireArmClass)
		{
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			if (IsEnabled())
			{
				if (x == 0f && y == 0f)
				{
					mag.ForceEmpty();
					mag.UpdateBulletDisplay();
				}
				else
				{
					float num = ((x != y) ? Random.Range(x, y) : x);
					mag.ReloadMagWithTypeUpToPercentage(fireArmClass, num);
					mag.UpdateBulletDisplay();
				}
			}
		}

		private static void Parser(string s, ref MetaTags tags)
		{
			string[] array = s.Split(new char[1] { ',' });
			float result;
			float result2;
			if (array.Length == 0 || array.Length > 2)
			{
				Lootations.Logger.LogError((object)"Invalid mag load range parameter amount");
			}
			else if (!float.TryParse(array[0], out result))
			{
				Lootations.Logger.LogError((object)"Failed converting mag load range into float");
			}
			else if (array.Length == 1)
			{
				SetAsStatic(result, ref tags);
			}
			else if (!float.TryParse(array[1], out result2))
			{
				Lootations.Logger.LogError((object)"Failed converting mag load range into float");
			}
			else
			{
				SetAsRange(result, result2, ref tags);
			}
		}

		public static void SetAsStatic(float v1, ref MetaTags tags)
		{
			tags.MagLoadRange.x = v1;
			tags.MagLoadRange.y = v1;
		}

		public static void SetAsRange(float v1, float v2, ref MetaTags tags)
		{
			if (v2 < v1)
			{
				float num = v2;
				v2 = v1;
				v1 = num;
			}
			tags.MagLoadRange.x = v1;
			tags.MagLoadRange.y = v2;
		}

		private bool IsEnabled()
		{
			return x != 1f || y != 1f;
		}

		public static MetaTags.MetaTagsFunction GetMetaTagParser()
		{
			return Parser;
		}
	}
	public class MetaTags
	{
		public delegate void MetaTagsFunction(string s, ref MetaTags tags);

		private static Dictionary<string, MetaTagsFunction> keyToMethod = new Dictionary<string, MetaTagsFunction>
		{
			{
				"ModDependency",
				delegate(string s, ref MetaTags tags)
				{
					tags.Validators.Add(new ModDependency(s));
				}
			},
			{
				"CartridgesAsAmmoBoxes",
				delegate(string s, ref MetaTags tags)
				{
					tags.CartridgesAsAmmoBoxes = s.ToLower() == "true";
				}
			},
			{
				"LevelSwitch",
				delegate(string s, ref MetaTags tags)
				{
					tags.LevelSwitch = s.ToLower() == "true";
				}
			},
			{
				"MagLoadRange",
				MagLoadRangeTag.GetMetaTagParser()
			}
		};

		public List<IValidator> Validators = new List<IValidator>();

		public bool CartridgesAsAmmoBoxes = false;

		public MagLoadRangeTag MagLoadRange = new MagLoadRangeTag();

		public bool LevelSwitch = false;

		private static void ResetOneShotTags(ref MetaTags tags)
		{
			tags.LevelSwitch = false;
		}

		public static void UpdateTags(LootTable table, ref MetaTags tags)
		{
			ResetOneShotTags(ref tags);
			string[] meta = table.Meta;
			string[] array = meta;
			foreach (string text in array)
			{
				string[] array2 = text.Split(new char[1] { ':' });
				if (array2.Length != 2)
				{
					Lootations.Logger.LogWarning((object)"Skipping meta tag with ambiguous key:value pair");
					continue;
				}
				string text2 = array2[0].Trim();
				if (!keyToMethod.ContainsKey(text2))
				{
					Lootations.Logger.LogWarning((object)("Skipping meta tag with non-existing meta key: " + text2));
					continue;
				}
				string s = array2[1].Trim();
				keyToMethod[text2](s, ref tags);
			}
		}

		public bool IsZeroWeightEntriesValid()
		{
			return LevelSwitch;
		}
	}
	public class ModDependency : IValidator
	{
		private string _modDependency;

		public ModDependency(string modDependency)
		{
			_modDependency = modDependency;
		}

		public bool IsValid()
		{
			if (Lootations.DisabledModDrops != null && Lootations.DisabledModDrops.Value.Split(new char[1] { ',' }).Contains(_modDependency))
			{
				return false;
			}
			return Chainloader.PluginInfos.ContainsKey(_modDependency);
		}
	}
	public class TableEntry
	{
		public enum TableType
		{
			OBJECT_ID,
			TABLE_REFERENCE,
			TAGS
		}

		public TableType Type { get; set; }

		public int Weight { get; set; }

		public List<string> LootIds { get; set; }

		public static TableEntry ObjectEntry(string objectId, int weight)
		{
			return new TableEntry
			{
				Weight = weight,
				LootIds = new List<string>(1) { objectId },
				Type = TableType.OBJECT_ID
			};
		}

		public static TableEntry TableReference(string tableName, int weight)
		{
			return new TableEntry
			{
				Weight = weight,
				LootIds = new List<string>(1) { tableName },
				Type = TableType.TABLE_REFERENCE
			};
		}

		public List<string> RollObjectId(ref MetaTags tags)
		{
			switch (Type)
			{
			case TableType.OBJECT_ID:
				return LootIds;
			case TableType.TABLE_REFERENCE:
				return TableManager.GetTable(LootIds[0]).RollObjectId(ref tags);
			case TableType.TAGS:
				return new List<string>();
			default:
				Lootations.Logger.LogError((object)"Invalid TableEntry Type. Returning None.");
				return new List<string>();
			}
		}

		private bool IsTagAndValueValid(string tag, string value)
		{
			Type type = ((object)IM.OD["BulbBlue"]).GetType();
			PropertyInfo property = type.GetProperty(tag.Insert(0, "Tag"));
			if ((object)property == null)
			{
				Lootations.Logger.LogError((object)("Could not find tag with name " + property));
				return false;
			}
			return true;
		}

		private void InitializeTagTable()
		{
			if (Type != TableType.TAGS || LootIds.Count == 0)
			{
				return;
			}
			string[] array = LootIds[0].Split(new char[1] { ':' });
			if (array.Length != 2)
			{
				Lootations.Logger.LogError((object)"Error parsing tags in tag table entry, invalid argument length");
				return;
			}
			string tag = array[0];
			string value = array[1];
			List<string> list = new List<string>();
			if (!IsTagAndValueValid(tag, value))
			{
			}
			foreach (KeyValuePair<string, FVRObject> item in IM.OD)
			{
			}
		}
	}
	public static class TableManager
	{
		private static Dictionary<string, LootTable> _lootTables;

		public static readonly LootTable NullTable = new LootTable("NONE", new TableEntry[1] { TableEntry.ObjectEntry("NONE", 1) });

		public static void Initialize()
		{
			_lootTables = new Dictionary<string, LootTable>();
			Lootations.Logger.LogInfo((object)"Begun reading loot table files.");
			string[] files = Directory.GetFiles(Paths.PluginPath, "*.lttbl", SearchOption.AllDirectories);
			string[] array = files;
			foreach (string fileName in array)
			{
				ProcessFile(fileName);
			}
			ValidateAllTables();
		}

		private static void ValidateAllTables()
		{
			foreach (KeyValuePair<string, LootTable> lootTable in _lootTables)
			{
				LootTable value = lootTable.Value;
				RemoveZeroWeightEntries(value);
				ValidateObjectIds(lootTable.Value);
			}
			foreach (KeyValuePair<string, LootTable> lootTable2 in _lootTables)
			{
				lootTable2.Value.CalculateTotalWeight();
			}
			foreach (KeyValuePair<string, LootTable> lootTable3 in _lootTables)
			{
				ValidateReferences(lootTable3.Value);
			}
		}

		private static void RemoveZeroWeightEntries(LootTable table)
		{
			MetaTags tags = new MetaTags();
			MetaTags.UpdateTags(table, ref tags);
			if (tags.IsZeroWeightEntriesValid())
			{
				return;
			}
			for (int i = 0; i < table.Entries.Count; i++)
			{
				TableEntry tableEntry = table.Entries[i];
				if (tableEntry.Weight == 0)
				{
					Lootations.Logger.LogDebug((object)("Removing 0 weight entry from table " + table.Name));
					table.Entries.RemoveAt(i);
					i--;
				}
			}
		}

		private static void ValidateObjectIds(LootTable table)
		{
			for (int i = 0; i < table.Entries.Count; i++)
			{
				if (table.Entries[i].Type == TableEntry.TableType.TABLE_REFERENCE)
				{
					continue;
				}
				List<string> lootIds = table.Entries[i].LootIds;
				for (int j = 0; j < lootIds.Count; j++)
				{
					string text = lootIds[j];
					if (!IM.OD.ContainsKey(text))
					{
						Lootations.Logger.LogDebug((object)("Unknown object id " + text + " in table " + table.Name));
					}
				}
				if (lootIds.Count == 0)
				{
					table.Entries.RemoveAt(i);
					table.CalculateTotalWeight();
					Lootations.Logger.LogDebug((object)("Removing entry with no object IDs in table " + table.Name));
					Lootations.Logger.LogDebug((object)"(If this table is intended to have nothing, add a 1 weight entry to drop 'NONE')");
					i--;
				}
			}
		}

		private static void ValidateReferences(LootTable table)
		{
			for (int i = 0; i < table.Entries.Count; i++)
			{
				TableEntry tableEntry = table.Entries[i];
				if (tableEntry.Type == TableEntry.TableType.TABLE_REFERENCE)
				{
					if (GetTable(tableEntry.LootIds[0]) == NullTable)
					{
						Lootations.Logger.LogWarning((object)("Reference to non-existant table " + tableEntry.LootIds[0] + " in " + table.Name));
						table.Entries.RemoveAt(i);
						table.CalculateTotalWeight();
						i--;
					}
					else if (GetTable(tableEntry.LootIds[0]).TotalWeight == 0)
					{
						Lootations.Logger.LogDebug((object)("Deleting reference entry to empty table " + tableEntry.LootIds[0] + " in " + table.Name));
						table.Entries.RemoveAt(i);
						table.CalculateTotalWeight();
						i--;
					}
				}
			}
		}

		public static void AddLootTable(LootTable table)
		{
			MetaTags tags = new MetaTags();
			MetaTags.UpdateTags(table, ref tags);
			foreach (IValidator validator in tags.Validators)
			{
				if (!validator.IsValid())
				{
					Lootations.Logger.LogInfo((object)("Skipping loading table due to failed validator: " + table.Name));
					return;
				}
			}
			if (_lootTables.ContainsKey(table.Name))
			{
				Lootations.Logger.LogInfo((object)("Appending to table " + table.Name));
				LootTable lootTable = _lootTables[table.Name];
				{
					foreach (TableEntry entry in table.Entries)
					{
						lootTable.Entries.Add(entry);
					}
					return;
				}
			}
			_lootTables.Add(table.Name, table);
		}

		public static LootTable GetTable(string name)
		{
			if (!_lootTables.TryGetValue(name, out var value))
			{
				Lootations.Logger.LogWarning((object)("Attempt to access nonexistant table " + name));
				return NullTable;
			}
			return value;
		}

		private static void ProcessFile(string fileName)
		{
			string text = File.ReadAllText(fileName);
			List<LootTable> list = JsonConvert.DeserializeObject<List<LootTable>>(text);
			foreach (LootTable item in list)
			{
				AddLootTable(item);
			}
		}
	}
	public interface IDistantManipulable
	{
		void OnDistantInteract(FVRViveHand hand);
	}
	public interface ILootTrigger
	{
		public delegate void OnTriggeredDelegate(ILootTrigger trigger);

		event OnTriggeredDelegate OnTriggered;

		void Trigger();

		void LootReset();
	}
	internal interface ITriggerDataReceiver
	{
		void ReceiveTriggerData(List<byte> data);
	}
	public class LootCardScanTrigger : MonoBehaviour, ILootTrigger
	{
		public GameObject LootObjectOwner;

		public int KeycardTier = 1;

		public event ILootTrigger.OnTriggeredDelegate OnTriggered;

		public void Awake()
		{
			LootObject.HookTrigger(LootObjectOwner, (MonoBehaviour)(object)this);
		}

		private void OnTriggerEnter(Collider other)
		{
			WW_Keycard component = ((Component)other).GetComponent<WW_Keycard>();
			if ((Object)(object)component != (Object)null && component.TierType == KeycardTier)
			{
				Trigger();
			}
		}

		public void Trigger()
		{
			this.OnTriggered?.Invoke(this);
		}

		private void OnDrawGizmos()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			Gizmos.color = new Color(0f, 0.6f, 0f, 0.5f);
		}

		public void LootReset()
		{
		}
	}
	public class LootCoverTrigger : FVRInteractiveObject, ILootTrigger, IDistantManipulable, ITriggerDataReceiver
	{
		public GameObject LootObjectOwner;

		public Transform Root;

		public Transform Hinge;

		private float startAngle = 0f;

		private Vector3 offset = Vector3.zero;

		public float MinRot = 0f;

		public float MaxRot = 45f;

		public event ILootTrigger.OnTriggeredDelegate OnTriggered;

		public override void Awake()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			((FVRInteractiveObject)this).Awake();
			startAngle = ((Component)Hinge).transform.localEulerAngles.z;
			if ((Object)(object)Root == (Object)null || (Object)(object)Hinge == (Object)null)
			{
				Lootations.Logger.LogError((object)"CoverTrigger doesn't have a root or hinge, this is misconfigured!");
				((Component)this).gameObject.SetActive(false);
			}
			else
			{
				LootObject.HookTrigger(LootObjectOwner, (MonoBehaviour)(object)this);
			}
		}

		public void Trigger()
		{
			this.OnTriggered?.Invoke(this);
		}

		public override void BeginInteraction(FVRViveHand hand)
		{
			//IL_0002: 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)
			offset = Vector3.zero;
			((FVRInteractiveObject)this).BeginInteraction(hand);
			AudioSource component = ((Component)this).GetComponent<AudioSource>();
			if (component != null)
			{
				component.Play();
			}
			Trigger();
		}

		public override void UpdateInteraction(FVRViveHand hand)
		{
			//IL_0015: 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_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: 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)
			((FVRInteractiveObject)this).UpdateInteraction(hand);
			Vector3 val = Root.InverseTransformPoint(((HandInput)(ref hand.Input)).Pos + offset);
			float num = Mathf.Atan2(val.y, val.x) * 57.29578f;
			num = Mathf.Clamp(num, MinRot, MaxRot);
			((Component)Hinge).transform.localEulerAngles = new Vector3(0f, 0f, num);
			if (Networking.IsConnected())
			{
				List<byte> data = BitConverter.GetBytes(num).ToList();
				Networking.SendTriggerDataUDP(this, data);
			}
		}

		public void LootReset()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			((Component)Hinge).transform.localEulerAngles = new Vector3(0f, 0f, startAngle);
		}

		private void OnDrawGizmos()
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: 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_009c: 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_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)Root == (Object)null))
			{
				Gizmos.color = new Color(0f, 0.6f, 0f, 0.5f);
				Gizmos.DrawLine(((Component)Root).transform.position, ((Component)Root).transform.position + new Vector3(0f, ((Component)Root).transform.forward.y * Mathf.Sin(MinRot), ((Component)Root).transform.forward.z * Mathf.Cos(MinRot)) * 0.25f);
				Gizmos.DrawLine(((Component)Root).transform.position, ((Component)Root).transform.position + new Vector3(0f, ((Component)Root).transform.forward.y * Mathf.Sin(MaxRot), ((Component)Root).transform.forward.z * Mathf.Cos(MaxRot)) * 0.25f);
			}
		}

		public void OnDistantInteract(FVRViveHand hand)
		{
			//IL_0008: 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_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)
			offset = ((RaycastHit)(ref hand.m_grabHit)).point - ((HandInput)(ref hand.Input)).Pos;
		}

		public void ReceiveTriggerData(List<byte> data)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			float num = BitConverter.ToSingle(data.ToArray(), 0);
			((Component)Hinge).transform.localEulerAngles = new Vector3(0f, 0f, num);
		}
	}
	public class LootDamageTrigger : MonoBehaviour, IFVRDamageable, ILootTrigger
	{
		public GameObject LootObjectOwner;

		public DamageClass triggerDamageType = (DamageClass)3;

		public float triggerDamageSize = 10f;

		public event ILootTrigger.OnTriggeredDelegate OnTriggered;

		public void Awake()
		{
			LootObject.HookTrigger(LootObjectOwner, (MonoBehaviour)(object)this);
		}

		void IFVRDamageable.Damage(Damage dam)
		{
			//IL_0002: 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 (dam.Class == triggerDamageType)
			{
				AudioSource component = ((Component)this).GetComponent<AudioSource>();
				if (component != null)
				{
					component.Play();
				}
				Trigger();
			}
		}

		public void Trigger()
		{
			this.OnTriggered?.Invoke(this);
		}

		public void LootReset()
		{
		}
	}
	public class LootPhysicsTrigger : FVRPhysicalObject, ILootTrigger
	{
		[Header("Loot Trigger")]
		public GameObject LootObjectOwner;

		private Vector3 startingPosition;

		private Quaternion startingRotation;

		private Vector3 startingScale;

		public event ILootTrigger.OnTriggeredDelegate OnTriggered;

		public override void Awake()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			startingPosition = ((Component)this).transform.localPosition;
			startingRotation = ((Component)this).transform.localRotation;
			startingScale = ((Component)this).transform.localScale;
			LootObject.HookTrigger(LootObjectOwner, (MonoBehaviour)(object)this);
		}

		public override void BeginInteraction(FVRViveHand hand)
		{
			((FVRPhysicalObject)this).BeginInteraction(hand);
			Trigger();
		}

		public void Trigger()
		{
			this.OnTriggered?.Invoke(this);
		}

		public void LootReset()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			((Component)this).transform.position = startingPosition;
			((Component)this).transform.rotation = startingRotation;
			((Component)this).transform.localScale = startingScale;
		}
	}
	public class LootProximityTrigger : MonoBehaviour, ILootTrigger
	{
		public GameObject LootObjectOwner;

		[Header("Instance Settings")]
		public bool UseInstanceSettings = false;

		public float TriggerDistance = 250f;

		private float triggerDistance;

		public event ILootTrigger.OnTriggeredDelegate OnTriggered;

		public void Awake()
		{
			LootObject.HookTrigger(LootObjectOwner, (MonoBehaviour)(object)this);
			if (UseInstanceSettings)
			{
				triggerDistance = TriggerDistance;
			}
			else
			{
				triggerDistance = Lootations.ProximitySpawnDistance.Value;
			}
		}

		public void Trigger()
		{
			this.OnTriggered?.Invoke(this);
		}

		public void LootReset()
		{
		}

		public void Update()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			if (Utilities.PlayerWithinDistance(((Component)this).transform.position, triggerDistance))
			{
				Trigger();
			}
		}
	}
	public class LootSlideTrigger : FVRInteractiveObject, ILootTrigger, IDistantManipulable, ITriggerDataReceiver
	{
		public GameObject LootObjectOwner;

		public GameObject Root;

		public GameObject Hinge;

		public float MaxOffset = 0.25f;

		private Vector3 inputOffset = Vector3.zero;

		public event ILootTrigger.OnTriggeredDelegate OnTriggered;

		public override void Awake()
		{
			if ((Object)(object)Root == (Object)null || (Object)(object)Hinge == (Object)null)
			{
				Lootations.Logger.LogError((object)"SlideTrigger doesn't have a root or hinge, this is misconfigured!");
				((Component)this).gameObject.SetActive(false);
			}
			else
			{
				LootObject.HookTrigger(LootObjectOwner, (MonoBehaviour)(object)this);
			}
		}

		public override void BeginInteraction(FVRViveHand hand)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			((FVRInteractiveObject)this).BeginInteraction(hand);
			inputOffset = Vector3.zero;
			LootObject component = LootObjectOwner.GetComponent<LootObject>();
			Trigger();
			component.EnsureOwnerOfSpawnedItems();
		}

		public void Trigger()
		{
			this.OnTriggered?.Invoke(this);
		}

		public override void UpdateInteraction(FVRViveHand hand)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			((FVRInteractiveObject)this).UpdateInteraction(hand);
			Vector3 val = Root.transform.InverseTransformPoint(((HandInput)(ref hand.Input)).Pos + inputOffset);
			float num = Mathf.Clamp(val.z, 0f, MaxOffset);
			Hinge.transform.localPosition = new Vector3(0f, 0f, num);
			if (Networking.IsConnected())
			{
				Networking.SendTriggerDataUDP(this, BitConverter.GetBytes(num).ToList());
			}
		}

		public void LootReset()
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			Hinge.transform.localPosition = new Vector3(0f, 0f, 0f);
		}

		private void OnDrawGizmos()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: 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_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)
			Gizmos.color = new Color(0f, 0.6f, 0f, 0.5f);
			Gizmos.DrawLine(Root.transform.position, Root.transform.position + Root.transform.forward * MaxOffset);
		}

		public void OnDistantInteract(FVRViveHand hand)
		{
			//IL_0010: 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_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			((FVRInteractiveObject)this).BeginInteraction(hand);
			inputOffset = ((RaycastHit)(ref hand.m_grabHit)).point - ((HandInput)(ref hand.Input)).Pos;
		}

		public void ReceiveTriggerData(List<byte> data)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			float num = BitConverter.ToSingle(data.ToArray(), 0);
			Hinge.transform.localPosition = new Vector3(0f, 0f, num);
		}
	}
	internal static class Utilities
	{
		private static readonly float NAVMESH_QUERY_RANGE = 30f;

		public static LootSpawnPoint[] GameObjectsToPoints(GameObject[] gameObjects)
		{
			if (gameObjects.Length == 0)
			{
				return new LootSpawnPoint[0];
			}
			LootSpawnPoint[] array = new LootSpawnPoint[gameObjects.Length];
			for (int i = 0; i < gameObjects.Length; i++)
			{
				GameObject val = gameObjects[i];
				LootSpawnPoint component = val.GetComponent<LootSpawnPoint>();
				if ((Object)(object)component == (Object)null)
				{
					Lootations.Logger.LogError((object)"Object has loot spawn point set without its component");
				}
				else
				{
					array[i] = component;
				}
			}
			return array;
		}

		public static bool FindPointOnNavmesh(Vector3 centre, out Vector3 result)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			NavMeshHit val = default(NavMeshHit);
			if (NavMesh.SamplePosition(centre, ref val, NAVMESH_QUERY_RANGE, -1))
			{
				result = ((NavMeshHit)(ref val)).position;
				return true;
			}
			result = Vector3.zero;
			return false;
		}

		public static bool SampleNavMesh(Vector3 centre, float range, out Vector3 result)
		{
			//IL_0006: 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_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//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_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			NavMeshHit val2 = default(NavMeshHit);
			for (int i = 0; i < 30; i++)
			{
				Vector3 val = centre + Random.insideUnitSphere * range;
				if (NavMesh.SamplePosition(val, ref val2, 2f, -1))
				{
					result = ((NavMeshHit)(ref val2)).position;
					return true;
				}
			}
			result = Vector3.zero;
			return false;
		}

		public static string GetRandomInStringArray(string[] arr)
		{
			if (arr.Length == 0)
			{
				return "";
			}
			return arr[Random.Range(0, arr.Length + 1)];
		}

		public static Vector3 GetPlayerPosition()
		{
			//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_0018: Unknown result type (might be due to invalid IL or missing references)
			return ((Component)GM.CurrentPlayerBody.Head).transform.position;
		}

		public static bool PositionsWithinDistance(Vector3 a, Vector3 b, float distance)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = b - a;
			return ((Vector3)(ref val)).sqrMagnitude < distance * distance;
		}

		public static PlayerData GetPlayer(int i)
		{
			return PlayerData.GetPlayer(i);
		}

		public static bool PlayerWithinDistance(Vector3 a, float distance)
		{
			//IL_0044: 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)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			if (Networking.IsHost())
			{
				int[] playerIds = Networking.GetPlayerIds();
				int[] array = playerIds;
				foreach (int id in array)
				{
					if (PositionsWithinDistance(Networking.GetPlayerPosition(id), a, distance))
					{
						return true;
					}
				}
			}
			return PositionsWithinDistance(GetPlayerPosition(), a, distance);
		}
	}
}