Decompiled source of GunGame v1.0.1

GunGame.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security;
using System.Security.Permissions;
using Atlas;
using BepInEx;
using BepInEx.Logging;
using FistVR;
using GunGame.Scripts;
using GunGame.Scripts.Options;
using GunGame.Scripts.Weapons;
using HarmonyLib;
using Sodalite.Api;
using Technie.PhysicsCreator.QHull;
using UnityEditor;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: Debuggable(DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
public class CustomDebug : MonoBehaviourSingleton<CustomDebug>
{
	public Text DebugWeaponText;

	public Text DebugAmmoText;
}
namespace GunGame.Scripts
{
	public class CustomSosigSpawner : MonoBehaviour
	{
		public SosigOrder SpawnState;

		public int IFF;

		public SpawnedSosigInfo Spawn(SosigEnemyID SosigType)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_0010: 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_004c: 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_0071: 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_0089: 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)
			SpawnOptions val = new SpawnOptions();
			val.SpawnActivated = true;
			val.SpawnState = SpawnState;
			val.IFF = IFF;
			val.SpawnWithFullAmmo = true;
			val.EquipmentMode = (EquipmentSlots)7;
			val.SosigTargetPosition = ((Component)this).transform.position;
			val.SosigTargetRotation = ((Component)this).transform.eulerAngles;
			SpawnOptions val2 = val;
			SosigEnemyTemplate val3 = ManagerSingleton<IM>.Instance.odicSosigObjsByID[SosigType];
			Sosig spawnedSosig = SosigAPI.Spawn(val3, val2, ((Component)this).transform.position, ((Component)this).transform.rotation);
			SpawnedSosigInfo result = default(SpawnedSosigInfo);
			result.SosigType = SosigType;
			result.SpawnedSosig = spawnedSosig;
			return result;
		}

		private void OnDrawGizmos()
		{
			//IL_0015: 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_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: 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)
			Gizmos.color = new Color(0.8f, 0.2f, 0.2f, 0.5f);
			Gizmos.DrawSphere(((Component)this).transform.position, 0.1f);
			Gizmos.DrawLine(((Component)this).transform.position, ((Component)this).transform.position + ((Component)this).transform.forward * 0.25f);
		}
	}
	public struct SpawnedSosigInfo
	{
		public SosigEnemyID SosigType;

		public Sosig SpawnedSosig;
	}
	public class EndArea : MonoBehaviour
	{
		public Text TimeText;

		public Text KillsText;

		public Text DeathsText;

		public Transform EndPos;

		public void EndGame()
		{
			//IL_000c: 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_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			GM.CurrentMovementManager.TeleportToPoint(EndPos.position, true, ((Component)this).transform.position + ((Component)this).transform.forward);
			foreach (Transform playerSpawner in MonoBehaviourSingleton<GameManager>.Instance.PlayerSpawners)
			{
				((Component)playerSpawner).transform.position = EndPos.position;
			}
			KillsText.text = "Kills: " + MonoBehaviourSingleton<GameManager>.Instance.Kills;
			DeathsText.text = "Deaths: " + MonoBehaviourSingleton<GameManager>.Instance.Deaths;
			TimeSpan timeSpan = TimeSpan.FromSeconds(MonoBehaviourSingleton<GameManager>.Instance.GameTime);
			TimeText.text = "Time: " + timeSpan.Hours.ToString("00") + ":" + timeSpan.Minutes.ToString("00") + ":" + timeSpan.Seconds.ToString("00");
		}
	}
	public class GameManager : MonoBehaviourSingleton<GameManager>
	{
		[HideInInspector]
		public int Kills;

		[HideInInspector]
		public int Deaths;

		[HideInInspector]
		public bool GameEnded;

		public EndArea EndArea;

		public static Action BeforeGameStartedEvent;

		public static Action GameStartedEvent;

		public PlayerSpawner PlayerSpawner;

		public List<Transform> PlayerSpawners;

		private Progression _progression;

		private Harmony _harmony;

		private float _timer;

		public float GameTime => Time.time - _timer;

		public override void Awake()
		{
			base.Awake();
			_progression = ((Component)this).GetComponent<Progression>();
			_harmony = Harmony.CreateAndPatchAll(typeof(PlayerSpawner), (string)null);
			_harmony.PatchAll(typeof(SosigBehavior));
			_harmony.PatchAll(typeof(Progression));
		}

		public void StartGame()
		{
			GameEnded = false;
			if (BeforeGameStartedEvent != null)
			{
				BeforeGameStartedEvent();
			}
			_progression.SpawnAndEquip();
			PlayerSpawner.MovePlayerToRandomSpawn();
			if (GameStartedEvent != null)
			{
				GameStartedEvent();
			}
			_timer = Time.time;
		}

		public void RemovePausedTime(float timePaused)
		{
			_timer += timePaused;
		}

		public void EndGame()
		{
			EndArea.EndGame();
			GameEnded = true;
		}

		public void DebugAdvanceWeapon()
		{
			_progression.Promote();
		}

		public void DebugPreviousWeapon()
		{
			_progression.Demote();
		}

		public void DebugTeleport()
		{
			PlayerSpawner.MovePlayerToRandomSpawn();
		}

		public void DebugStart()
		{
			if (BeforeGameStartedEvent != null)
			{
				BeforeGameStartedEvent();
			}
			_progression.SpawnAndEquip();
			if (GameStartedEvent != null)
			{
				GameStartedEvent();
			}
			_timer = Time.time;
		}

		private void OnDestroy()
		{
			_harmony.UnpatchSelf();
		}
	}
}
public class GunsLeftUI : MonoBehaviour
{
	private Text _gunsLeftText;

	private void Awake()
	{
		_gunsLeftText = ((Component)this).GetComponent<Text>();
		Progression.WeaponChangedEvent = (Action)Delegate.Combine(Progression.WeaponChangedEvent, new Action(UpdateUI));
	}

	private void UpdateUI()
	{
		int num = Mathf.Min(GameSettings.CurrentPool.GetWeaponCount(), WeaponCountOption.WeaponCount);
		int num2 = MonoBehaviourSingleton<Progression>.Instance.CurrentWeaponId + 1;
		int num3 = num - num2;
		_gunsLeftText.text = "Guns left: " + num3;
	}

	private void OnDestroy()
	{
		Progression.WeaponChangedEvent = (Action)Delegate.Remove(Progression.WeaponChangedEvent, new Action(UpdateUI));
	}
}
namespace CustomScripts
{
	public class LeverWrapper : MonoBehaviour
	{
		public UnityEvent LeverToggleEvent;

		public UnityEvent LeverOnEvent;

		public UnityEvent LeverOffEvent;

		public UnityEvent LeverHoldStartEvent;

		public UnityEvent LeverHoldEndEvent;

		private TrapLever _lever;

		private bool _isOn;

		private bool _isHeld;

		private void Awake()
		{
			_lever = ((Component)this).GetComponentInChildren<TrapLever>();
			_lever.MessageTargets.Add(((Component)this).gameObject);
		}

		private void Update()
		{
			if (!_isHeld && ((FVRInteractiveObject)_lever).IsHeld)
			{
				OnHoldStart();
			}
			else if (_isHeld && !((FVRInteractiveObject)_lever).IsHeld)
			{
				OnHoldEnd();
			}
		}

		private void OnHoldStart()
		{
			_isHeld = true;
			if (LeverHoldStartEvent != null)
			{
				LeverHoldStartEvent.Invoke();
			}
		}

		private void OnHoldEnd()
		{
			_isHeld = false;
			if (LeverHoldEndEvent != null)
			{
				LeverHoldEndEvent.Invoke();
			}
		}

		public void ON()
		{
			if (!_isOn)
			{
				_isOn = true;
				if (LeverToggleEvent != null)
				{
					LeverToggleEvent.Invoke();
				}
				if (LeverOnEvent != null)
				{
					LeverOnEvent.Invoke();
				}
			}
		}

		public void OFF()
		{
			if (_isOn)
			{
				_isOn = false;
				if (LeverToggleEvent != null)
				{
					LeverToggleEvent.Invoke();
				}
				if (LeverOffEvent != null)
				{
					LeverOffEvent.Invoke();
				}
			}
		}
	}
}
namespace GunGame.Scripts
{
	public class MonoBehaviourSingleton<T> : MonoBehaviour where T : Component
	{
		public static T Instance { get; private set; }

		public virtual void Awake()
		{
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = (T)(object)((this is T) ? this : null);
			}
			else
			{
				Object.Destroy((Object)(object)((Component)this).gameObject);
			}
		}
	}
}
namespace GunGame.Scripts.Options
{
	public class GameSettings : MonoBehaviourSingleton<GameSettings>
	{
		public static Action SettingsChanged;

		public static Action WeaponPoolChanged;

		public static bool DisabledAutoLoading;

		public static bool AlwaysChamberRounds;

		public static bool HealOnPromotion;

		public static bool AlwaysResetSosigs;

		[SerializeField]
		private Image DisabledAutoLoadingImage;

		[SerializeField]
		private Image AlwaysChamberRoundsImage;

		[SerializeField]
		private Image HealOnPromotionImage;

		[SerializeField]
		private Text MaxSosigCountText;

		public static int MaxSosigCount;

		public static WeaponPoolInterface CurrentPool { get; private set; }

		private void Start()
		{
			DisabledAutoLoading = false;
			AlwaysChamberRounds = false;
			HealOnPromotion = false;
			AlwaysResetSosigs = false;
			ResetMaxSosigCount();
		}

		public void IncreaseMaxSosigCount()
		{
			MaxSosigCount++;
			MaxSosigCountText.text = MaxSosigCount.ToString();
			if (SettingsChanged != null)
			{
				SettingsChanged();
			}
		}

		public void DecreaseMaxSosigCount()
		{
			MaxSosigCount--;
			if (MaxSosigCount < 1)
			{
				MaxSosigCount = 1;
			}
			MaxSosigCountText.text = MaxSosigCount.ToString();
			if (SettingsChanged != null)
			{
				SettingsChanged();
			}
		}

		public void ResetMaxSosigCount()
		{
			MaxSosigCount = MonoBehaviourSingleton<SosigBehavior>.Instance.MaxSosigCount;
			MaxSosigCountText.text = MaxSosigCount.ToString();
			if (SettingsChanged != null)
			{
				SettingsChanged();
			}
		}

		public void ToggleAutoLoading()
		{
			DisabledAutoLoading = !DisabledAutoLoading;
			((Behaviour)DisabledAutoLoadingImage).enabled = DisabledAutoLoading;
			if (SettingsChanged != null)
			{
				SettingsChanged();
			}
		}

		public void ToggleAlwaysChamberRounds()
		{
			AlwaysChamberRounds = !AlwaysChamberRounds;
			((Behaviour)AlwaysChamberRoundsImage).enabled = AlwaysChamberRounds;
			if (SettingsChanged != null)
			{
				SettingsChanged();
			}
		}

		public void ToggleHealOnPromotion()
		{
			HealOnPromotion = !HealOnPromotion;
			((Behaviour)HealOnPromotionImage).enabled = HealOnPromotion;
			if (SettingsChanged != null)
			{
				SettingsChanged();
			}
		}

		public static void ChangeCurrentPool(WeaponPoolInterface newPool)
		{
			CurrentPool = newPool;
			CurrentPool.Initialize();
			MonoBehaviourSingleton<Progression>.Instance.ProgressionType = CurrentPool.GetProgressionType();
			if (WeaponPoolChanged != null)
			{
				WeaponPoolChanged();
			}
			if (SettingsChanged != null)
			{
				SettingsChanged();
			}
		}
	}
	public class KillsPerWeaponOption : MonoBehaviour
	{
		public Action OptionChanged;

		public int DefaultCount;

		public static int KillsPerWeaponCount;

		public static string Description;

		[SerializeField]
		private Text _counterText;

		[SerializeField]
		private Text _descriptionText;

		private void Awake()
		{
			OptionChanged = (Action)Delegate.Combine(OptionChanged, new Action(UpdateUI));
			GameSettings.WeaponPoolChanged = (Action)Delegate.Combine(GameSettings.WeaponPoolChanged, new Action(ResetClicked));
		}

		private void Start()
		{
			ResetClicked();
		}

		public void ArrowLeftClicked()
		{
			KillsPerWeaponCount--;
			KillProgressionType progressionType = MonoBehaviourSingleton<Progression>.Instance.ProgressionType;
			if (KillsPerWeaponCount <= 1 && progressionType != KillProgressionType.Tiers)
			{
				KillsPerWeaponCount = 1;
			}
			else if (KillsPerWeaponCount <= 0)
			{
				KillsPerWeaponCount = 0;
			}
			if (OptionChanged != null)
			{
				OptionChanged();
			}
		}

		public void ArrowRightClicked()
		{
			KillsPerWeaponCount++;
			if (OptionChanged != null)
			{
				OptionChanged();
			}
		}

		public void ResetClicked()
		{
			UIData progressionTypeUIDefaults = MonoBehaviourSingleton<Progression>.Instance.GetProgressionTypeUIDefaults();
			KillsPerWeaponCount = progressionTypeUIDefaults.Value;
			Description = progressionTypeUIDefaults.Text;
			if (OptionChanged != null)
			{
				OptionChanged();
			}
		}

		private void UpdateUI()
		{
			_counterText.text = KillsPerWeaponCount.ToString();
			_descriptionText.text = Description;
		}

		private void OnDestroy()
		{
			OptionChanged = (Action)Delegate.Remove(OptionChanged, new Action(UpdateUI));
			GameSettings.WeaponPoolChanged = (Action)Delegate.Remove(GameSettings.WeaponPoolChanged, new Action(ResetClicked));
		}
	}
	public class LeftHandOption : MonoBehaviour
	{
		public Action OptionChanged;

		public static bool LeftHandModeEnabled;

		[SerializeField]
		private Image EnabledImage;

		private void Awake()
		{
			OptionChanged = (Action)Delegate.Combine(OptionChanged, new Action(UpdateUI));
			LeftHandModeEnabled = false;
			((Behaviour)EnabledImage).enabled = false;
		}

		public void ToggleClicked()
		{
			LeftHandModeEnabled = !LeftHandModeEnabled;
			if (OptionChanged != null)
			{
				OptionChanged();
			}
		}

		private void UpdateUI()
		{
			((Behaviour)EnabledImage).enabled = LeftHandModeEnabled;
		}

		private void OnDestroy()
		{
			OptionChanged = (Action)Delegate.Remove(OptionChanged, new Action(UpdateUI));
		}
	}
	public class MusicToggleOption : MonoBehaviour
	{
		public Action OptionChanged;

		public static bool MusicEnabled;

		public AudioSource MusicAudioSource;

		public bool MusicEnabledAtStart = false;

		[SerializeField]
		private Image EnabledImage;

		private void Awake()
		{
			OptionChanged = (Action)Delegate.Combine(OptionChanged, new Action(OnToggleMusic));
			MusicEnabled = MusicEnabledAtStart;
			((Behaviour)EnabledImage).enabled = MusicEnabled;
			OnToggleMusic();
		}

		public void ToggleClicked()
		{
			MusicEnabled = !MusicEnabled;
			if (OptionChanged != null)
			{
				OptionChanged();
			}
		}

		private void OnToggleMusic()
		{
			if (MusicEnabled)
			{
				MusicAudioSource.Play();
			}
			else
			{
				MusicAudioSource.Stop();
			}
			((Behaviour)EnabledImage).enabled = MusicEnabled;
		}

		private void OnDestroy()
		{
			OptionChanged = (Action)Delegate.Remove(OptionChanged, new Action(OnToggleMusic));
		}
	}
	public class QuickbeltOption : MonoBehaviour
	{
		public static FVRQuickBeltSlot AmmoQuickbeltSlot;

		public static FVRQuickBeltSlot ExtraQuickbeltSlot;

		private FVRPhysicalObject MagObject;

		private FVRPhysicalObject ExtraObject;

		public Transform MagSpawnPos;

		private string _magName = "MagazineStanag5rnd";

		private string _extraName = "ReflexGamepointRDS";

		private void Awake()
		{
			GameManager.BeforeGameStartedEvent = (Action)Delegate.Combine(GameManager.BeforeGameStartedEvent, new Action(OnGameStart));
		}

		private IEnumerator Start()
		{
			yield return (object)new WaitForSeconds(0.2f);
			SpawnMag();
			SpawnExtra();
		}

		private void OnGameStart()
		{
			AmmoQuickbeltSlot = GM.CurrentPlayerBody.QBSlots_Internal[0];
			ExtraQuickbeltSlot = GM.CurrentPlayerBody.QBSlots_Internal[1];
			if (Object.op_Implicit((Object)(object)MagObject.QuickbeltSlot))
			{
				Debug.Log((object)"Found mag slot item");
				AmmoQuickbeltSlot = MagObject.QuickbeltSlot;
			}
			else if ((Object)(object)ExtraObject.QuickbeltSlot == (Object)(object)GM.CurrentPlayerBody.QBSlots_Internal[0])
			{
				Debug.Log((object)"Default mag slot");
				AmmoQuickbeltSlot = GM.CurrentPlayerBody.QBSlots_Internal[1];
			}
			if (Object.op_Implicit((Object)(object)ExtraObject.QuickbeltSlot))
			{
				Debug.Log((object)"Found extra slot item");
				ExtraQuickbeltSlot = ExtraObject.QuickbeltSlot;
			}
			else if ((Object)(object)MagObject.QuickbeltSlot == (Object)(object)GM.CurrentPlayerBody.QBSlots_Internal[1])
			{
				Debug.Log((object)"Default extra slot");
				ExtraQuickbeltSlot = GM.CurrentPlayerBody.QBSlots_Internal[0];
			}
			if (Object.op_Implicit((Object)(object)AmmoQuickbeltSlot.CurObject))
			{
				AmmoQuickbeltSlot.CurObject.ClearQuickbeltState();
			}
			if (Object.op_Implicit((Object)(object)ExtraQuickbeltSlot.CurObject))
			{
				ExtraQuickbeltSlot.CurObject.ClearQuickbeltState();
			}
		}

		private void SpawnMag()
		{
			//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_0061: 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)
			FVRObject value = null;
			if (!IM.OD.TryGetValue(_magName, out value))
			{
				Debug.LogError((object)("No object found with id: " + _magName));
				return;
			}
			GameObject gameObject = ((AnvilAsset)value).GetGameObject();
			Vector3 position = ((Component)MagSpawnPos).transform.position;
			position.z -= 0.2f;
			GameObject val = Object.Instantiate<GameObject>(gameObject, position, ((Component)this).transform.rotation);
			val.SetActive(true);
			MagObject = val.GetComponent<FVRPhysicalObject>();
		}

		private void SpawnExtra()
		{
			//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_0061: 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)
			FVRObject value = null;
			if (!IM.OD.TryGetValue(_extraName, out value))
			{
				Debug.LogError((object)("No object found with id: " + _extraName));
				return;
			}
			GameObject gameObject = ((AnvilAsset)value).GetGameObject();
			Vector3 position = ((Component)MagSpawnPos).transform.position;
			position.z += 0.2f;
			GameObject val = Object.Instantiate<GameObject>(gameObject, position, ((Component)this).transform.rotation);
			val.SetActive(true);
			ExtraObject = val.GetComponent<FVRPhysicalObject>();
		}

		private void OnDestroy()
		{
			GameManager.BeforeGameStartedEvent = (Action)Delegate.Remove(GameManager.BeforeGameStartedEvent, new Action(OnGameStart));
		}
	}
	public class SelectedPoolUI : MonoBehaviour
	{
		public Text TitleText;

		public Text DescriptionText;

		private void Awake()
		{
			GameSettings.SettingsChanged = (Action)Delegate.Combine(GameSettings.SettingsChanged, new Action(OnSettingsChanged));
		}

		private void OnSettingsChanged()
		{
			TitleText.text = GameSettings.CurrentPool.GetName();
			DescriptionText.text = GameSettings.CurrentPool.GetDescription();
		}

		private void OnDestroy()
		{
			GameSettings.SettingsChanged = (Action)Delegate.Remove(GameSettings.SettingsChanged, new Action(OnSettingsChanged));
		}
	}
	public class StartingHealthOption : MonoBehaviour
	{
		public Action OptionChanged;

		public int[] PossibleHealth;

		private int _optionIndex = 1;

		public static int CurrentHealth = 1000;

		[SerializeField]
		private Text _healthText;

		private void Awake()
		{
			PossibleHealth = new int[5] { 100, 1000, 2000, 5000, 10000 };
			OptionChanged = (Action)Delegate.Combine(OptionChanged, new Action(UpdateUI));
			OptionChanged = (Action)Delegate.Combine(OptionChanged, new Action(UpdateHealth));
		}

		private IEnumerator Start()
		{
			yield return (object)new WaitForSeconds(0.1f);
			ResetClicked();
		}

		public void ArrowLeftClicked()
		{
			_optionIndex--;
			if (_optionIndex < 0)
			{
				_optionIndex = 0;
			}
			CurrentHealth = PossibleHealth[_optionIndex];
			if (OptionChanged != null)
			{
				OptionChanged();
			}
		}

		public void ArrowRightClicked()
		{
			_optionIndex++;
			if (_optionIndex >= PossibleHealth.Length)
			{
				_optionIndex = PossibleHealth.Length - 1;
			}
			CurrentHealth = PossibleHealth[_optionIndex];
			if (OptionChanged != null)
			{
				OptionChanged();
			}
		}

		public void ResetClicked()
		{
			_optionIndex = 1;
			CurrentHealth = PossibleHealth[_optionIndex];
			if (OptionChanged != null)
			{
				OptionChanged();
			}
		}

		private void UpdateHealth()
		{
			GM.CurrentPlayerBody.SetHealthThreshold((float)CurrentHealth);
			GM.CurrentPlayerBody.ResetHealth();
		}

		private void UpdateUI()
		{
			_healthText.text = CurrentHealth.ToString();
		}

		private void OnDestroy()
		{
			OptionChanged = (Action)Delegate.Remove(OptionChanged, new Action(UpdateUI));
			OptionChanged = (Action)Delegate.Remove(OptionChanged, new Action(UpdateHealth));
		}
	}
	public class WeaponCountOption : MonoBehaviour
	{
		public Action OptionChanged;

		public static int WeaponCount;

		[SerializeField]
		private Text _counterText;

		private void Awake()
		{
			OptionChanged = (Action)Delegate.Combine(OptionChanged, new Action(UpdateUI));
			GameSettings.WeaponPoolChanged = (Action)Delegate.Combine(GameSettings.WeaponPoolChanged, new Action(ResetClicked));
		}

		public void ArrowLeftClicked()
		{
			WeaponCount--;
			if (WeaponCount <= 1)
			{
				WeaponCount = 1;
			}
			if (OptionChanged != null)
			{
				OptionChanged();
			}
		}

		public void ArrowRightClicked()
		{
			WeaponCount++;
			if (WeaponCount > GameSettings.CurrentPool.GetWeaponCount())
			{
				WeaponCount = GameSettings.CurrentPool.GetWeaponCount();
			}
			if (OptionChanged != null)
			{
				OptionChanged();
			}
		}

		public void ArrowRight10Clicked()
		{
			WeaponCount += 20;
			if (WeaponCount > GameSettings.CurrentPool.GetWeaponCount())
			{
				WeaponCount = GameSettings.CurrentPool.GetWeaponCount();
			}
			if (OptionChanged != null)
			{
				OptionChanged();
			}
		}

		public void ArrowLeft10Clicked()
		{
			WeaponCount -= 20;
			if (WeaponCount <= 1)
			{
				WeaponCount = 1;
			}
			if (OptionChanged != null)
			{
				OptionChanged();
			}
		}

		public void ResetClicked()
		{
			WeaponCount = GameSettings.CurrentPool.GetWeaponCount();
			if (OptionChanged != null)
			{
				OptionChanged();
			}
		}

		private void UpdateUI()
		{
			_counterText.text = WeaponCount.ToString();
		}

		private void OnDestroy()
		{
			OptionChanged = (Action)Delegate.Remove(OptionChanged, new Action(UpdateUI));
			GameSettings.WeaponPoolChanged = (Action)Delegate.Remove(GameSettings.WeaponPoolChanged, new Action(ResetClicked));
		}
	}
}
public class Pause : MonoBehaviour
{
	[SerializeField]
	private Transform PauseWaypoint;

	[SerializeField]
	private Transform UnPauseWaypoint;

	[SerializeField]
	private Text TimeText;

	[SerializeField]
	private Text KillsText;

	[SerializeField]
	private Text DeathsText;

	private float _pauseTimer;

	public void PauseTheGame()
	{
		//IL_000c: 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_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		GM.CurrentMovementManager.TeleportToPoint(PauseWaypoint.position, true, ((Component)this).transform.position + ((Component)this).transform.forward);
		KillsText.text = "Kills: " + MonoBehaviourSingleton<GameManager>.Instance.Kills;
		DeathsText.text = "Deaths: " + MonoBehaviourSingleton<GameManager>.Instance.Deaths;
		TimeSpan timeSpan = TimeSpan.FromSeconds(MonoBehaviourSingleton<GameManager>.Instance.GameTime);
		TimeText.text = "Time: " + timeSpan.Hours.ToString("00") + ":" + timeSpan.Minutes.ToString("00") + ":" + timeSpan.Seconds.ToString("00");
		_pauseTimer = Time.time;
	}

	public void UnpauseTheGame()
	{
		//IL_000c: 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_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		GM.CurrentMovementManager.TeleportToPoint(UnPauseWaypoint.position, true, ((Component)this).transform.position + ((Component)this).transform.forward);
		float timePaused = Time.time - _pauseTimer;
		MonoBehaviourSingleton<GameManager>.Instance.RemovePausedTime(timePaused);
	}
}
public class PlayerFollower : MonoBehaviour
{
	private bool _isActive;

	private Transform _transform;

	private Transform _playerHeadTransform;

	private void Awake()
	{
		_transform = ((Component)this).GetComponent<Transform>();
	}

	private IEnumerator Start()
	{
		yield return (object)new WaitForSeconds(0.1f);
		_playerHeadTransform = ((Component)GM.CurrentPlayerBody.Head).transform;
		_isActive = true;
	}

	private void Update()
	{
		//IL_001d: 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_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_003a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: 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_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_0066: 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)
		if (_isActive)
		{
			_transform.position = _playerHeadTransform.position;
			Quaternion rotation = _playerHeadTransform.rotation;
			float y = ((Quaternion)(ref rotation)).eulerAngles.y;
			Quaternion rotation2 = _transform.rotation;
			Vector3 eulerAngles = ((Quaternion)(ref rotation2)).eulerAngles;
			eulerAngles.y = y;
			_transform.rotation = Quaternion.Euler(eulerAngles);
		}
	}
}
namespace GunGame.Scripts
{
	public class PlayerSpawner : MonoBehaviourSingleton<PlayerSpawner>
	{
		public static Action BeingRevivedEvent;

		public Progression Progression;

		private IEnumerator Start()
		{
			yield return null;
			GM.CurrentSceneSettings.DeathResetPoint = ((Component)this).transform;
			GM.CurrentMovementManager.TeleportToPoint(((Component)this).transform.position, true, ((Component)this).transform.position + ((Component)this).transform.forward);
		}

		private IEnumerator DelayedRespawn()
		{
			MonoBehaviourSingleton<GameManager>.Instance.Deaths++;
			MonoBehaviourSingleton<Progression>.Instance.KillsWithCurrentWeapon = 0;
			MonoBehaviourSingleton<Progression>.Instance.CurrentTier = 0;
			yield return (object)new WaitForSeconds(3f);
			if (MonoBehaviourSingleton<Progression>.Instance.ProgressionType == KillProgressionType.Tiers || GameSettings.AlwaysResetSosigs)
			{
				((MonoBehaviour)this).StartCoroutine(MonoBehaviourSingleton<SosigBehavior>.Instance.ClearSosigs());
			}
			MonoBehaviourSingleton<Progression>.Instance.Demote();
			GM.CurrentPlayerBody.ActivatePower((PowerupType)3, (PowerUpIntensity)0, (PowerUpDuration)2, false, false, -1f);
			GM.CurrentPlayerBody.HealPercent(100f);
			MovePlayerToRandomSpawn();
			if (BeingRevivedEvent != null)
			{
				BeingRevivedEvent();
			}
		}

		[HarmonyPatch(typeof(GM), "KillPlayer", new Type[] { typeof(bool) })]
		[HarmonyPostfix]
		private static void Postfix(bool KilledSelf)
		{
			MonoBehaviourSingleton<PlayerSpawner>.Instance.OnPlayerDeath();
		}

		private void OnPlayerDeath()
		{
			((MonoBehaviour)this).StartCoroutine(DelayedRespawn());
		}

		public void MovePlayerToRandomSpawn()
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: 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_005e: Unknown result type (might be due to invalid IL or missing references)
			int index = Random.Range(0, MonoBehaviourSingleton<GameManager>.Instance.PlayerSpawners.Count);
			((Component)this).transform.position = MonoBehaviourSingleton<GameManager>.Instance.PlayerSpawners[index].position;
			GM.CurrentMovementManager.TeleportToPoint(((Component)this).transform.position, true, ((Component)this).transform.position + ((Component)this).transform.forward);
		}

		private void OnDrawGizmos()
		{
			//IL_0015: 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_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: 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)
			Gizmos.color = new Color(0.2f, 0.8f, 0.2f, 0.5f);
			Gizmos.DrawSphere(((Component)this).transform.position, 0.1f);
			Gizmos.DrawLine(((Component)this).transform.position, ((Component)this).transform.position + ((Component)this).transform.forward * 0.25f);
		}
	}
	public class Progression : MonoBehaviourSingleton<Progression>
	{
		public static Action SosigDespawnedEvent;

		public static Action WeaponChangedEvent;

		public AudioSource EquipSound;

		[HideInInspector]
		public int KillsWithCurrentWeapon = 0;

		public static List<int> DeadSosigs = new List<int>();

		private List<GameObject> _currentEquipment = new List<GameObject>();

		private WeaponBuffer _weaponBuffer;

		[HideInInspector]
		public KillProgressionType ProgressionType = KillProgressionType.Count;

		[HideInInspector]
		private List<EnemyData> Enemies = new List<EnemyData>();

		[HideInInspector]
		public int CurrentTier = 0;

		[HideInInspector]
		private int ProbabilityTotal = 0;

		[HideInInspector]
		private int InverseProbabilityTotal = 0;

		public int CurrentWeaponId { get; private set; }

		public override void Awake()
		{
			base.Awake();
			_weaponBuffer = ((Component)this).GetComponent<WeaponBuffer>();
		}

		public void Demote()
		{
			if (!MonoBehaviourSingleton<GameManager>.Instance.GameEnded)
			{
				CurrentWeaponId--;
				if (CurrentWeaponId < 0)
				{
					CurrentWeaponId = 0;
				}
				SpawnAndEquip(demotion: true);
			}
		}

		public void Promote()
		{
			if (!MonoBehaviourSingleton<GameManager>.Instance.GameEnded)
			{
				if (GameSettings.HealOnPromotion)
				{
					GM.CurrentPlayerBody.HealPercent(100f);
				}
				CurrentWeaponId++;
				KillsWithCurrentWeapon = 0;
				if (CurrentWeaponId >= GameSettings.CurrentPool.GetWeaponCount() || CurrentWeaponId >= WeaponCountOption.WeaponCount)
				{
					CurrentWeaponId = GameSettings.CurrentPool.GetWeaponCount() - 1;
					MonoBehaviourSingleton<GameManager>.Instance.EndGame();
				}
				else
				{
					EquipSound.Play();
					SpawnAndEquip();
				}
			}
		}

		public void SpawnAndEquip(bool demotion = false)
		{
			DestroyOldEq();
			if (((Component)MonoBehaviourSingleton<CustomDebug>.Instance.DebugWeaponText).gameObject.activeInHierarchy)
			{
				MonoBehaviourSingleton<CustomDebug>.Instance.DebugWeaponText.text = "Weapon " + GameSettings.CurrentPool.GetWeapon(CurrentWeaponId).GunName;
				MonoBehaviourSingleton<CustomDebug>.Instance.DebugAmmoText.text = "Ammo " + GameSettings.CurrentPool.GetWeapon(CurrentWeaponId).MagName;
			}
			FVRPhysicalObject fromBuffer = _weaponBuffer.GetFromBuffer(ObjectType.Gun, CurrentWeaponId, demotion);
			if ((Object)(object)fromBuffer == (Object)null)
			{
				Debug.LogError((object)"Trying to equip null gun! Probably the ObjectId is invalid. Attempting a fix by promoting the player");
				Promote();
				return;
			}
			_currentEquipment.Add(((Component)fromBuffer).gameObject);
			if (Utility.IsNullOrWhiteSpace(GameSettings.CurrentPool.GetWeapon(CurrentWeaponId).MagName))
			{
				EquipWeapon(fromBuffer);
				_weaponBuffer.DestroyMagBuffer();
			}
			else
			{
				FVRPhysicalObject fromBuffer2 = _weaponBuffer.GetFromBuffer(ObjectType.MagazineToLoad, CurrentWeaponId, demotion);
				if ((Object)(object)fromBuffer2 == (Object)null)
				{
					Debug.LogError((object)"Trying to equip null magazine! Probably the ObjectId is invalid. Attempting a fix by promoting the player");
					Promote();
					return;
				}
				fromBuffer2.UsesGravity = false;
				fromBuffer2.RootRigidbody.isKinematic = true;
				FVRPhysicalObject fromBuffer3 = _weaponBuffer.GetFromBuffer(ObjectType.MagazineForQuickbelt, CurrentWeaponId, demotion);
				_currentEquipment.Add(((Component)fromBuffer2).gameObject);
				_currentEquipment.Add(((Component)fromBuffer3).gameObject);
				if (!GameSettings.DisabledAutoLoading)
				{
					LoadTheGun(fromBuffer, fromBuffer2);
				}
				EquipWeapon(fromBuffer);
				FixAmmoRotation();
				MoveMagazineToSlot(fromBuffer3);
			}
			if (!Utility.IsNullOrWhiteSpace(GameSettings.CurrentPool.GetWeapon(CurrentWeaponId).Extra))
			{
				FVRPhysicalObject fromBuffer4 = _weaponBuffer.GetFromBuffer(ObjectType.Extra, CurrentWeaponId, demotion);
				_currentEquipment.Add(((Component)fromBuffer4).gameObject);
				MoveExtraToSlot(fromBuffer4);
			}
			_weaponBuffer.ClearBuffer();
			_weaponBuffer.GenerateBuffer(CurrentWeaponId);
			if (WeaponChangedEvent != null)
			{
				WeaponChangedEvent();
			}
		}

		private void DestroyOldEq()
		{
			for (int i = 0; i < _currentEquipment.Count; i++)
			{
				if (Object.op_Implicit((Object)(object)_currentEquipment[i]) && Object.op_Implicit((Object)(object)_currentEquipment[i].GetComponent<FVRPhysicalObject>()))
				{
					((FVRInteractiveObject)_currentEquipment[i].GetComponent<FVRPhysicalObject>()).ForceBreakInteraction();
				}
				Object.Destroy((Object)(object)_currentEquipment[i]);
			}
			_currentEquipment.Clear();
		}

		private void MoveMagazineToSlot(FVRPhysicalObject magazine)
		{
			if (Object.op_Implicit((Object)(object)QuickbeltOption.AmmoQuickbeltSlot.CurObject))
			{
				QuickbeltOption.AmmoQuickbeltSlot.CurObject.ClearQuickbeltState();
			}
			magazine.ForceObjectIntoInventorySlot(QuickbeltOption.AmmoQuickbeltSlot);
			magazine.m_isSpawnLock = true;
		}

		private void MoveExtraToSlot(FVRPhysicalObject extra)
		{
			if (Object.op_Implicit((Object)(object)QuickbeltOption.ExtraQuickbeltSlot.CurObject))
			{
				QuickbeltOption.ExtraQuickbeltSlot.CurObject.ClearQuickbeltState();
			}
			extra.ForceObjectIntoInventorySlot(QuickbeltOption.ExtraQuickbeltSlot);
		}

		private void LoadTheGun(FVRPhysicalObject weapon, FVRPhysicalObject ammo)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Expected O, but got Unknown
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)((ammo is FVRFireArmMagazine) ? ammo : null) != (Object)null)
			{
				try
				{
					((FVRFireArmMagazine)ammo).Load((FVRFireArm)(object)((weapon is FVRFireArm) ? weapon : null));
				}
				catch (Exception)
				{
					Debug.LogWarning((object)("Weapon failed to load magazine for gun " + weapon.ObjectWrapper.DisplayName + " with magazine " + ammo.ObjectWrapper.DisplayName));
				}
			}
			else if (Object.op_Implicit((Object)(object)((Component)weapon).GetComponentInChildren<RevolverCylinder>()) && (Object)(object)((ammo is Speedloader) ? ammo : null) != (Object)null)
			{
				((Component)weapon).GetComponentInChildren<RevolverCylinder>().LoadFromSpeedLoader((Speedloader)ammo);
			}
			else if (GameSettings.AlwaysChamberRounds || ((Object)(object)((ammo is FVRFireArmMagazine) ? ammo : null) == (Object)null && (Object)(object)((Component)weapon).GetComponentInChildren<FVRFireArmMagazine>() == (Object)null && (Object)(object)((weapon is FVRFireArm) ? weapon : null) != (Object)null))
			{
				try
				{
					List<FVRFireArmChamber> chambers = ((Component)weapon).GetComponent<FVRFireArm>().GetChambers();
					foreach (FVRFireArmChamber item in chambers)
					{
						FVRFireArmRound component = ((Component)_weaponBuffer.SpawnImmediate(ObjectType.MagazineToLoad, GameSettings.CurrentPool.GetWeapon(CurrentWeaponId))).GetComponent<FVRFireArmRound>();
						item.SetRound(component, false);
					}
					BreakActionWeapon componentInChildren = ((Component)weapon).GetComponentInChildren<BreakActionWeapon>();
					if ((Object)(object)componentInChildren != (Object)null)
					{
						componentInChildren.CockAllHammers();
					}
				}
				catch (Exception)
				{
					Debug.LogWarning((object)("Error while trying to load gun chambers manually for a gun: " + ((Object)weapon).name + " and ammo: " + ((Object)ammo).name));
				}
			}
			FVRFireArmMagazine componentInChildren2 = ((Component)weapon).GetComponentInChildren<FVRFireArmMagazine>();
			if (Object.op_Implicit((Object)(object)componentInChildren2))
			{
				FireArmRoundClass @class = AM.SRoundDisplayDataDic[componentInChildren2.RoundType].Classes[0].Class;
				componentInChildren2.ReloadMagWithType(@class);
			}
		}

		public void FixAmmoRotation()
		{
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)_currentEquipment[0]) && Object.op_Implicit((Object)(object)_currentEquipment[1]) && Object.op_Implicit((Object)(object)_currentEquipment[0].GetComponent<FVRFireArm>()) && Object.op_Implicit((Object)(object)_currentEquipment[0].GetComponent<FVRFireArm>().MagazineMountPos))
			{
				_currentEquipment[1].transform.rotation = ((Component)_currentEquipment[0].GetComponent<FVRFireArm>().MagazineMountPos).transform.rotation;
			}
		}

		private void EquipWeapon(FVRPhysicalObject weapon)
		{
			FVRViveHand val = GM.CurrentMovementManager.Hands[1];
			if (LeftHandOption.LeftHandModeEnabled)
			{
				val = GM.CurrentMovementManager.Hands[0];
			}
			val.RetrieveObject(weapon);
		}

		private static void OnSosigKilledByPlayer(Sosig killedSosig)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			MonoBehaviourSingleton<GameManager>.Instance.Kills++;
			SosigEnemyID val = MonoBehaviourSingleton<SosigBehavior>.Instance.Sosigs[killedSosig];
			if (MonoBehaviourSingleton<Progression>.Instance.ProgressionType == KillProgressionType.Points)
			{
				int num = 1;
				foreach (EnemyData enemy in MonoBehaviourSingleton<Progression>.Instance.Enemies)
				{
					if (enemy.EnemyName == val)
					{
						num = enemy.Value;
						break;
					}
				}
				MonoBehaviourSingleton<Progression>.Instance.KillsWithCurrentWeapon += num;
				if (MonoBehaviourSingleton<Progression>.Instance.KillsWithCurrentWeapon >= KillsPerWeaponOption.KillsPerWeaponCount)
				{
					MonoBehaviourSingleton<Progression>.Instance.Promote();
				}
			}
			else if (MonoBehaviourSingleton<Progression>.Instance.ProgressionType == KillProgressionType.Tiers)
			{
				int num2 = -1;
				int num3 = -1;
				foreach (EnemyData enemy2 in MonoBehaviourSingleton<Progression>.Instance.Enemies)
				{
					num3++;
					if (enemy2.EnemyName == val)
					{
						num2 = num3;
						break;
					}
				}
				if (num2 == -1)
				{
					MonoBehaviourSingleton<Progression>.Instance.KillsWithCurrentWeapon = 0;
					MonoBehaviourSingleton<Progression>.Instance.CurrentTier = 0;
					MonoBehaviourSingleton<Progression>.Instance.Promote();
				}
				else
				{
					if (num2 != MonoBehaviourSingleton<Progression>.Instance.CurrentTier)
					{
						return;
					}
					MonoBehaviourSingleton<Progression>.Instance.KillsWithCurrentWeapon++;
					if (MonoBehaviourSingleton<Progression>.Instance.KillsWithCurrentWeapon >= MonoBehaviourSingleton<Progression>.Instance.Enemies[MonoBehaviourSingleton<Progression>.Instance.CurrentTier].Value + KillsPerWeaponOption.KillsPerWeaponCount)
					{
						MonoBehaviourSingleton<Progression>.Instance.CurrentTier++;
						MonoBehaviourSingleton<Progression>.Instance.KillsWithCurrentWeapon = 0;
						if (MonoBehaviourSingleton<Progression>.Instance.CurrentTier == MonoBehaviourSingleton<Progression>.Instance.Enemies.Count)
						{
							MonoBehaviourSingleton<Progression>.Instance.CurrentTier = 0;
							MonoBehaviourSingleton<Progression>.Instance.Promote();
						}
					}
				}
			}
			else
			{
				MonoBehaviourSingleton<Progression>.Instance.KillsWithCurrentWeapon++;
				if (MonoBehaviourSingleton<Progression>.Instance.KillsWithCurrentWeapon >= KillsPerWeaponOption.KillsPerWeaponCount)
				{
					MonoBehaviourSingleton<Progression>.Instance.Promote();
				}
			}
		}

		[HarmonyPatch(typeof(Sosig), "SosigDies")]
		[HarmonyPostfix]
		private static void OnSosigDied(Sosig __instance, DamageClass damClass, SosigDeathType deathType)
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: 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)
			if (!DeadSosigs.Contains(((Object)__instance).GetInstanceID()))
			{
				DeadSosigs.Add(((Object)__instance).GetInstanceID());
				if (__instance.GetDiedFromIFF() == GM.CurrentPlayerBody.GetPlayerIFF())
				{
					OnSosigKilledByPlayer(__instance);
				}
				__instance.DeSpawnSosig();
				MonoBehaviourSingleton<SosigBehavior>.Instance.OnSosigKilled(__instance);
				SosigEnemyID nextSosigType = GetNextSosigType();
				MonoBehaviourSingleton<SosigBehavior>.Instance.SpawnSosigRandomPlace(nextSosigType);
			}
		}

		public void InitEnemyProgression()
		{
			ProbabilityTotal = 0;
			InverseProbabilityTotal = 0;
			ProgressionType = GameSettings.CurrentPool.GetProgressionType();
			Enemies = GameSettings.CurrentPool.GetEnemies();
			foreach (EnemyData enemy in MonoBehaviourSingleton<Progression>.Instance.Enemies)
			{
				if (enemy.Value == 0)
				{
					enemy.Value = 1;
				}
			}
			if (MonoBehaviourSingleton<Progression>.Instance.ProgressionType == KillProgressionType.Points)
			{
				foreach (EnemyData enemy2 in MonoBehaviourSingleton<Progression>.Instance.Enemies)
				{
					InverseProbabilityTotal += Math.Max(1, (int)(1f / (float)enemy2.Value * 100f));
				}
			}
			foreach (EnemyData enemy3 in MonoBehaviourSingleton<Progression>.Instance.Enemies)
			{
				ProbabilityTotal += enemy3.Value;
			}
		}

		public static SosigEnemyID GetNextSosigType()
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0293: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: 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_0273: Unknown result type (might be due to invalid IL or missing references)
			//IL_0278: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_023e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0243: Unknown result type (might be due to invalid IL or missing references)
			if (MonoBehaviourSingleton<Progression>.Instance.Enemies.Count == 0)
			{
				Debug.Log((object)"No enemies loaded, make sure that your weaponpool is formatted correctly!");
				return (SosigEnemyID)1200;
			}
			if (MonoBehaviourSingleton<Progression>.Instance.ProgressionType == KillProgressionType.Count)
			{
				if (MonoBehaviourSingleton<Progression>.Instance.ProbabilityTotal == 0)
				{
					Debug.Log((object)"All probabilities set to 0!");
					return MonoBehaviourSingleton<Progression>.Instance.Enemies[Random.Range(0, MonoBehaviourSingleton<Progression>.Instance.Enemies.Count - 1)].EnemyName;
				}
				int num = Random.Range(0, MonoBehaviourSingleton<Progression>.Instance.ProbabilityTotal);
				int num2 = 0;
				foreach (EnemyData enemy in MonoBehaviourSingleton<Progression>.Instance.Enemies)
				{
					num2 += enemy.Value;
					if (num < num2)
					{
						return enemy.EnemyName;
					}
				}
				Debug.Log((object)"Default enemy selected");
				return MonoBehaviourSingleton<Progression>.Instance.Enemies[MonoBehaviourSingleton<Progression>.Instance.Enemies.Count - 1].EnemyName;
			}
			if (MonoBehaviourSingleton<Progression>.Instance.ProgressionType == KillProgressionType.Points)
			{
				if (MonoBehaviourSingleton<Progression>.Instance.ProbabilityTotal == 0)
				{
					Debug.Log((object)"All probabilities set to 0!");
					return MonoBehaviourSingleton<Progression>.Instance.Enemies[Random.Range(0, MonoBehaviourSingleton<Progression>.Instance.Enemies.Count - 1)].EnemyName;
				}
				int num3 = Random.Range(0, MonoBehaviourSingleton<Progression>.Instance.InverseProbabilityTotal);
				int num4 = 0;
				foreach (EnemyData enemy2 in MonoBehaviourSingleton<Progression>.Instance.Enemies)
				{
					num4 += Math.Max(1, (int)(1f / (float)enemy2.Value * 100f));
					if (num3 < num4)
					{
						return enemy2.EnemyName;
					}
				}
				Debug.Log((object)"Default enemy selection");
				return MonoBehaviourSingleton<Progression>.Instance.Enemies[MonoBehaviourSingleton<Progression>.Instance.Enemies.Count - 1].EnemyName;
			}
			if (MonoBehaviourSingleton<Progression>.Instance.ProgressionType == KillProgressionType.Tiers)
			{
				return MonoBehaviourSingleton<Progression>.Instance.Enemies[MonoBehaviourSingleton<Progression>.Instance.CurrentTier].EnemyName;
			}
			Debug.Log((object)"Progression type isn't handled correctly somehow, check that your weaponpool file is formatted correctly!");
			return (SosigEnemyID)1210;
		}

		public UIData GetProgressionTypeUIDefaults()
		{
			UIData result = default(UIData);
			switch (GameSettings.CurrentPool.GetProgressionType())
			{
			case KillProgressionType.Points:
			{
				result.Text = "Points to advance";
				int num = 0;
				foreach (EnemyData enemy in GameSettings.CurrentPool.GetEnemies())
				{
					num += enemy.Value;
				}
				result.Value = num;
				break;
			}
			case KillProgressionType.Tiers:
				result.Text = "Extra kills per tier";
				result.Value = 0;
				break;
			default:
				result.Text = "Kills to advance";
				result.Value = 3;
				break;
			}
			return result;
		}
	}
	public enum KillProgressionType
	{
		Count,
		Points,
		Tiers
	}
	public struct UIData
	{
		public string Text;

		public int Value;
	}
	public class SosigBehavior : MonoBehaviourSingleton<SosigBehavior>
	{
		public int MaxSosigCount = 8;

		[HideInInspector]
		public int RealSosigCount;

		[Header("Don't spawn sosigs too close or too far from the player")]
		public int IgnoredSpawnersCloseToPlayer = 2;

		public int IgnoredSpawnersFarFromPlayer = 0;

		public bool DespawnDistantSosigs = false;

		public float MaxSosigDistanceFromPlayer = 0f;

		public float HearRangeMultiplier = 1f;

		public float SightRangeMultiplier = 1f;

		public List<Transform> Waypoints;

		public List<CustomSosigSpawner> SosigSpawners;

		[HideInInspector]
		public Dictionary<Sosig, SosigEnemyID> Sosigs;

		public override void Awake()
		{
			base.Awake();
			Sosigs = new Dictionary<Sosig, SosigEnemyID>();
			GameManager.GameStartedEvent = (Action)Delegate.Combine(GameManager.GameStartedEvent, new Action(OnGameStarted));
		}

		private void OnGameStarted()
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			MonoBehaviourSingleton<Progression>.Instance.InitEnemyProgression();
			RealSosigCount = GameSettings.MaxSosigCount;
			for (int i = 0; i < RealSosigCount; i++)
			{
				SpawnSosigRandomPlace(Progression.GetNextSosigType());
			}
			((MonoBehaviour)this).StartCoroutine(UpdateWaypoints());
		}

		[HarmonyPatch(typeof(Sosig), "Start")]
		[HarmonyPostfix]
		private static void SosigSpawned(Sosig __instance)
		{
			__instance.CanBeKnockedOut = false;
			__instance.m_maxUnconsciousTime = 0f;
			__instance.BleedRateMult = 0.1f;
			for (int i = 0; i < __instance.Links.Count; i++)
			{
				__instance.Links[i].SetIntegrity(__instance.Links[i].m_integrity * 0.65f);
			}
			__instance.Links[0].DamMult = 13.5f;
			__instance.Links[1].DamMult = 6f;
			__instance.Links[2].DamMult = 5f;
			__instance.Links[3].DamMult = 4f;
			__instance.MaxHearingRange *= MonoBehaviourSingleton<SosigBehavior>.Instance.HearRangeMultiplier;
			__instance.MaxSightRange *= MonoBehaviourSingleton<SosigBehavior>.Instance.SightRangeMultiplier;
			if (MonoBehaviourSingleton<SosigBehavior>.Instance.DespawnDistantSosigs)
			{
				((MonoBehaviour)MonoBehaviourSingleton<SosigBehavior>.Instance).StartCoroutine(MonoBehaviourSingleton<SosigBehavior>.Instance.CheckSosigDistance(__instance));
			}
		}

		private IEnumerator UpdateWaypoints()
		{
			while (true)
			{
				for (int i = 0; i < Sosigs.Count; i++)
				{
					if (i >= 0 && i < Sosigs.Count)
					{
						Sosig key = Sosigs.ElementAt(i).Key;
						if (!((Object)(object)key == (Object)null))
						{
							key.SetCurrentOrder((SosigOrder)7);
							key.CommandAssaultPoint(Waypoints[Random.Range(0, Waypoints.Count)].position);
						}
					}
				}
				yield return (object)new WaitForSeconds((float)Random.Range(12, 25));
			}
		}

		private IEnumerator CheckSosigDistance(Sosig sosig)
		{
			WaitForSeconds delay = new WaitForSeconds(6f);
			while ((Object)(object)sosig != (Object)null)
			{
				yield return delay;
				if (Vector3.Distance(((Component)GM.CurrentPlayerBody).transform.position, ((Component)sosig).transform.position) > MaxSosigDistanceFromPlayer)
				{
					if (!Progression.DeadSosigs.Contains(((Object)sosig).GetInstanceID()))
					{
						SosigEnemyID sosigtype = Sosigs[sosig];
						Sosigs.Remove(sosig);
						sosig.DeSpawnSosig();
						MonoBehaviourSingleton<SosigBehavior>.Instance.SpawnSosigRandomPlace(sosigtype);
					}
					break;
				}
			}
		}

		public void SpawnSosigRandomPlace(SosigEnemyID sosigtype)
		{
			//IL_0095: 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)
			List<CustomSosigSpawner> list = SosigSpawners.OrderBy((CustomSosigSpawner spawner) => Vector3.Distance(((Component)spawner).transform.position, ((Component)GM.CurrentPlayerBody).transform.position)).ToList();
			if (IgnoredSpawnersCloseToPlayer > list.Count || IgnoredSpawnersFarFromPlayer > list.Count || IgnoredSpawnersCloseToPlayer + IgnoredSpawnersFarFromPlayer > list.Count)
			{
				Debug.LogError((object)"Ignoring more spawners than available, aborting");
			}
			int index = Random.Range(IgnoredSpawnersCloseToPlayer, list.Count - IgnoredSpawnersFarFromPlayer);
			SpawnedSosigInfo spawnedSosigInfo = list[index].Spawn(sosigtype);
			Sosigs.Add(spawnedSosigInfo.SpawnedSosig, spawnedSosigInfo.SosigType);
		}

		public void OnSosigKilled(Sosig sosig)
		{
			Sosigs.Remove(sosig);
		}

		public IEnumerator ClearSosigs()
		{
			List<Sosig> TempSosigsList = new List<Sosig>();
			foreach (Sosig key in Sosigs.Keys)
			{
				TempSosigsList.Add(key);
			}
			foreach (Sosig sosig in TempSosigsList)
			{
				Sosigs.Remove(sosig);
				sosig.DeSpawnSosig();
				SosigEnemyID sosigType = Progression.GetNextSosigType();
				yield return (object)new WaitForSeconds(1f);
				MonoBehaviourSingleton<SosigBehavior>.Instance.SpawnSosigRandomPlace(sosigType);
			}
		}

		private void OnDestroy()
		{
			GameManager.GameStartedEvent = (Action)Delegate.Remove(GameManager.GameStartedEvent, new Action(OnGameStarted));
		}
	}
}
namespace GunGame.Scripts.Weapons
{
	[Serializable]
	public class EnemyData
	{
		public SosigEnemyID EnemyName = (SosigEnemyID)1;

		public string EnemyNameString = "";

		public int Value = 0;

		public EnemyData(SosigEnemyID InputEnum, int InputValue)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: 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)
			EnemyName = InputEnum;
			Value = InputValue;
		}

		public EnemyData(string InputNameString, int InputValue)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			EnemyName = StringToSosigID(InputNameString);
			Value = InputValue;
		}

		private SosigEnemyID StringToSosigID(string InputString)
		{
			//IL_0032: 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_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				return (SosigEnemyID)Enum.Parse(typeof(SosigEnemyID), InputString, ignoreCase: true);
			}
			catch (Exception)
			{
				Debug.LogError((object)(InputString + " is not a valid SosigEnemyID, please check your weapon pool format"));
				return (SosigEnemyID)1;
			}
		}
	}
	[Serializable]
	public class GunData
	{
		public string GunName;

		public string MagName;

		public List<string> MagNames;

		public string Extra;

		public int CategoryID;

		public override string ToString()
		{
			return "Name: " + GunName + ", MagName: " + MagName + ", Extra: " + Extra;
		}
	}
	public class PoolChoice : MonoBehaviour
	{
		public Text TitleText;

		public Button Button;

		private WeaponPoolInterface _weaponPool;

		public void Initialize(WeaponPoolInterface weaponPool)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			_weaponPool = weaponPool;
			TitleText.text = _weaponPool.GetName();
			((UnityEvent)Button.onClick).AddListener(new UnityAction(OnClick));
		}

		public void OnClick()
		{
			GameSettings.ChangeCurrentPool(_weaponPool);
		}
	}
	public class WeaponBuffer : MonoBehaviour
	{
		public Transform BufferSpawnPos;

		private FVRPhysicalObject _gun;

		private FVRPhysicalObject _magazineToLoad;

		private FVRPhysicalObject _magazineForQuickbelt;

		private FVRPhysicalObject GetBufferObject(ObjectType type)
		{
			return (FVRPhysicalObject)(type switch
			{
				ObjectType.Gun => _gun, 
				ObjectType.MagazineToLoad => _magazineToLoad, 
				ObjectType.MagazineForQuickbelt => _magazineForQuickbelt, 
				_ => null, 
			});
		}

		public FVRPhysicalObject GetFromBuffer(ObjectType type, int index, bool demoted)
		{
			FVRPhysicalObject bufferObject = GetBufferObject(type);
			if (demoted)
			{
				if (Object.op_Implicit((Object)(object)bufferObject))
				{
					Object.Destroy((Object)(object)((Component)bufferObject).gameObject);
				}
				return SpawnImmediate(type, GameSettings.CurrentPool.GetWeapon(index));
			}
			FVRPhysicalObject val = bufferObject;
			if ((Object)(object)val == (Object)null)
			{
				val = SpawnImmediate(type, GameSettings.CurrentPool.GetWeapon(index));
			}
			return val;
		}

		public void ClearBuffer()
		{
			_gun = null;
			_magazineToLoad = null;
			_magazineForQuickbelt = null;
		}

		public void DestroyMagBuffer()
		{
			if (Object.op_Implicit((Object)(object)_magazineToLoad))
			{
				Object.Destroy((Object)(object)((Component)_magazineToLoad).gameObject);
			}
			if (Object.op_Implicit((Object)(object)_magazineForQuickbelt))
			{
				Object.Destroy((Object)(object)((Component)_magazineForQuickbelt).gameObject);
			}
		}

		public void GenerateBuffer(int currentIndex)
		{
			if (currentIndex + 1 < GameSettings.CurrentPool.GetWeaponCount())
			{
				((MonoBehaviour)this).StartCoroutine(SpawnAsync(ObjectType.Gun, GameSettings.CurrentPool.GetWeapon(currentIndex + 1)));
				((MonoBehaviour)this).StartCoroutine(SpawnAsync(ObjectType.MagazineToLoad, GameSettings.CurrentPool.GetWeapon(currentIndex + 1)));
				((MonoBehaviour)this).StartCoroutine(SpawnAsync(ObjectType.MagazineForQuickbelt, GameSettings.CurrentPool.GetWeapon(currentIndex + 1)));
			}
		}

		private IEnumerator SpawnAsync(ObjectType type, GunData gunData)
		{
			string weaponString = "";
			if (type == ObjectType.Gun)
			{
				weaponString = gunData.GunName;
			}
			if (type == ObjectType.MagazineToLoad || type == ObjectType.MagazineForQuickbelt)
			{
				weaponString = gunData.MagName;
			}
			FVRObject newObj = null;
			if (!IM.OD.TryGetValue(weaponString, out newObj))
			{
				Debug.LogError((object)("No object found with id: " + weaponString));
				yield break;
			}
			AnvilCallback<GameObject> callback = ((AnvilAsset)newObj).GetGameObjectAsync();
			yield return callback;
			Vector3 spawnOffset = Vector3.left * (float)type;
			switch (type)
			{
			case ObjectType.Gun:
				_gun = Object.Instantiate<GameObject>(callback.Result, BufferSpawnPos.position + spawnOffset, BufferSpawnPos.rotation).GetComponent<FVRPhysicalObject>();
				((Component)_gun).gameObject.SetActive(true);
				break;
			case ObjectType.MagazineToLoad:
				_magazineToLoad = Object.Instantiate<GameObject>(callback.Result, BufferSpawnPos.position + spawnOffset, BufferSpawnPos.rotation).GetComponent<FVRPhysicalObject>();
				((Component)_magazineToLoad).gameObject.SetActive(true);
				_magazineToLoad.UsesGravity = false;
				_magazineToLoad.RootRigidbody.isKinematic = true;
				break;
			case ObjectType.MagazineForQuickbelt:
				_magazineForQuickbelt = Object.Instantiate<GameObject>(callback.Result, BufferSpawnPos.position + spawnOffset, BufferSpawnPos.rotation).GetComponent<FVRPhysicalObject>();
				((Component)_magazineForQuickbelt).gameObject.SetActive(true);
				break;
			}
		}

		public FVRPhysicalObject SpawnImmediate(ObjectType objectType, GunData gunData)
		{
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			string text = "";
			if (objectType == ObjectType.Gun)
			{
				text = gunData.GunName;
			}
			if (objectType == ObjectType.MagazineToLoad || objectType == ObjectType.MagazineForQuickbelt)
			{
				text = gunData.MagName;
			}
			if (objectType == ObjectType.Extra)
			{
				text = gunData.Extra;
			}
			FVRObject value = null;
			if (!IM.OD.TryGetValue(text, out value))
			{
				Debug.LogError((object)("No object found with id: " + text));
				return null;
			}
			GameObject gameObject = ((AnvilAsset)value).GetGameObject();
			GameObject val = Object.Instantiate<GameObject>(gameObject, ((Component)this).transform.position + Vector3.up, ((Component)this).transform.rotation);
			val.SetActive(true);
			return val.GetComponent<FVRPhysicalObject>();
		}
	}
	public enum ObjectType
	{
		Gun,
		MagazineToLoad,
		MagazineForQuickbelt,
		Extra
	}
	[Serializable]
	public class WeaponPool : WeaponPoolInterface
	{
		public string Name;

		public string Description;

		public OrderType OrderType;

		public string EnemyType = "M_Swat_Scout";

		public int CurrentIndex;

		public List<GunData> Guns = new List<GunData>();

		[NonSerialized]
		public List<EnemyData> Enemies = new List<EnemyData>();

		[HideInInspector]
		public List<string> GunNames = new List<string>();

		[HideInInspector]
		public List<string> MagNames = new List<string>();

		[HideInInspector]
		public List<int> CategoryIDs = new List<int>();

		public string GetName()
		{
			return Name;
		}

		public string GetDescription()
		{
			return Description;
		}

		public GunData GetNextWeapon()
		{
			if (CurrentIndex + 1 >= GunNames.Count)
			{
				return null;
			}
			return Guns[CurrentIndex + 1];
		}

		public GunData GetWeapon(int index)
		{
			return Guns[index];
		}

		public int GetWeaponCount()
		{
			return Guns.Count;
		}

		public int GetCurrentWeaponIndex()
		{
			return CurrentIndex;
		}

		public GunData GetCurrentWeapon()
		{
			return Guns[CurrentIndex];
		}

		public KillProgressionType GetProgressionType()
		{
			return KillProgressionType.Count;
		}

		public List<EnemyData> GetEnemies()
		{
			return Enemies;
		}

		public bool IncrementProgress()
		{
			CurrentIndex++;
			if (CurrentIndex == Guns.Count)
			{
				return true;
			}
			return false;
		}

		public void DecrementProgress()
		{
			if (CurrentIndex > 0)
			{
				CurrentIndex--;
			}
		}

		public void Initialize()
		{
			SetGunOrder();
			SeedEnemyList();
			CurrentIndex = 0;
		}

		private void SetGunOrder()
		{
			if (OrderType == OrderType.Random)
			{
				IListExtensions.Shuffle<GunData>((IList<GunData>)Guns);
			}
			if (OrderType == OrderType.RandomWithinCategory)
			{
				IListExtensions.Shuffle<GunData>((IList<GunData>)Guns);
				Guns = Guns.OrderBy((GunData x) => x.CategoryID).ToList();
			}
		}

		private void SeedEnemyList()
		{
			Enemies.Add(new EnemyData(EnemyType, 1));
		}

		private void SetSpawners()
		{
		}
	}
	[Serializable]
	public class WeaponPoolAdvanced : WeaponPoolInterface
	{
		public string Name = "";

		public string Description = "";

		public OrderType OrderType = OrderType.Fixed;

		public string EnemyType = "M_Swat_Scout";

		public int CurrentIndex = 0;

		public string WeaponPoolType = "";

		public KillProgressionType EnemyProgressionType = KillProgressionType.Count;

		public List<GunData> Guns = new List<GunData>();

		public List<EnemyData> Enemies = new List<EnemyData>();

		[HideInInspector]
		public List<string> GunNames = new List<string>();

		[HideInInspector]
		public List<string> MagNames = new List<string>();

		[HideInInspector]
		public List<int> CategoryIDs = new List<int>();

		public string GetName()
		{
			return Name;
		}

		public string GetDescription()
		{
			return Description;
		}

		public GunData GetNextWeapon()
		{
			return Guns[CurrentIndex];
		}

		public GunData GetWeapon(int index)
		{
			return Guns[index];
		}

		public int GetWeaponCount()
		{
			return Guns.Count;
		}

		public int GetCurrentWeaponIndex()
		{
			return CurrentIndex;
		}

		public GunData GetCurrentWeapon()
		{
			return Guns[CurrentIndex];
		}

		public KillProgressionType GetProgressionType()
		{
			return EnemyProgressionType;
		}

		public List<EnemyData> GetEnemies()
		{
			return Enemies;
		}

		public bool IncrementProgress()
		{
			CurrentIndex++;
			if (CurrentIndex == Guns.Count)
			{
				return true;
			}
			return false;
		}

		public void DecrementProgress()
		{
			if (CurrentIndex > 0)
			{
				CurrentIndex--;
			}
		}

		public void Initialize()
		{
			SetGunOrder();
			SeedRandomMagazines();
			CurrentIndex = 0;
			AutofillEnemyData();
		}

		private void SetGunOrder()
		{
			if (OrderType == OrderType.Random)
			{
				IListExtensions.Shuffle<GunData>((IList<GunData>)Guns);
			}
			if (OrderType == OrderType.RandomWithinCategory)
			{
				IListExtensions.Shuffle<GunData>((IList<GunData>)Guns);
				Guns = Guns.OrderBy((GunData x) => x.CategoryID).ToList();
			}
		}

		private void AutofillEnemyData()
		{
			//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)
			foreach (EnemyData enemy in Enemies)
			{
				if (!Utility.IsNullOrWhiteSpace(enemy.EnemyNameString))
				{
					enemy.EnemyName = (SosigEnemyID)Enum.Parse(typeof(SosigEnemyID), enemy.EnemyNameString, ignoreCase: true);
				}
			}
		}

		private void SeedRandomMagazines()
		{
			Random.InitState((int)Convert.ToInt16(Time.time));
			int num = Random.Range(0, 10);
			foreach (GunData gun in Guns)
			{
				if (gun.MagNames.Count > 0)
				{
					gun.MagName = gun.MagNames[num % gun.MagNames.Count];
				}
				num++;
			}
		}
	}
	public interface WeaponPoolInterface
	{
		string GetName();

		string GetDescription();

		int GetWeaponCount();

		int GetCurrentWeaponIndex();

		GunData GetWeapon(int index);

		GunData GetCurrentWeapon();

		GunData GetNextWeapon();

		KillProgressionType GetProgressionType();

		List<EnemyData> GetEnemies();

		bool IncrementProgress();

		void DecrementProgress();

		void Initialize();
	}
	public enum OrderType
	{
		Fixed,
		Random,
		RandomWithinCategory
	}
	public class WeaponPoolLoader : MonoBehaviourSingleton<WeaponPoolLoader>
	{
		public static Action WeaponLoadedEvent;

		public Transform ChoicesListParent;

		public PoolChoice ChoicePrefab;

		public List<WeaponPool> DebugWeaponPools;

		private List<string> _loadedWeaponPoolsLocations = new List<string>();

		private List<WeaponPoolInterface> _weaponPools = new List<WeaponPoolInterface>();

		private List<PoolChoice> _choices = new List<PoolChoice>();

		public void SaveDebugWeaponPools()
		{
			for (int i = 0; i < DebugWeaponPools.Count; i++)
			{
				DebugWeaponPools[i].GunNames.Clear();
				DebugWeaponPools[i].MagNames.Clear();
				DebugWeaponPools[i].CategoryIDs.Clear();
				for (int j = 0; j < DebugWeaponPools[i].Guns.Count; j++)
				{
					DebugWeaponPools[i].GunNames.Add(DebugWeaponPools[i].Guns[j].GunName);
					DebugWeaponPools[i].MagNames.Add(DebugWeaponPools[i].Guns[j].MagName);
					DebugWeaponPools[i].CategoryIDs.Add(DebugWeaponPools[i].Guns[j].CategoryID);
				}
				DebugWeaponPools[i].Guns.Clear();
			}
			foreach (WeaponPool debugWeaponPool in DebugWeaponPools)
			{
				WriteWeaponPool(Application.dataPath + "/GunGame//GunGameWeaponPool_" + debugWeaponPool.Name + ".json", debugWeaponPool);
			}
		}

		public override void Awake()
		{
			base.Awake();
			_loadedWeaponPoolsLocations = GetWeaponPoolLocations();
			_weaponPools = new List<WeaponPoolInterface>();
			if (_loadedWeaponPoolsLocations.Count == 0)
			{
				Debug.LogError((object)"No weapon pools found!");
				return;
			}
			for (int i = 0; i < _loadedWeaponPoolsLocations.Count; i++)
			{
				WeaponPoolInterface weaponPoolInterface = LoadWeaponPool(_loadedWeaponPoolsLocations[i]);
				if (weaponPoolInterface != null)
				{
					_weaponPools.Add(weaponPoolInterface);
					Debug.Log((object)("Weapon pool loaded with name: " + weaponPoolInterface.GetName() + " and count: " + weaponPoolInterface.GetWeaponCount()));
				}
				else
				{
					Debug.Log((object)("Failed to load Weapon pool at location: " + _loadedWeaponPoolsLocations[i]));
				}
			}
			for (int j = 0; j < _weaponPools.Count; j++)
			{
				PoolChoice poolChoice = Object.Instantiate<PoolChoice>(ChoicePrefab, ChoicesListParent);
				poolChoice.Initialize(_weaponPools[j]);
				_choices.Add(poolChoice);
			}
			WeaponPoolInterface newPool = _weaponPools[0];
			GameSettings.ChangeCurrentPool(newPool);
			if (WeaponLoadedEvent != null)
			{
				WeaponLoadedEvent();
			}
		}

		public WeaponPoolInterface LoadWeaponPool(string path)
		{
			using StreamReader streamReader = new StreamReader(path);
			string text = streamReader.ReadToEnd();
			WeaponPoolAdvanced newWeaponPoolAdvanced = null;
			try
			{
				newWeaponPoolAdvanced = JsonUtility.FromJson<WeaponPoolAdvanced>(text);
			}
			catch (Exception ex)
			{
				Debug.Log((object)ex.Message);
				return null;
			}
			if (newWeaponPoolAdvanced.WeaponPoolType == "Advanced")
			{
				if (_weaponPools.FirstOrDefault((WeaponPoolInterface x) => x.GetName() == newWeaponPoolAdvanced.GetName()) != null)
				{
					return null;
				}
				Debug.Log((object)("Loaded advanced weapon pool: " + newWeaponPoolAdvanced.GetName()));
				return newWeaponPoolAdvanced;
			}
			WeaponPool newWeaponPool = JsonUtility.FromJson<WeaponPool>(text);
			if (_weaponPools.FirstOrDefault((WeaponPoolInterface x) => x.GetName() == newWeaponPool.GetName()) != null)
			{
				return null;
			}
			newWeaponPool.Guns.Clear();
			for (int i = 0; i < newWeaponPool.GunNames.Count; i++)
			{
				GunData gunData = new GunData();
				gunData.GunName = newWeaponPool.GunNames[i];
				gunData.MagName = newWeaponPool.MagNames[i];
				gunData.CategoryID = newWeaponPool.CategoryIDs[i];
				GunData item = gunData;
				newWeaponPool.Guns.Add(item);
			}
			Debug.Log((object)("Loaded basic weapon pool: " + newWeaponPoolAdvanced.GetName()));
			return newWeaponPool;
		}

		public void WriteWeaponPool(string path, WeaponPool weaponPool)
		{
			using StreamWriter streamWriter = new StreamWriter(path);
			string value = JsonUtility.ToJson((object)weaponPool, true);
			streamWriter.Write(value);
		}

		private List<string> GetWeaponPoolLocations()
		{
			string pluginPath = Paths.PluginPath;
			List<string> list = Directory.GetFiles(pluginPath, "GunGameWeaponPool*.json", SearchOption.AllDirectories).ToList();
			List<string> collection = Directory.GetFiles(pluginPath, "AdvancedGunGameWeaponPool*.json", SearchOption.AllDirectories).ToList();
			list.AddRange(collection);
			return list;
		}
	}
}
namespace Kodeman.GunGame
{
	[BepInPlugin("Kodeman.GunGame", "GunGame", "1.0.3")]
	[BepInProcess("h3vr.exe")]
	[Description("Built with MeatKit")]
	[BepInDependency("nrgill28.Atlas", "1.0.1")]
	public class GunGamePlugin : BaseUnityPlugin
	{
		private static readonly string BasePath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);

		internal static ManualLogSource Logger;

		private void Awake()
		{
			Logger = ((BaseUnityPlugin)this).Logger;
			LoadAssets();
		}

		private void LoadAssets()
		{
			Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "Kodeman.GunGame");
			AtlasPlugin.RegisterScene(Path.Combine(BasePath, "gungame"));
		}
	}
}
namespace Technie.PhysicsCreator
{
	public class AxisAlignedBoxFitter
	{
		public void Fit(Hull hull, Vector3[] meshVertices, int[] meshIndices)
		{
			//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)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			Vector3[] selectedVertices = FaceAlignmentBoxFitter.GetSelectedVertices(hull, meshVertices, meshIndices);
			ConstructionPlane plane = new ConstructionPlane(Vector3.zero, Vector3.up, Vector3.right);
			RotatedBox computedBox = RotatedBoxFitter.FindTightestBox(plane, selectedVertices);
			RotatedBoxFitter.ApplyToHull(computedBox, hull);
		}
	}
	public class Pose
	{
		public Vector3 forward;

		public Vector3 up;

		public Vector3 right;
	}
	public class Triangle
	{
		public Vector3 normal;

		public float area;

		public Vector3 center;

		public Triangle(Vector3 p0, Vector3 p1, Vector3 p2)
		{
			//IL_0007: 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)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: 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_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = p1 - p0;
			Vector3 val2 = p2 - p0;
			Vector3 val3 = Vector3.Cross(val, val2);
			area = ((Vector3)(ref val3)).magnitude * 0.5f;
			normal = ((Vector3)(ref val3)).normalized;
			center = (p0 + p1 + p2) / 3f;
		}
	}
	public class TriangleBucket
	{
		private List<Triangle> triangles;

		private Vector3 averagedNormal;

		private Vector3 averagedCenter;

		private float totalArea;

		public float Area => totalArea;

		public TriangleBucket(Triangle initialTriangle)
		{
			triangles = new List<Triangle>();
			triangles.Add(initialTriangle);
			CalculateNormal();
			CalcTotalArea();
		}

		public void Add(Triangle t)
		{
			triangles.Add(t);
			CalculateNormal();
			CalcTotalArea();
		}

		public void Add(TriangleBucket otherBucket)
		{
			foreach (Triangle triangle in otherBucket.triangles)
			{
				triangles.Add(triangle);
			}
			CalculateNormal();
			CalcTotalArea();
		}

		private void CalculateNormal()
		{
			//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_0029: 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_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			averagedNormal = Vector3.zero;
			foreach (Triangle triangle in triangles)
			{
				averagedNormal += triangle.normal * triangle.area;
			}
			((Vector3)(ref averagedNormal)).Normalize();
		}

		public Vector3 GetAverageNormal()
		{
			//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_000d: Unknown result type (might be due to invalid IL or missing references)
			return averagedNormal;
		}

		public Vector3 GetAverageCenter()
		{
			//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_0018: Unknown result type (might be due to invalid IL or missing references)
			return triangles[0].center;
		}

		private void CalcTotalArea()
		{
			totalArea = 0f;
			foreach (Triangle triangle in triangles)
			{
				totalArea += triangle.area;
			}
		}
	}
	public class TriangleAreaSorter : IComparer<Triangle>
	{
		public int Compare(Triangle lhs, Triangle rhs)
		{
			if (lhs.area < rhs.area)
			{
				return 1;
			}
			if (lhs.area > rhs.area)
			{
				return -1;
			}
			return 0;
		}
	}
	public class TriangleBucketSorter : IComparer<TriangleBucket>
	{
		public int Compare(TriangleBucket lhs, TriangleBucket rhs)
		{
			if (lhs.Area < rhs.Area)
			{
				return 1;
			}
			if (lhs.Area > rhs.Area)
			{
				return -1;
			}
			return 0;
		}
	}
	public class FaceAlignmentBoxFitter
	{
		public void Fit(Hull hull, Vector3[] meshVertices, int[] meshIndices)
		{
			if (meshIndices.Length < 3)
			{
				return;
			}
			List<Triangle> list = FindTriangles(meshVertices, meshIndices, hull.selectedFaces);
			list.Sort(new TriangleAreaSorter());
			List<TriangleBucket> list2 = new List<TriangleBucket>();
			foreach (Triangle item in list)
			{
				TriangleBucket triangleBucket = FindBestBucket(item, 30f, list2);
				if (triangleBucket != null)
				{
					triangleBucket.Add(item);
					continue;
				}
				triangleBucket = new TriangleBucket(item);
				list2.Add(triangleBucket);
			}
			while (list2.Count > 3)
			{
				MergeClosestBuckets(list2);
			}
			list2.Sort(new TriangleBucketSorter());
			Vector3[] selectedVertices = GetSelectedVertices(hull, meshVertices, meshIndices);
			ConstructionPlane plane = CreateConstructionPlane(list2[0], (list2.Count <= 1) ? null : list2[1], (list2.Count <= 2) ? null : list2[2]);
			RotatedBox computedBox = RotatedBoxFitter.FindTightestBox(plane, selectedVertices);
			RotatedBoxFitter.ApplyToHull(computedBox, hull);
		}

		public static List<Triangle> FindTriangles(Vector3[] meshVertices, int[] meshIndices, List<int> selectedFaces)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//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_0061: 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_0065: Unknown result type (might be due to invalid IL or missing references)
			List<Triangle> list = new List<Triangle>();
			foreach (int selectedFace in selectedFaces)
			{
				int num = meshIndices[selectedFace * 3];
				int num2 = meshIndices[selectedFace * 3 + 1];
				int num3 = meshIndices[selectedFace * 3 + 2];
				Vector3 p = meshVertices[num];
				Vector3 p2 = meshVertices[num2];
				Vector3 p3 = meshVertices[num3];
				Triangle item = new Triangle(p, p2, p3);
				list.Add(item);
			}
			return list;
		}

		public static void FindTriangles(Hull hull, Vector3[] meshVertices, int[] meshIndices, out Vector3[] hullVertices, out int[] hullIndices)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: 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_0064: 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_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			List<Vector3> list = new List<Vector3>();
			foreach (int selectedFace in hull.selectedFaces)
			{
				int num = meshIndices[selectedFace * 3];
				int num2 = meshIndices[selectedFace * 3 + 1];
				int num3 = meshIndices[selectedFace * 3 + 2];
				Vector3 item = meshVertices[num];
				Vector3 item2 = meshVertices[num2];
				Vector3 item3 = meshVertices[num3];
				list.Add(item);
				list.Add(item2);
				list.Add(item3);
			}
			hullVertices = list.ToArray();
			hullIndices = new int[hullVertices.Length];
			for (int i = 0; i < hullIndices.Length; i++)
			{
				hullIndices[i] = i;
			}
		}

		public static Vector3[] GetSelectedVertices(Hull hull, Vector3[] meshVertices, int[] meshIndices)
		{
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<int, int> dictionary = new Dictionary<int, int>();
			foreach (int selectedFace in hull.selectedFaces)
			{
				int num = meshIndices[selectedFace * 3];
				int num2 = meshIndices[selectedFace * 3 + 1];
				int num3 = meshIndices[selectedFace * 3 + 2];
				dictionary[num] = num;
				dictionary[num2] = num2;
				dictionary[num3] = num3;
			}
			List<Vector3> list = new List<Vector3>();
			foreach (int key in dictionary.Keys)
			{
				list.Add(meshVertices[key]);
			}
			return list.ToArray();
		}

		private TriangleBucket FindBestBucket(Triangle tri, float thresholdAngleDeg, List<TriangleBucket> buckets)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: 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_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			TriangleBucket result = null;
			float num = float.PositiveInfinity;
			foreach (TriangleBucket bucket in buckets)
			{
				float num2 = Vector3.Angle(tri.normal, bucket.GetAverageNormal());
				if (num2 < thresholdAngleDeg && num2 < num)
				{
					num = num2;
					result = bucket;
					continue;
				}
				float num3 = Vector3.Angle(tri.normal * -1f, bucket.GetAverageNormal());
				if (num3 < thresholdAngleDeg && num3 < num)
				{
					tri.normal *= -1f;
					num = num3;
					result = bucket;
				}
			}
			return result;
		}

		private void MergeClosestBuckets(List<TriangleBucket> buckets)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			TriangleBucket triangleBucket = null;
			TriangleBucket triangleBucket2 = null;
			float num = float.PositiveInfinity;
			for (int i = 0; i < buckets.Count; i++)
			{
				for (int j = i + 1; j < buckets.Count; j++)
				{
					TriangleBucket triangleBucket3 = buckets[i];
					TriangleBucket triangleBucket4 = buckets[j];
					float num2 = Vector3.Angle(triangleBucket3.GetAverageNormal(), triangleBucket4.GetAverageNormal());
					if (num2 < num)
					{
						num = num2;
						triangleBucket = triangleBucket3;
						triangleBucket2 = triangleBucket4;
					}
				}
			}
			if (triangleBucket != null && triangleBucket2 != null)
			{
				buckets.Remove(triangleBucket2);
				triangleBucket.Add(triangleBucket2);
			}
		}

		private ConstructionPlane CreateConstructionPlane(TriangleBucket primaryBucket, TriangleBucket secondaryBucket, TriangleBucket tertiaryBucket)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: 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_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: 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_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0023: 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_002c: 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_0072: 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_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: 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)
			if (primaryBucket != null && secondaryBucket != null)
			{
				Vector3 averageNormal = primaryBucket.GetAverageNormal();
				Vector3 t = Vector3.Cross(averageNormal, secondaryBucket.GetAverageNormal());
				Vector3 averageCenter = primaryBucket.GetAverageCenter();
				return new ConstructionPlane(averageCenter, averageNormal, t);
			}
			if (primaryBucket != null)
			{
				Vector3 averageNormal2 = primaryBucket.GetAverageNormal();
				Vector3 averageCenter2 = primaryBucket.GetAverageCenter();
				Vector3 t2 = Vector3.Cross(averageNormal2, (!(Vector3.Dot(averageNormal2, Vector3.up) > 0.5f)) ? Vector3.up : Vector3.right);
				return new ConstructionPlane(averageCenter2, averageNormal2, t2);
			}
			return null;
		}
	}
	public class GizmoUtils
	{
		public static void ToggleGizmos(bool gizmosOn)
		{
			int num = (gizmosOn ? 1 : 0);
			Assembly assembly = Assembly.GetAssembly(typeof(Editor));
			Type type = assembly.GetType("UnityEditor.AnnotationUtility");
			if ((object)type == null)
			{
				return;
			}
			MethodInfo method = type.GetMethod("GetAnnotations", BindingFlags.Static | BindingFlags.NonPublic);
			MethodInfo method2 = type.GetMethod("SetGizmoEnabled", BindingFlags.Static | BindingFlags.NonPublic);
			MethodInfo method3 = type.GetMethod("SetIconEnabled", BindingFlags.Static | BindingFlags.NonPublic);
			object obj = method.Invoke(null, null);
			foreach (object item in (IEnumerable)obj)
			{
				Type type2 = item.GetType();
				FieldInfo field = type2.GetField("classID", BindingFlags.Instance | BindingFlags.Public);
				FieldInfo field2 = type2.GetField("scriptClass", BindingFlags.Instance | BindingFlags.Public);
				if ((object)field == null || (object)field2 == null)
				{
					continue;
				}
				int num2 = (int)field.GetValue(item);
				string text = (string)field2.GetValue(item);
				if (text == "HullPainter")
				{
					switch (method2.GetParameters().Length)
					{
					case 3:
						method2.Invoke(null, new object[3] { num2, text, num });
						break;
					case 4:
						method2.Invoke(null, new object[4] { num2, text, num, true });
						break;
					}
					int num3 = method3.GetParameters().Length;
					if (num3 == 3)
					{
						method3.Invoke(null, new object[3] { num2, text, num });
					}
				}
			}
		}
	}
	public class HullData : ScriptableObject
	{
	}
	public class HullMapping
	{
		public Hull sourceHull;

		public Collider generatedCollider;

		public MeshCollider[] autoGeneratedColliders;

		public HullPainterChild targetChild;

		public HullPainterChild[] targetAutoGeneratedChilds;

		public void AddAutoChild(HullPainterChild newChild, MeshCollider newCollider)
		{
			if ((Object)(object)newChild != (Object)null)
			{
				List<HullPainterChild> list = new List<HullPainterChild>();
				if (targetAutoGeneratedChilds != null)
				{
					list.AddRange(targetAutoGeneratedChilds);
				}
				if (!list.Contains(newChild))
				{
					list.Add(newChild);
					targetAutoGeneratedChilds = list.ToArray();
				}
			}
			if ((Object)(object)newCollider != (Object)null)
			{
				List<MeshCollider> list2 = new List<MeshCollider>();
				if (autoGeneratedColliders != null)
				{
					list2.AddRange(autoGeneratedColliders);
				}
				if (!list2.Contains(newCollider))
				{
					list2.Add(newCollider);
					autoGeneratedColliders = list2.ToArray();
				}
			}
		}
	}
	public class HullPainter : MonoBehaviour
	{
		public PaintingData paintingData;

		public HullData hullData;

		private List<HullMapping> hullMapping;

		private Mesh debugMesh;

		private void OnDestroy()
		{
			SceneView.RepaintAll();
		}

		public void CreateColliderComponents(Mesh[] autoHulls)
		{
			CreateHullMapping();
			foreach (Hull hull in paintingData.hulls)
			{
				UpdateCollider(hull);
			}
			foreach (Hull hull2 in paintingData.hulls)
			{
				CreateAutoHulls(hull2, autoHulls);
			}
		}

		public void RemoveAllColliders()
		{
			if (hullMapping == null)
			{
				return;
			}
			foreach (HullMapping item in hullMapping)
			{
				DestroyImmediateWithUndo((Object)(object)item.generatedCollider);
				if (item.autoGeneratedColliders != null)
				{
					MeshCollider[] autoGeneratedColliders = item.autoGeneratedColliders;
					foreach (MeshCollider obj in autoGeneratedColliders)
					{
						DestroyImmediateWithUndo((Object)(object)obj);
					}
				}
			}
			for (int num = hullMapping.Count - 1; num >= 0; num--)
			{
				if ((Object)(object)hullMapping[num].targetChild != (Object)null)
				{
					hullMapping.RemoveAt(num);
				}
			}
		}

		public void RemoveAllGenerated()
		{
			CreateHullMapping();
			foreach (HullMapping item in hullMapping)
			{
				DestroyImmediateWithUndo((Object)(object)item.generatedCollider);
				if ((Object)(object)item.targetChild != (Object)null)
				{
					DestroyImmediateWithUndo((Object)(object)((Component)item.targetChild).gameObject);
				}
				if (item.autoGeneratedColliders != null)
				{
					MeshCollider[] autoGeneratedColliders = item.autoGeneratedColliders;
					foreach (MeshCollider obj in autoGeneratedColliders)
					{
						DestroyImmediateWithUndo((Object)(object)obj);
					}
				}
				if (item.targetAutoGeneratedChilds == null)
				{
					continue;
				}
				HullPainterChild[] targetAutoGeneratedChilds = item.targetAutoGeneratedChilds;
				foreach (HullPainterChild hullPainterChild in targetAutoGeneratedChilds)
				{
					GameObject gameObject = ((Component)hullPainterChild).gameObject;
					DestroyImmediateWithUndo((Object)(object)hullPainterChild);
					if (gameObject.transform.childCount == 0 && gameObject.GetComponents<Component>().Length == 1)
					{
						DestroyImmediateWithUndo((Object)(object)gameObject);
					}
				}
			}
		}

		private static bool IsDeletable(GameObject obj)
		{
			Component[] components = obj.GetComponents<Component>();
			int num = 0;
			Component[] array = components;
			foreach (Component val in array)
			{
				if (val is Transform || val is Collider || val is HullPainter || val is HullPainterChild)
				{
					num++;
				}
			}
			return components.Length == num;
		}

		private static void DestroyImmediateWithUndo(Object obj)
		{
			if (!(obj == (Object)null))
			{
				Undo.DestroyObjectImmediate(obj);
			}
		}

		private void CreateHullMapping()
		{
			//IL_04c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_04eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0526: Unknown result type (might be due to invalid IL or missing references)
			//IL_052d: Unknown result type (might be due to invalid IL or missing references)
			//IL_05d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_05dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_05f5: Unknown result type (might be due to invalid IL or missing references)
			if (this.hullMapping == null)
			{
				this.hullMapping = new List<HullMapping>();
			}
			for (int num = this.hullMapping.Count - 1; num >= 0; num--)
			{
				HullMapping hullMapping = this.hullMapping[num];
				if (hullMapping == null || hullMapping.sourceHull == null || ((Object)(object)hullMapping.generatedCollider == (Object)null && (Object)(object)hullMapping.targetChild == (Object)null))
				{
					this.hullMapping.RemoveAt(num);
				}
			}
			foreach (Hull hull4 in paintingData.hulls)
			{
				if (IsMapped(hull4))
				{
					Collider val = FindExistingCollider(this.hullMapping, hull4);
					bool flag = hull4.type == HullType.ConvexHull && val is MeshCollider;
					bool flag2 = hull4.type == HullType.Box && val is BoxCollider;
					bool flag3 = hull4.type == HullType.Sphere && val is SphereCollider;
					bool flag4 = hull4.type == HullType.Face && val is MeshCollider;
					bool flag5 = hull4.type == HullType.FaceAsBox && val is BoxCollider;
					bool flag6 = hull4.type == HullType.Auto && val is MeshCollider && hull4.autoMeshes != null && hull4.autoMeshes.Length > 0;
					bool flag7 = flag || flag2 || flag3 || flag4 || flag5 || flag6;
					bool flag8 = (Object)(object)val == (Object)null || hull4.isChildCollider == ((Object)(object)((Component)val).transform.parent == (Object)(object)((Component)this).transform) || hull4.type == HullType.Auto;
					if (!flag7 || !flag8)
					{
						DestroyImmediateWithUndo((Object)(object)val);
						RemoveMapping(hull4);
					}
				}
			}
			List<Hull> list = new List<Hull>();
			List<Collider> list2 = new List<Collider>();
			List<HullPainterChild> list3 = new List<HullPainterChild>();
			foreach (Hull hull5 in paintingData.hulls)
			{
				if (!IsMapped(hull5))
				{
					list.Add(hull5);
				}
			}
			foreach (Collider item in FindLocal<Collider>())
			{
				if (!IsMapped(item))
				{
					list2.Add(item);
				}
			}
			foreach (HullPainterChild item2 in FindLocal<HullPainterChild>())
			{
				if (!IsMapped(item2))
				{
					list3.Add(item2);
				}
			}
			for (int num2 = list.Count - 1; num2 >= 0; num2--)
			{
				Hull hull = list[num2];
				bool flag9 = false;
				for (int num3 = list2.Count - 1; num3 >= 0; num3--)
				{
					Collider val2 = list2[num3];
					MeshCollider val3 = (MeshCollider)(object)((val2 is MeshCollider) ? val2 : null);
					BoxCollider val4 = (BoxCollider)(object)((val2 is BoxCollider) ? val2 : null);
					SphereCollider val5 = (SphereCollider)(object)((val2 is SphereCollider) ? val2 : null);
					HullPainterChild hullPainterChild = null;
					if ((Object)(object)((Component)val2).transform.parent == (Object)(object)((Component)this).transform)
					{
						hullPainterChild = ((Component)val2).gameObject.GetComponent<HullPainterChild>();
					}
					bool flag10 = hull.isChildCollider && (Object)(object)((Component)val2).transform.parent == (Object)(object)((Component)this).transform;
					if ((Object)(object)hullPainterChild != (Object)null && hullPainterChild.isAutoHull && hull.type == HullType.Auto && (Object)(object)val3 != (Object)null && hull.ContainsAutoMesh(val3.sharedMesh))
					{
						HullMapping hullMapping2 = FindMapping(hull);
						if (hullMapping2 == null)
						{
							hullMapping2 = new HullMapping();
							hullMapping2.sourceHull = hull;
							this.hullMapping.Add(hullMapping2);
						}
						hullMapping2.AddAutoChild(hullPainterChild, (MeshCollider)(object)((val2 is MeshCollider) ? val2 : null));
						hullPainterChild.parent = this;
						list2.RemoveAt(num3);
						list3.Remove(hullPainterChild);
						flag9 = true;
					}
					else if (flag10)
					{
						bool flag11 = hull.type == HullType.Box && val2 is BoxCollider && Approximately(((Bounds)(ref hull.collisionBox)).center, val4.center) && Approximately(((Bounds)(ref hull.collisionBox)).size, val4.size);
						bool flag12 = hull.type == HullType.Sphere && val2 is SphereCollider && hull.collisionSphere != null && Approximately(hull.collisionSphere.center, val5.center) && Approximately(hull.collisionSphere.radius, val5.radius);
						bool flag13 = hull.type == HullType.ConvexHull && val2 is MeshCollider && (Object)(object)val3.sharedMesh == (Object)(object)hull.collisionMesh;
						bool flag14 = hull.type == HullType.Face && val2 is MeshCollider && (Object)(object)val3.sharedMesh == (Object)(object)hull.faceCollisionMesh;
						bool flag15 = hull.type == HullType.FaceAsBox && val2 is BoxCollider && Approximately(hull.faceBoxCenter, val4.center) && Approximately(hull.faceBoxSize, val4.size);
						if (flag11 || flag12 || flag13 || flag14 || flag15)
						{
							AddMapping(hull, val2, hullPainterChild);
							list.RemoveAt(num2);
							list2.RemoveAt(num3);
							for (int i = 0; i < list3.Count; i++)
							{
								if ((Object)(object)list3[i] == (Object)(object)hullPainterChild)
								{
									list3.RemoveAt(i);
									break;
								}
							}
							break;
						}
					}
				}
				if (flag9)
				{
					list.RemoveAt(num2);
				}
			}
			for (int num4 = list.Count - 1; num4 >= 0; num4--)
			{
				Hull hull2 = list[num4];
				if (hull2.isChildCollider)
				{
					for (int num5 = list3.Count - 1; num5 >= 0; num5--)
					{
						HullPainterChild child = list3[num5];
						HullMapping hullMapping3 = FindMapping(child);
						if (hullMapping3 != null && hullMapping3.sourceHull != null)
						{
							if ((Object)(object)hullMapping3.generatedCollider == (Object)null)
							{
								RecreateChildCollider(hullMapping3);
							}
							list.RemoveAt(num4);
							list3.RemoveAt(num5);
							break;
						}
					}
				}
			}
			for (int num6 = list.Count - 1; num6 >= 0; num6--)
			{
				Hull hull3 = list[num6];
				if (hull3.isChildCollider && hull3.type == HullType.Auto)
				{
					bool flag16 = false;
					for (int num7 = list3.Count - 1; num7 >= 0; num7--)
					{
						HullPainterChild hullPainterChild2 = list3[num7];
						if (hullPainterChild2.isAutoHull && ((Object)((Component)hullPainterChild2).gameObject).name.StartsWith(hull3.name))
						{
							HullMapping hullMapping4 = FindMapping(hull3);
							if (hullMapping4 == null)
							{
								hullMapping4 = new HullMapping();
								hullMapping4.sourceHull = hull3;
								this.hullMapping.Add(hullMapping4);
							}
							hullMapping4.AddAutoChild(hullPainterChild2, null);
							list3.RemoveAt(num7);
							flag16 = true;
						}
					}
					if (flag16)
					{
						list.RemoveAt(num6);
					}
				}
			}
			foreach (HullMapping item3 in this.hullMapping)
			{
				if ((Object)(object)item3.targetChild != (Object)null && (Object)(object)item3.generatedCollider == (Object)null)
				{
					RecreateChildCollider(item3);
				}
			}
			foreach (HullMapping item4 in this.hullMapping)
			{
				if ((Object)(object)item4.targetChild == (Object)null && (Object)(object)item4.generatedCollider != (Object)null && (Object)(object)((Component)item4.generatedCollider).transform.parent == (Object)(object)((Component)this).transform)
				{
					HullPainterChild hullPainterChild3 = AddComponent<HullPainterChild>(((Component)item4.generatedCollider).gameObject);
					hullPainterChild3.parent = this;
					item4.targetChild = hullPainterChild3;
				}
			}
			foreach (Hull item5 in list)
			{
				if (item5.type == HullType.Box)
				{
					CreateCollider<BoxCollider>(item5);
				}
				else if (item5.type == HullType.Sphere)
				{
					CreateCollider<SphereCollider>(item5);
				}
				else if (item5.type == HullType.ConvexHull)
				{
					CreateCollider<MeshCollider>(item5);
				}
				else if (item5.type == HullType.Face)
				{
					CreateCollider<MeshCollider>(item5);
				}
				else if (item5.type == HullType.FaceAsBox)
				{
					CreateCollider<BoxCollider>(item5);
				}
			}
			foreach (Collider item6 in list2)
			{
				if ((Object)(object)item6 == (Object)null)
				{
					continue;
				}
				if ((Object)(object)((Component)item6).gameObject == (Object)(object)((Component)this).gameObject)
				{
					DestroyImmediateWithUndo((Object)(object)item6);