Decompiled source of MatchMaker v0.2.1

plugins/Matchmaker.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using EntityStates;
using EntityStates.AI.Walker;
using EntityStates.Commando;
using HG.BlendableTypes;
using JetBrains.Annotations;
using KinematicCharacterController;
using MatcherMod;
using MatcherMod.Modules;
using MatcherMod.Modules.Achievements;
using MatcherMod.Modules.BaseStates;
using MatcherMod.Modules.Characters;
using MatcherMod.Modules.Components;
using MatcherMod.Modules.SkillDefs;
using MatcherMod.Modules.UI;
using MatcherMod.Survivors.Matcher;
using MatcherMod.Survivors.Matcher.Components;
using MatcherMod.Survivors.Matcher.Components.UI;
using MatcherMod.Survivors.Matcher.Content;
using MatcherMod.Survivors.Matcher.SkillDefs;
using MatcherMod.Survivors.Matcher.SkillStates;
using Matchmaker;
using Matchmaker.MatchGrid;
using On.RoR2;
using On.RoR2.UI;
using R2API;
using RiskOfOptions;
using RiskOfOptions.OptionConfigs;
using RiskOfOptions.Options;
using RoR2;
using RoR2.Achievements;
using RoR2.Audio;
using RoR2.CharacterAI;
using RoR2.ContentManagement;
using RoR2.Orbs;
using RoR2.Projectile;
using RoR2.Skills;
using RoR2.UI;
using ShaderSwapper;
using TMPro;
using Unity;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.EventSystems;
using UnityEngine.Networking;
using UnityEngine.Rendering;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.UI;

[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: CompilationRelaxations(8)]
[assembly: AssemblyCompany("Matchmaker")]
[assembly: AssemblyProduct("Matchmaker")]
[assembly: AssemblyTitle("Matchmaker")]
[assembly: AssemblyInformationalVersion("1.0.0+4db30a441e14cc77f733f20c727fb208967a49ea")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace Matchmaker
{
	public static class Util
	{
		public static bool IsDebug => CharacterConfig.Debug.Value;

		public static Vector3 ToVector3(this Vector2 vector)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			return new Vector3(vector.x, vector.y, 0f);
		}

		public static Vector3 ToVector3(this Vector2Int vector)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			return new Vector3((float)((Vector2Int)(ref vector)).x, (float)((Vector2Int)(ref vector)).y, 0f);
		}

		public static Vector2 ToVector2(this Vector3 vector)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			return new Vector2(vector.x, vector.y);
		}

		public static Vector2 ToVector2(this Vector2Int vector)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			return new Vector2((float)((Vector2Int)(ref vector)).x, (float)((Vector2Int)(ref vector)).y);
		}

		public static Vector2Int RoundToInt(this Vector2 vector)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			return new Vector2Int(Mathf.RoundToInt(vector.x), Mathf.RoundToInt(vector.y));
		}

		public static Vector2Int FloorToInt(this Vector2 vector)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			return new Vector2Int(Mathf.FloorToInt(vector.x), Mathf.FloorToInt(vector.y));
		}

		public static bool FAILSAFE(ref int count)
		{
			count++;
			if (count > 100000)
			{
				Debug.LogError((object)"FAILSAFE");
				return true;
			}
			return false;
		}

		public static float ExpDecayLerp(float a, float b, float decay, float deltaTime)
		{
			return b + (a - b) * Mathf.Exp((0f - decay) * deltaTime);
		}

		public static Vector3 ExpDecayLerp(Vector3 a, Vector3 b, float decay, float deltaTime)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			return b + (a - b) * Mathf.Exp((0f - decay) * deltaTime);
		}

		public static Color ExpDecayLerp(Color a, Color b, float decay, float deltaTime)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			return b + (a - b) * Mathf.Exp((0f - decay) * deltaTime);
		}

		public static void NormalizeSpriteScale(SpriteRenderer spriteRenderer, float scale)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: 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_002d: 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)
			Transform transform = ((Component)spriteRenderer).transform;
			Vector3 val = Vector3.one * scale * spriteRenderer.sprite.pixelsPerUnit;
			Rect rect = spriteRenderer.sprite.rect;
			transform.localScale = val / ((Rect)(ref rect)).width;
		}

		public static int WeightedRandom(List<float> values, bool normalize = true)
		{
			if (normalize)
			{
				values.Normalize();
			}
			float num = 0f;
			float value = Random.value;
			for (int i = 0; i < values.Count; i++)
			{
				num += values[i];
				if (value <= num)
				{
					return i;
				}
			}
			return 0;
		}

		public static void Normalize(this List<float> weights)
		{
			float num = 0f;
			for (int i = 0; i < weights.Count; i++)
			{
				num += weights[i];
			}
			if (num > 0f)
			{
				for (int j = 0; j < weights.Count; j++)
				{
					weights[j] /= num;
				}
			}
		}
	}
}
namespace Matchmaker.MatchGrid
{
	public enum DragDirection
	{
		HORIZONTAL = 1,
		VERTICAL = -1
	}
	public class InteractableCombatScroll : InteractableTileBehavior
	{
		protected override void Activate()
		{
			BreakThisTile();
			for (int i = 0; i < base.matchGrid.TileGrid.GetLength(0); i++)
			{
				for (int j = 0; j < base.matchGrid.TileGrid.GetLength(1); j++)
				{
					for (int k = 2; k < base.matchGrid.TileTypes.Length; k++)
					{
						if ((Object)(object)base.matchGrid.TileGrid[i, j] != (Object)null && base.matchGrid.TileGrid[i, j].TileType == base.matchGrid.TileTypes[k])
						{
							base.matchGrid.TileGrid[i, j].Transform(base.matchGrid.TileTypes[Random.Range(0, 2)]);
						}
					}
				}
			}
			base.matchGrid.DelayedProcessAllGridMatches(0.5f);
		}
	}
	public abstract class InteractableTileBehavior : MatchTileBehavior
	{
		public override void OnTilePointerDown(MatchTile tile, PointerEventData eventData)
		{
			base.matchGrid.GetSelected();
			if (base.matchGrid.CanInteract)
			{
				Activate();
			}
		}

		protected abstract void Activate();

		public override bool CheckAgainstThisTile(MatchTile otherTile)
		{
			return false;
		}

		public override bool CheckAgainstThisTileType(MatchTileType otherTile)
		{
			return false;
		}

		public override void OnTilePointerUp(MatchTile tile)
		{
		}

		public override void OnTileDrag(PointerEventData eventData)
		{
		}

		protected virtual void BreakThisTile()
		{
			_matchTile.Break();
			base.matchGrid.FillEmptyTiles();
		}
	}
	public class InteractableTileBomb : InteractableTileBehavior
	{
		public MatchTileType tileToDestroy;

		[SerializeField]
		private Image bombTarget;

		private float _randomizeInterval = 0.5f;

		private float _randomizeTim = 0.5f;

		private int _tileTargetIndex = 0;

		public override void Init(MatchTile matchTile)
		{
			base.Init(matchTile);
			_tileTargetIndex = Random.Range(0, base.matchGrid.TileTypes.Length);
			IncrementTargetTIle();
		}

		private void FixedUpdate()
		{
			_randomizeTim -= Time.fixedDeltaTime;
			if (_randomizeTim < 0f)
			{
				_randomizeTim = _randomizeInterval;
				IncrementTargetTIle();
			}
		}

		private void IncrementTargetTIle()
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			_tileTargetIndex++;
			_tileTargetIndex %= base.matchGrid.TileTypes.Length;
			tileToDestroy = base.matchGrid.TileTypes[_tileTargetIndex];
			((Graphic)bombTarget).color = tileToDestroy.GetColor();
			bombTarget.sprite = tileToDestroy.GetIcon();
		}

		protected override void Activate()
		{
			BreakThisTile();
			for (int i = 0; i < base.matchGrid.TileGrid.GetLength(0); i++)
			{
				for (int j = 0; j < base.matchGrid.TileGrid.GetLength(1); j++)
				{
					if ((Object)(object)base.matchGrid.TileGrid[i, j] != (Object)null && base.matchGrid.TileGrid[i, j].TileType == tileToDestroy)
					{
						base.matchGrid.Award(base.matchGrid.TileGrid[i, j].TileType, 1, 1);
						base.matchGrid.TileGrid[i, j].Break();
					}
				}
			}
			base.matchGrid.FillEmptyTiles();
			base.matchGrid.DelayedProcessAllGridMatches(0.5f);
		}
	}
	public class InteractableTileTimeStop : InteractableTileBehavior
	{
		protected override void Activate()
		{
			BreakThisTile();
			base.matchGrid.StopTime();
		}
	}
	public class MatchGrid : MonoBehaviour
	{
		public delegate void MatchAwardedEvent(MatchTileType matchType, int matchCount, int tilesMatched);

		public MatchAwardedEvent OnMatchAwarded;

		[SerializeField]
		private UISelectOnHover UISelectOnHover;

		[SerializeField]
		private MatchTile tilePrefab;

		[SerializeField]
		private Vector2Int gridSize;

		[SerializeField]
		private Vector2 tileDistance;

		[SerializeField]
		private RectTransform anchor;

		[SerializeField]
		private float minimumSwapDistance;

		[SerializeField]
		private float breakTime = 0.3f;

		[SerializeField]
		private float fallTime = 0.3f;

		private MatchTileType[] _tileTypes;

		private SpecialTileInfo[] _specialTileTypes;

		private Vector3 _gridStartLocalPosition;

		private MatchTile[,] _tileGrid = new MatchTile[0, 0];

		private MatchTile[,] _tempTileGrid = new MatchTile[0, 0];

		private MatchTile _ghostTileHead;

		private MatchTile _ghostTileTail;

		private Vector2Int _selectedGridPosition;

		private Vector2 _pointerDownPosition;

		private bool _awaitingDrag;

		private Vector2Int _awaitingGridPosition;

		private Vector2 _awaitingPointerDownPosition;

		private TileDragLineup _selectedDragRow;

		private TileDragLineup _selectedDragCol;

		private TileDragLineup _currentDragLineup;

		private DragDirection _dragDirection;

		private bool _isDragging;

		private IEnumerator _manualCoroutine;

		private float _manualWait;

		private float _timeStoppedTime;

		public Action<float> timeStopAction;

		public Vector2Int GridSize => gridSize;

		public Vector2 TileDistance => tileDistance;

		public MatchTileType[] TileTypes => _tileTypes;

		public MatchTile[,] TileGrid => _tileGrid;

		private TileDragLineup curentDragLineup
		{
			get
			{
				return _currentDragLineup;
			}
			set
			{
				if (_currentDragLineup != value)
				{
					_manualCoroutine = OnDraggedLineChanged(_currentDragLineup, value);
					_currentDragLineup = value;
				}
			}
		}

		public bool CanInteract => _manualCoroutine == null && !_isDragging;

		private bool isTimeStopped => _timeStoppedTime > 0f;

		private void FixedUpdate()
		{
			_manualWait -= Time.fixedDeltaTime;
			if (_manualCoroutine != null)
			{
				_manualCoroutine.MoveNext();
			}
			if (!(_timeStoppedTime > 0f))
			{
				return;
			}
			_timeStoppedTime -= Time.fixedDeltaTime;
			if (_timeStoppedTime < 0f)
			{
				if (_isDragging)
				{
					CancelDragging();
				}
				else
				{
					_manualCoroutine = ProcessAllGridMatches();
				}
			}
		}

		public void CompleteCoroutine()
		{
			if (_manualCoroutine != null)
			{
				while (_manualCoroutine.MoveNext())
				{
					_manualWait = -1f;
				}
				_manualCoroutine = null;
			}
		}

		public void Init(MatchTileType[] tileTypes_, SpecialTileInfo[] specialTileTypes_)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			Init(tileTypes_, specialTileTypes_, gridSize);
		}

		public void Init(MatchTileType[] tileTypes_, SpecialTileInfo[] specialTileTypes_, Vector2Int gridSize_)
		{
			//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)
			_tileTypes = tileTypes_;
			_specialTileTypes = specialTileTypes_;
			gridSize = gridSize_;
			ReGenerateGrid();
			if ((Object)(object)_ghostTileHead == (Object)null)
			{
				_ghostTileHead = Object.Instantiate<MatchTile>(tilePrefab, (Transform)(object)anchor);
				((Component)_ghostTileHead).gameObject.SetActive(false);
			}
			if ((Object)(object)_ghostTileTail == (Object)null)
			{
				_ghostTileTail = Object.Instantiate<MatchTile>(tilePrefab, (Transform)(object)anchor);
				((Component)_ghostTileTail).gameObject.SetActive(false);
			}
		}

		private void ReGenerateGrid()
		{
			for (int i = 0; i < _tileGrid.GetLength(0); i++)
			{
				for (int j = 0; j < _tileGrid.GetLength(1); j++)
				{
					MatchTile matchTile = _tileGrid[i, j];
					if ((Object)(object)matchTile != (Object)null)
					{
						Object.Destroy((Object)(object)((Component)matchTile).gameObject);
					}
					else
					{
						Log.Warning($"null at {i}, {j} {Environment.StackTrace}");
					}
				}
			}
			GenerateGrid();
		}

		private void GenerateGrid()
		{
			//IL_0008: 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_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_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: 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_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			anchor.sizeDelta = Vector2.Scale(tileDistance, gridSize.ToVector2());
			_tileGrid = new MatchTile[((Vector2Int)(ref gridSize)).x, ((Vector2Int)(ref gridSize)).y];
			_tempTileGrid = new MatchTile[((Vector2Int)(ref gridSize)).x, ((Vector2Int)(ref gridSize)).y];
			Vector3 val = Vector3.Scale(tileDistance.ToVector3() * 0.5f, (gridSize - Vector2Int.one).ToVector3());
			_gridStartLocalPosition = -val;
			FillEmptyTiles();
			_manualCoroutine = DelayedProcessMatches(0.6f);
		}

		private IEnumerator DelayedProcessMatches(float delay)
		{
			_manualWait = delay;
			while (_manualWait > 0f)
			{
				yield return null;
			}
			_manualCoroutine = ProcessAllGridMatches();
		}

		private IEnumerator ProcessAllGridMatches()
		{
			Log.Debug("processing matches");
			int failsafe = 0;
			int chain = 0;
			List<MatchInfo> matches;
			do
			{
				if (_awaitingDrag)
				{
					StartDragging();
					break;
				}
				matches = new List<MatchInfo>();
				matches.AddRange(FindAllGridmatches());
				chain += matches.Count;
				IEnumerator enumerator = ProcessMatches(matches);
				while (enumerator.MoveNext())
				{
					yield return null;
				}
				Util.FAILSAFE(ref failsafe);
			}
			while (matches.Count > 0);
			Log.Debug($"match chain {chain}");
			_manualCoroutine = null;
		}

		private List<MatchInfo> FindAllGridmatches()
		{
			List<MatchInfo> list = new List<MatchInfo>();
			for (int i = 0; i < ((Vector2Int)(ref gridSize)).x; i++)
			{
				for (int j = 0; j < ((Vector2Int)(ref gridSize)).y; j++)
				{
					if ((Object)(object)_tileGrid[i, j] == (Object)null)
					{
						Log.Error($"checking for match and tile at {i}, {j} was null. is this fine?\n" + Environment.StackTrace);
					}
					CheckForMatches(_tileGrid[i, j], list);
				}
			}
			return list;
		}

		private MatchTile GenerateRandomTile(int gridX, int gridY)
		{
			//IL_00c9: 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)
			List<float> list = new List<float>();
			for (int i = 0; i < _specialTileTypes.Length; i++)
			{
				list.Add(_specialTileTypes[i].SpawnChance);
			}
			MatchTile matchTile;
			if (_specialTileTypes.Length == 0 || Random.value > list.Sum())
			{
				matchTile = Object.Instantiate<MatchTile>(tilePrefab, (Transform)(object)anchor);
				((Component)matchTile).transform.localPosition = GridToWorldPosition(gridX, gridY);
				matchTile.Init(this, _tileTypes[Random.Range(0, _tileTypes.Length)], gridX, gridY);
			}
			else
			{
				SpecialTileInfo specialTileInfo = _specialTileTypes[Util.WeightedRandom(list)];
				matchTile = Object.Instantiate<MatchTile>(specialTileInfo.tilePrefab, (Transform)(object)anchor);
				((Component)matchTile).transform.localPosition = GridToWorldPosition(gridX, gridY);
				matchTile.Init(this, null, gridX, gridY);
			}
			return matchTile;
		}

		private Vector3 GridToWorldPosition(Vector2Int gridPoint)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			return GridToWorldPosition(((Vector2Int)(ref gridPoint)).x, ((Vector2Int)(ref gridPoint)).y);
		}

		private Vector3 GridToWorldPosition(int gridX, int gridY)
		{
			//IL_0002: 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_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)
			return _gridStartLocalPosition + new Vector3((float)gridX * tileDistance.x, (float)gridY * tileDistance.y, 0f);
		}

		private IEnumerator OnDraggedLineChanged(TileDragLineup oldLineup_, TileDragLineup newLineup_)
		{
			if (oldLineup_ != null && newLineup_ != null)
			{
				oldLineup_.ResetTiles();
			}
			if (newLineup_ == null)
			{
				for (int i = 0; i < oldLineup_.Count; i++)
				{
					TempMoveTile(oldLineup_[i].currentGridPosition, oldLineup_[i].tile);
				}
				List<MatchInfo> matches = new List<MatchInfo>();
				for (int j = 0; j < oldLineup_.Count; j++)
				{
					MatchTileDragInfo matchTileDragInfo = oldLineup_[j];
					CheckForMatches(matchTileDragInfo, matches);
					List<MatchTile> tileLine = ((_dragDirection == DragDirection.VERTICAL) ? GetGridRow(((Vector2Int)(ref matchTileDragInfo.currentGridPosition)).y) : GetGridColumn(((Vector2Int)(ref matchTileDragInfo.currentGridPosition)).x));
					for (int l = 0; l < tileLine.Count; l++)
					{
						if (!(tileLine[l].GridPosition == matchTileDragInfo.currentGridPosition))
						{
							CheckForMatches(tileLine[l], matches);
						}
					}
				}
				ClearTempGrid();
				if (matches.Count > 0 || isTimeStopped)
				{
					for (int k = 0; k < oldLineup_.Count; k++)
					{
						MatchTileDragInfo tileInfo = oldLineup_[k];
						Vector2Int newPosition = tileInfo.currentGridPosition;
						SetMoveTile(newPosition, tileInfo.tile, animate: false);
					}
				}
				else
				{
					oldLineup_.ResetTiles();
				}
				if (!isTimeStopped)
				{
					IEnumerator allMatchesCoroutine = ProcessAllGridMatches();
					while (allMatchesCoroutine.MoveNext())
					{
						yield return null;
					}
				}
			}
			_manualCoroutine = null;
		}

		private void ClearTempGrid()
		{
			for (int i = 0; i < ((Vector2Int)(ref gridSize)).x; i++)
			{
				for (int j = 0; j < ((Vector2Int)(ref gridSize)).y; j++)
				{
					_tempTileGrid[i, j] = null;
				}
			}
		}

		private void TempMoveTile(Vector2Int newPosition, MatchTile movingTile)
		{
			_tempTileGrid[((Vector2Int)(ref newPosition)).x, ((Vector2Int)(ref newPosition)).y] = movingTile;
		}

		private void SetMoveTile(Vector2Int newPosition, MatchTile movingTile, bool animate = true)
		{
			//IL_0010: 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_001f: Unknown result type (might be due to invalid IL or missing references)
			if (animate)
			{
				movingTile.OnMove();
			}
			movingTile.GridPosition = newPosition;
			((Component)movingTile).transform.localPosition = GridToWorldPosition(newPosition);
			_tileGrid[((Vector2Int)(ref newPosition)).x, ((Vector2Int)(ref newPosition)).y] = movingTile;
		}

		private IEnumerator ProcessMatches(List<MatchInfo> matches)
		{
			for (int i = 0; i < matches.Count; i++)
			{
				if (Util.IsDebug)
				{
					string log = "";
					for (int j = 0; j < matches[i].tilesMatched.Length; j++)
					{
						string text = log;
						Vector2Int gridPosition = matches[i].tilesMatched[j].GridPosition;
						object arg = ((Vector2Int)(ref gridPosition)).x;
						gridPosition = matches[i].tilesMatched[j].GridPosition;
						log = text + $"({arg}, {((Vector2Int)(ref gridPosition)).y}) ";
					}
				}
				Award(matches[i].matchType, matches[i].GetMatchCount(), matches[i].tilesMatched.Length);
				matches[i].Break();
			}
			if (matches.Count > 0)
			{
				_manualWait = breakTime;
				while (_manualWait > 0f)
				{
					yield return null;
				}
			}
			if (FillEmptyTiles())
			{
				_manualWait = fallTime;
				while (_manualWait > 0f)
				{
					yield return null;
				}
			}
		}

		public bool FillEmptyTiles()
		{
			bool result = false;
			for (int i = 0; i < ((Vector2Int)(ref gridSize)).x; i++)
			{
				for (int num = ((Vector2Int)(ref gridSize)).y - 1; num >= 0; num--)
				{
					List<MatchTile> list = new List<MatchTile>();
					if ((Object)(object)_tileGrid[i, num] == (Object)null)
					{
						int j = num;
						int num2 = 0;
						for (; j < ((Vector2Int)(ref gridSize)).y; j++)
						{
							if ((Object)(object)_tileGrid[i, j] != (Object)null)
							{
								list.Add(_tileGrid[i, j]);
							}
							else
							{
								num2++;
							}
						}
						result = true;
						DropTiles(i, num + 1, num2, list);
					}
				}
			}
			return result;
		}

		private void DropTiles(int x, int y, int dropAmount, List<MatchTile> droppingTiles)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < dropAmount; i++)
			{
				droppingTiles.Add(GenerateRandomTile(x, ((Vector2Int)(ref gridSize)).y + i));
			}
			for (int j = 0; j < droppingTiles.Count; j++)
			{
				SetMoveTile(droppingTiles[j].GridPosition + Vector2Int.down * dropAmount, droppingTiles[j]);
			}
		}

		public void Award(MatchTileType matchType, int matchCount, int tilesMatched)
		{
			OnMatchAwarded?.Invoke(matchType, matchCount, tilesMatched);
		}

		private void CheckForMatches(MatchTileDragInfo matchTileDragInfo, List<MatchInfo> matches)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			if (CheckForMatch(matchTileDragInfo.tile, matchTileDragInfo.currentGridPosition, DragDirection.VERTICAL, out var foundMatch) && !matches.Contains(foundMatch))
			{
				matches.Add(foundMatch);
			}
			if (CheckForMatch(matchTileDragInfo.tile, matchTileDragInfo.currentGridPosition, DragDirection.HORIZONTAL, out var foundMatch2) && !matches.Contains(foundMatch2))
			{
				matches.Add(foundMatch2);
			}
		}

		private void CheckForMatches(MatchTile tile, List<MatchInfo> matches)
		{
			if (CheckForMatch(tile, DragDirection.VERTICAL, out var foundMatch) && !matches.Contains(foundMatch))
			{
				matches.Add(foundMatch);
			}
			if (CheckForMatch(tile, DragDirection.HORIZONTAL, out var foundMatch2) && !matches.Contains(foundMatch2))
			{
				matches.Add(foundMatch2);
			}
		}

		private bool CheckForMatch(MatchTile tile, DragDirection dragDirection, out MatchInfo foundMatch)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)tile == (Object)null)
			{
				foundMatch = null;
				return false;
			}
			return CheckForMatch(tile, tile.GridPosition, dragDirection, out foundMatch);
		}

		private bool CheckForMatch(MatchTile tile, Vector2Int currentGridPosition, DragDirection dragDirection, out MatchInfo foundMatch)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)tile == (Object)null)
			{
				foundMatch = null;
				return false;
			}
			List<MatchTile> list = AggregateMatches(tile, currentGridPosition, dragDirection);
			if (list.Count >= 3)
			{
				foundMatch = new MatchInfo(list);
				return true;
			}
			foundMatch = null;
			return false;
		}

		private List<MatchTile> AggregateMatches(MatchTile tile, Vector2Int currentGridPosition, DragDirection dragDirection)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: 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_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0085: Unknown result type (might be due to invalid IL or missing references)
			List<MatchTile> list = new List<MatchTile> { tile };
			List<Vector2Int> checkedTilePositions = new List<Vector2Int> { currentGridPosition };
			Queue<Vector2Int> queue = new Queue<Vector2Int>();
			queue.Enqueue(currentGridPosition);
			MatchTileType tile2 = tile.TileType;
			int count = 0;
			while (queue.Count > 0 && !Util.FAILSAFE(ref count))
			{
				Vector2Int val = queue.Dequeue();
				if (dragDirection == DragDirection.HORIZONTAL)
				{
					CheckTile(list, queue, checkedTilePositions, ref tile2, val + Vector2Int.up);
					CheckTile(list, queue, checkedTilePositions, ref tile2, val + Vector2Int.down);
				}
				else
				{
					CheckTile(list, queue, checkedTilePositions, ref tile2, val + Vector2Int.left);
					CheckTile(list, queue, checkedTilePositions, ref tile2, val + Vector2Int.right);
				}
			}
			return list;
		}

		private void CheckTile(List<MatchTile> matchedTiles, Queue<Vector2Int> tileCheckQueue, List<Vector2Int> checkedTilePositions, ref MatchTileType tile, Vector2Int checkTilePosition)
		{
			//IL_0002: 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_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			if (!checkedTilePositions.Contains(checkTilePosition) && ((Vector2Int)(ref checkTilePosition)).x >= 0 && ((Vector2Int)(ref checkTilePosition)).x < ((Vector2Int)(ref gridSize)).x && ((Vector2Int)(ref checkTilePosition)).y >= 0 && ((Vector2Int)(ref checkTilePosition)).y < ((Vector2Int)(ref gridSize)).y)
			{
				MatchTile gridTileToCheck = GetGridTileToCheck(checkTilePosition);
				if ((Object)(object)gridTileToCheck != (Object)null && gridTileToCheck.CheckAgainstThisTileType(tile))
				{
					matchedTiles.Add(gridTileToCheck);
					checkedTilePositions.Add(checkTilePosition);
					tileCheckQueue.Enqueue(checkTilePosition);
				}
			}
		}

		private MatchTile GetGridTileToCheck(Vector2Int coordinates)
		{
			return GetGridTileToCheck(((Vector2Int)(ref coordinates)).x, ((Vector2Int)(ref coordinates)).y);
		}

		private MatchTile GetGridTileToCheck(int x, int y)
		{
			if ((Object)(object)_tempTileGrid[x, y] != (Object)null)
			{
				return _tempTileGrid[x, y];
			}
			return _tileGrid[x, y];
		}

		public void TilePointerDown(MatchTile tile, PointerEventData eventData)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			if (!tile.IsMoving)
			{
				AwaitDragging(tile.GridPosition, eventData.position);
				if (_manualCoroutine == null)
				{
					StartDragging();
				}
			}
		}

		private void AwaitDragging(Vector2Int gridPosition, Vector2 position)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//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)
			_awaitingDrag = true;
			_awaitingGridPosition = gridPosition;
			_awaitingPointerDownPosition = position;
		}

		private void StartDragging()
		{
			//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_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			_awaitingDrag = false;
			_isDragging = true;
			_selectedGridPosition = _awaitingGridPosition;
			_pointerDownPosition = _awaitingPointerDownPosition;
			if (!SetSelectedPositionLineups())
			{
				CancelDragging();
			}
		}

		private bool SetSelectedPositionLineups()
		{
			_selectedDragRow = new TileDragLineup(this, _ghostTileHead, _ghostTileTail);
			List<MatchTile> gridRow = GetGridRow(((Vector2Int)(ref _selectedGridPosition)).y);
			for (int i = 0; i < gridRow.Count; i++)
			{
				if ((Object)(object)gridRow[i] == (Object)null)
				{
					return false;
				}
			}
			_selectedDragRow.AddRange(gridRow, this);
			_selectedDragCol = new TileDragLineup(this, _ghostTileHead, _ghostTileTail);
			List<MatchTile> gridColumn = GetGridColumn(((Vector2Int)(ref _selectedGridPosition)).x);
			for (int j = 0; j < gridColumn.Count; j++)
			{
				if ((Object)(object)gridColumn[j] == (Object)null)
				{
					return false;
				}
			}
			_selectedDragCol.AddRange(gridColumn, this);
			return true;
		}

		private List<MatchTile> GetGridRow(int y)
		{
			List<MatchTile> list = new List<MatchTile>();
			for (int i = 0; i < _tileGrid.GetLength(0); i++)
			{
				list.Add(_tileGrid[i, y]);
			}
			return list;
		}

		private List<MatchTile> GetGridColumn(int x)
		{
			List<MatchTile> list = new List<MatchTile>();
			for (int i = 0; i < _tileGrid.GetLength(1); i++)
			{
				list.Add(_tileGrid[x, i]);
			}
			return list;
		}

		public void TilePointerUp(MatchTile tile)
		{
			CancelDragging();
			if (_manualCoroutine == null && !isTimeStopped)
			{
				_manualCoroutine = ProcessAllGridMatches();
			}
		}

		private void CancelDragging()
		{
			_awaitingDrag = false;
			_isDragging = false;
			curentDragLineup = null;
			((Component)_ghostTileHead).gameObject.SetActive(false);
			((Component)_ghostTileTail).gameObject.SetActive(false);
		}

		public void TileDrag(PointerEventData eventData)
		{
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			if (_manualCoroutine != null || !_isDragging)
			{
				return;
			}
			if (_currentDragLineup != null)
			{
				for (int i = 0; i < _currentDragLineup.Count; i++)
				{
					if (_currentDragLineup[i].tile.IsMoving)
					{
						_currentDragLineup.ResetTiles();
						CancelDragging();
						return;
					}
				}
			}
			((Component)_ghostTileHead).gameObject.SetActive(true);
			((Component)_ghostTileTail).gameObject.SetActive(true);
			Vector2 vector = eventData.position - _pointerDownPosition;
			vector = Vector2.op_Implicit(vector.ToVector3());
			if (MathF.Abs(vector.x) < minimumSwapDistance && MathF.Abs(vector.y) < minimumSwapDistance)
			{
				if (MathF.Abs(vector.x) > MathF.Abs(vector.y))
				{
					_dragDirection = DragDirection.HORIZONTAL;
				}
				else
				{
					_dragDirection = DragDirection.VERTICAL;
				}
			}
			Vector2Int deltaGridPosition = default(Vector2Int);
			if (_dragDirection == DragDirection.HORIZONTAL)
			{
				curentDragLineup = _selectedDragRow;
				vector.y = 0f;
				vector.x *= 1920f / (float)Screen.width;
				int num = Mathf.RoundToInt(vector.x / tileDistance.x);
				((Vector2Int)(ref deltaGridPosition))..ctor(num, 0);
			}
			else
			{
				curentDragLineup = _selectedDragCol;
				vector.x = 0f;
				vector.y *= 1080f / (float)Screen.height;
				int num2 = Mathf.RoundToInt(vector.y / tileDistance.y);
				((Vector2Int)(ref deltaGridPosition))..ctor(0, num2);
			}
			curentDragLineup.UpdatePositions(Vector2.op_Implicit(vector), deltaGridPosition);
		}

		public void RemoveTile(MatchTile matchTile)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			MatchTile[,] tileGrid = _tileGrid;
			Vector2Int gridPosition = matchTile.GridPosition;
			int x = ((Vector2Int)(ref gridPosition)).x;
			gridPosition = matchTile.GridPosition;
			tileGrid[x, ((Vector2Int)(ref gridPosition)).y] = null;
		}

		internal void DelayedProcessAllGridMatches(float delay)
		{
			_manualCoroutine = DelayedCoroutine(delay, ProcessAllGridMatches());
		}

		private IEnumerator DelayedCoroutine(float delay, IEnumerator coroutine)
		{
			_manualWait = delay;
			while (_manualWait > 0f)
			{
				yield return null;
			}
			_manualCoroutine = coroutine;
		}

		public void GetSelected()
		{
			UISelectOnHover.SetSelectedGameObject();
		}

		public void StopTime()
		{
			_timeStoppedTime = 3f;
			timeStopAction?.Invoke(3f);
		}
	}
	public class MatchGridInteractables : MonoBehaviour
	{
		[SerializeField]
		private MatchTile[] interactableTileTypes;

		public MatchTile[] InteractableTileTypes => interactableTileTypes;
	}
	public class MatchInfo : IEquatable<MatchInfo>
	{
		public MatchTile[] tilesMatched;

		public MatchTileType matchType => tilesMatched[0].TileType;

		public MatchInfo(List<MatchTile> tilesMatched)
		{
			this.tilesMatched = tilesMatched.ToArray();
		}

		public MatchInfo(params MatchTile[] tilesMatched)
		{
			this.tilesMatched = tilesMatched;
		}

		public int GetMatchCount()
		{
			int baseMatches;
			switch (tilesMatched.Length)
			{
			case 0:
			case 1:
			case 2:
				baseMatches = 0;
				Log.Error($"matched only {tilesMatched.Length} of {matchType}. was this intended?");
				break;
			case 3:
			case 4:
			case 5:
				baseMatches = tilesMatched.Length - 2;
				break;
			default:
				baseMatches = Mathf.RoundToInt((float)(tilesMatched.Length - 3) * 2f);
				break;
			}
			for (int i = 0; i < tilesMatched.Length; i++)
			{
				tilesMatched[i].ApplyMatchModifier(ref baseMatches);
			}
			return baseMatches;
		}

		public void Break()
		{
			for (int i = 0; i < tilesMatched.Length; i++)
			{
				MatchTile matchTile = tilesMatched[i];
				if ((Object)(object)matchTile != (Object)null && !matchTile.Broken)
				{
					matchTile.Break();
				}
			}
		}

		public bool Equals(MatchInfo other)
		{
			if (other.tilesMatched.Length != tilesMatched.Length)
			{
				return false;
			}
			int num = 0;
			for (int i = 0; i < tilesMatched.Length; i++)
			{
				for (int j = 0; j < other.tilesMatched.Length; j++)
				{
					if ((Object)(object)tilesMatched[i] == (Object)(object)other.tilesMatched[j])
					{
						num++;
					}
				}
			}
			return num == tilesMatched.Length;
		}
	}
	public class MatchTile : MonoBehaviour
	{
		[SerializeField]
		private MatchTileTrigger trigger;

		[SerializeField]
		private MatchTileBehavior behavior;

		[SerializeField]
		private Image image;

		[SerializeField]
		private Image flashImage;

		[SerializeField]
		private float moveLerp = 10f;

		private Vector2Int _gridPosition;

		private MatchGrid _matchGrid;

		private Vector3 _moveLerpPosition;

		private IEnumerator _manualCoroutine;

		public Vector2Int GridPosition
		{
			get
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				return _gridPosition;
			}
			set
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				_gridPosition = value;
			}
		}

		public MatchTileType TileType { get; set; }

		public bool Broken { get; internal set; }

		public MatchGrid MatchGrid => _matchGrid;

		public bool IsMoving { get; private set; }

		public virtual void Init(MatchGrid matchGrid, MatchTileType tileType, int x, int y)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			_matchGrid = matchGrid;
			_gridPosition = new Vector2Int(x, y);
			InitTileType(tileType);
			trigger.Init(this);
			behavior.Init(this);
		}

		public void InitTileType(MatchTileType tileType)
		{
			TileType = tileType;
			InitTIleTypeView(tileType);
		}

		private void InitTIleTypeView(MatchTileType tileType)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			if (TileType != null)
			{
				((Graphic)image).color = tileType.GetColor();
				image.sprite = tileType.GetIcon();
			}
		}

		private void Update()
		{
			if (_manualCoroutine != null && !_manualCoroutine.MoveNext())
			{
				_manualCoroutine = null;
			}
		}

		private void OnDestroy()
		{
			IsMoving = false;
		}

		internal void Break()
		{
			//IL_0021: 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)
			Broken = true;
			_matchGrid.RemoveTile(this);
			((Component)image).transform.localScale = Vector3.one * 1.3f;
			_manualCoroutine = DestroyCoroutine();
		}

		private IEnumerator DestroyCoroutine()
		{
			IsMoving = false;
			float destroyTimer = 0.5f;
			while (destroyTimer > 0f)
			{
				destroyTimer -= Time.deltaTime;
				Color color = ((Graphic)image).color;
				color.a = destroyTimer / 0.3f;
				((Graphic)image).color = color;
				yield return null;
			}
			Object.Destroy((Object)(object)((Component)this).gameObject);
		}

		public void OnMove()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			IsMoving = true;
			_moveLerpPosition = ((Component)image).transform.position;
			_manualCoroutine = MoveCoroutine();
		}

		private IEnumerator MoveCoroutine()
		{
			float moveTimer = 0.3f;
			while (moveTimer > 0f)
			{
				moveTimer -= Time.deltaTime;
				_moveLerpPosition = Util.ExpDecayLerp(_moveLerpPosition, ((Component)this).transform.position, moveLerp, Time.deltaTime);
				((Component)image).transform.position = _moveLerpPosition;
				yield return null;
			}
			((Component)image).transform.localPosition = Vector3.zero;
			IsMoving = false;
		}

		public virtual void OnTilePointerDown(MatchTile tile, PointerEventData eventData)
		{
			behavior.OnTilePointerDown(tile, eventData);
		}

		public virtual void OnTilePointerUp(MatchTile tile)
		{
			behavior.OnTilePointerUp(tile);
		}

		public virtual void OnTileDrag(PointerEventData eventData)
		{
			behavior.OnTileDrag(eventData);
		}

		public void Transform(MatchTileType matchTileType)
		{
			InitTileType(matchTileType);
			_manualCoroutine = TransformCoroutine();
		}

		private IEnumerator TransformCoroutine()
		{
			((Graphic)flashImage).color = Color.white;
			((Component)image).transform.localScale = Vector3.one * 1.1f;
			float transformTimer = 0.4f;
			while (transformTimer > 0f)
			{
				transformTimer -= Time.deltaTime;
				((Graphic)flashImage).color = Util.ExpDecayLerp(((Graphic)flashImage).color, Color.clear, 3f, Time.deltaTime);
				((Component)image).transform.localScale = Util.ExpDecayLerp(((Component)image).transform.localScale, Vector3.one, 3f, Time.deltaTime);
				yield return null;
			}
			((Graphic)flashImage).color = Color.clear;
		}

		public bool CheckAgainstThisTile(MatchTile otherTile)
		{
			return behavior.CheckAgainstThisTile(otherTile);
		}

		public bool CheckAgainstThisTileType(MatchTileType otherTile)
		{
			return behavior.CheckAgainstThisTileType(otherTile);
		}

		internal void ApplyMatchModifier(ref int baseMatches)
		{
			behavior.ApplyMatchModifier(ref baseMatches);
		}
	}
	public class MatchTileBehavior : MonoBehaviour
	{
		protected MatchTile _matchTile;

		protected MatchGrid matchGrid => _matchTile.MatchGrid;

		public virtual void Init(MatchTile matchTile)
		{
			_matchTile = matchTile;
		}

		public virtual void OnTilePointerDown(MatchTile tile, PointerEventData eventData)
		{
			matchGrid.GetSelected();
			matchGrid.TilePointerDown(tile, eventData);
		}

		public virtual void OnTilePointerUp(MatchTile tile)
		{
			matchGrid.TilePointerUp(tile);
		}

		public virtual void OnTileDrag(PointerEventData eventData)
		{
			matchGrid.TileDrag(eventData);
		}

		public virtual bool CheckAgainstThisTile(MatchTile otherTile)
		{
			return otherTile.TileType == _matchTile.TileType;
		}

		public virtual bool CheckAgainstThisTileType(MatchTileType otherTile)
		{
			return otherTile == _matchTile.TileType;
		}

		public virtual void ApplyMatchModifier(ref int baseMatches)
		{
		}
	}
	public class MatchTileDragInfo
	{
		public MatchTile tile;

		private MatchGrid grid;

		private Vector3 initialPosition;

		private Vector2Int initialGridPosition;

		public Vector2Int currentGridPosition;

		public MatchTileDragInfo(MatchTile tile, MatchGrid grid)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			this.tile = tile;
			this.grid = grid;
			initialGridPosition = tile.GridPosition;
			initialPosition = ((Component)tile).transform.localPosition;
		}

		public void ResetTile()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			((Component)tile).transform.localPosition = initialPosition;
			currentGridPosition = initialGridPosition;
		}

		public bool UpdatePosition(Vector3 delta, Vector2Int deltaGridPosition)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: 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_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			//IL_021a: Unknown result type (might be due to invalid IL or missing references)
			//IL_021b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0220: Unknown result type (might be due to invalid IL or missing references)
			//IL_0221: Unknown result type (might be due to invalid IL or missing references)
			bool result = false;
			currentGridPosition = initialGridPosition + deltaGridPosition;
			Vector3 zero = Vector3.zero;
			Vector2Int gridSize;
			while (true)
			{
				int x = ((Vector2Int)(ref currentGridPosition)).x;
				gridSize = grid.GridSize;
				if (x >= ((Vector2Int)(ref gridSize)).x)
				{
					ref Vector2Int reference = ref currentGridPosition;
					int x2 = ((Vector2Int)(ref reference)).x;
					gridSize = grid.GridSize;
					((Vector2Int)(ref reference)).x = x2 - ((Vector2Int)(ref gridSize)).x;
					ref float x3 = ref zero.x;
					float num = x3;
					gridSize = grid.GridSize;
					x3 = num - (float)((Vector2Int)(ref gridSize)).x * grid.TileDistance.x;
					result = true;
					continue;
				}
				break;
			}
			while (((Vector2Int)(ref currentGridPosition)).x < 0)
			{
				ref Vector2Int reference2 = ref currentGridPosition;
				int x4 = ((Vector2Int)(ref reference2)).x;
				gridSize = grid.GridSize;
				((Vector2Int)(ref reference2)).x = x4 + ((Vector2Int)(ref gridSize)).x;
				ref float x5 = ref zero.x;
				float num2 = x5;
				gridSize = grid.GridSize;
				x5 = num2 + (float)((Vector2Int)(ref gridSize)).x * grid.TileDistance.x;
				result = true;
			}
			while (true)
			{
				int y = ((Vector2Int)(ref currentGridPosition)).y;
				gridSize = grid.GridSize;
				if (y >= ((Vector2Int)(ref gridSize)).y)
				{
					ref Vector2Int reference3 = ref currentGridPosition;
					int y2 = ((Vector2Int)(ref reference3)).y;
					gridSize = grid.GridSize;
					((Vector2Int)(ref reference3)).y = y2 - ((Vector2Int)(ref gridSize)).y;
					ref float y3 = ref zero.y;
					float num3 = y3;
					gridSize = grid.GridSize;
					y3 = num3 - (float)((Vector2Int)(ref gridSize)).y * grid.TileDistance.y;
					result = true;
					continue;
				}
				break;
			}
			while (((Vector2Int)(ref currentGridPosition)).y < 0)
			{
				ref Vector2Int reference4 = ref currentGridPosition;
				int y4 = ((Vector2Int)(ref reference4)).y;
				gridSize = grid.GridSize;
				((Vector2Int)(ref reference4)).y = y4 + ((Vector2Int)(ref gridSize)).y;
				ref float y5 = ref zero.y;
				float num4 = y5;
				gridSize = grid.GridSize;
				y5 = num4 + (float)((Vector2Int)(ref gridSize)).y * grid.TileDistance.y;
				result = true;
			}
			((Component)tile).transform.localPosition = initialPosition + delta + zero;
			return result;
		}
	}
	public class MatchTileTrigger : EventTrigger
	{
		private MatchGrid _matchGrid;

		private MatchTile _tile;

		public void Init(MatchTile tile)
		{
			_tile = tile;
		}

		public override void OnPointerDown(PointerEventData eventData)
		{
			((EventTrigger)this).OnPointerDown(eventData);
			_tile.OnTilePointerDown(_tile, eventData);
		}

		public override void OnPointerUp(PointerEventData eventData)
		{
			((EventTrigger)this).OnPointerUp(eventData);
			_tile.OnTilePointerUp(_tile);
		}

		public override void OnDrag(PointerEventData eventData)
		{
			((EventTrigger)this).OnDrag(eventData);
			_tile.OnTileDrag(eventData);
		}
	}
	public class MatchTileType
	{
		public SkillDef skillDef;

		public MatchTileType(SkillDef skillDef)
		{
			this.skillDef = skillDef;
		}

		internal Color GetColor()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			return Color.white;
		}

		internal Sprite GetIcon()
		{
			return skillDef.icon;
		}
	}
	public class MultiplierMatchTileBehavior : MatchTileBehavior
	{
		[SerializeField]
		private int matchMultiplier;

		public override void Init(MatchTile matchTile)
		{
			base.Init(matchTile);
			matchTile.InitTileType(matchTile.MatchGrid.TileTypes[Random.Range(0, matchTile.MatchGrid.TileTypes.Length - 1)]);
		}

		public override void ApplyMatchModifier(ref int baseMatches)
		{
			baseMatches *= matchMultiplier;
		}
	}
	[Serializable]
	public class SpecialTileInfo
	{
		public MatchTile tilePrefab;

		public ItemDef itemDef;

		public ConfigEntry<float> spawnChance;

		public float SpawnChance => (float)spawnChance / 100f;

		public SpecialTileInfo(MatchTile tilePrefab, ItemDef itemDef, ConfigEntry<float> spawnChance)
		{
			this.tilePrefab = tilePrefab;
			this.itemDef = itemDef;
			this.spawnChance = spawnChance;
		}
	}
	public class TileDragLineup : List<MatchTileDragInfo>
	{
		public MatchTile ghostTileTail;

		public MatchTile ghostTileHead;

		private MatchGrid grid;

		private MatchTile _tailTile;

		private MatchTile _headTile;

		private Vector3 _ghostTileOFfset;

		private bool orderDirty = true;

		public TileDragLineup(MatchGrid grid, MatchTile ghostTileHead, MatchTile ghostTileTail)
		{
			this.ghostTileHead = ghostTileHead;
			this.ghostTileTail = ghostTileTail;
			this.grid = grid;
		}

		public void ResetTiles()
		{
			for (int i = 0; i < base.Count; i++)
			{
				base[i].ResetTile();
			}
		}

		public void UpdatePositions(Vector3 delta, Vector2Int deltaGridPosition)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_0225: Unknown result type (might be due to invalid IL or missing references)
			//IL_022b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0230: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: 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_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: 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_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < base.Count; i++)
			{
				orderDirty |= base[i].UpdatePosition(delta, deltaGridPosition);
			}
			if (orderDirty)
			{
				orderDirty = false;
				Sort((MatchTileDragInfo tile1, MatchTileDragInfo tile2) => (((Vector2Int)(ref tile1.currentGridPosition)).sqrMagnitude > ((Vector2Int)(ref tile2.currentGridPosition)).sqrMagnitude) ? 1 : (-1));
				if (delta.x > 0f)
				{
					SetGhostTiles(base[base.Count - 1].tile, base[0].tile);
					_ghostTileOFfset = Vector3.right * grid.TileDistance.x;
				}
				if (delta.x < 0f)
				{
					SetGhostTiles(base[0].tile, base[base.Count - 1].tile);
					_ghostTileOFfset = -Vector3.right * grid.TileDistance.x;
				}
				if (delta.y > 0f)
				{
					SetGhostTiles(base[base.Count - 1].tile, base[0].tile);
					_ghostTileOFfset = Vector3.up * grid.TileDistance.y;
				}
				if (delta.y < 0f)
				{
					SetGhostTiles(base[0].tile, base[base.Count - 1].tile);
					_ghostTileOFfset = -Vector3.up * grid.TileDistance.y;
				}
			}
			((Component)ghostTileHead).transform.localPosition = ((Component)_headTile).transform.localPosition + _ghostTileOFfset;
			((Component)ghostTileTail).transform.localPosition = ((Component)_tailTile).transform.localPosition - _ghostTileOFfset;
		}

		internal void AddRange(List<MatchTile> matchTiles, MatchGrid matchGrid)
		{
			for (int i = 0; i < matchTiles.Count; i++)
			{
				Add(new MatchTileDragInfo(matchTiles[i], matchGrid));
			}
		}

		private void SetGhostTiles(MatchTile headTile, MatchTile tailTile)
		{
			ghostTileTail.InitTileType(headTile.TileType);
			ghostTileHead.InitTileType(tailTile.TileType);
			_tailTile = tailTile;
			_headTile = headTile;
		}
	}
	public class TileView : MonoBehaviour
	{
		[SerializeField]
		private Transform anchor;

		[SerializeField]
		private Transform lerped;

		[SerializeField]
		private float lerpSpeed = 10f;

		private Vector3 _lastPosition;

		private void Awake()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			_lastPosition = anchor.position;
		}

		private void Update()
		{
			//IL_0003: 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_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_0034: Unknown result type (might be due to invalid IL or missing references)
			_lastPosition = Util.ExpDecayLerp(_lastPosition, anchor.position, lerpSpeed, Time.deltaTime);
			((Component)lerped).transform.position = _lastPosition;
		}
	}
	public class UISelectOnHover : EventTrigger
	{
		private MPEventSystemLocator _eventSystemLocator;

		private void Awake()
		{
			_eventSystemLocator = ((Component)this).GetComponent<MPEventSystemLocator>();
		}

		public override void OnPointerEnter(PointerEventData eventData)
		{
			((EventTrigger)this).OnPointerEnter(eventData);
			SetSelectedGameObject();
		}

		public void SetSelectedGameObject()
		{
			MPEventSystem eventSystem = _eventSystemLocator.eventSystem;
			if (eventSystem != null)
			{
				((EventSystem)eventSystem).SetSelectedGameObject(((Component)this).gameObject);
			}
		}
	}
	public class WildMatchTileBehavior : MatchTileBehavior
	{
		public override void Init(MatchTile matchTile)
		{
			base.Init(matchTile);
		}

		public override bool CheckAgainstThisTile(MatchTile otherTile)
		{
			return true;
		}

		public override bool CheckAgainstThisTileType(MatchTileType otherTile)
		{
			return true;
		}
	}
}
namespace MatcherMod
{
	internal static class Log
	{
		private static ManualLogSource _logSource;

		public static DateTime _startTime = default(DateTime);

		private static string timesLog = "";

		private static string funnyLog = "";

		internal static void Init(ManualLogSource logSource)
		{
			_logSource = logSource;
		}

		internal static void Debug(object data)
		{
			_logSource.LogDebug(data);
		}

		internal static void Error(object data)
		{
			_logSource.LogError(data);
		}

		internal static void ErrorAssetBundle(string assetName, string bundleName)
		{
			Error("failed to load asset, " + assetName + ", because it does not exist in asset bundle, " + bundleName);
		}

		internal static void Fatal(object data)
		{
			_logSource.LogFatal(data);
		}

		internal static void Info(object data)
		{
			_logSource.LogInfo(data);
		}

		internal static void Message(object data)
		{
			_logSource.LogMessage(data);
		}

		internal static void Warning(object data)
		{
			_logSource.LogWarning(data);
		}

		internal static bool CheckNullAndWarn(string name, object objecte)
		{
			Warning($"{name} is {objecte != null}");
			return objecte != null;
		}

		internal static void WarningDebug(string format, params object[] data)
		{
			DebugWarning(format, data);
		}

		internal static void DebugWarning(string format, params object[] data)
		{
			bool flag = false;
		}

		internal static void CurrentTime(string funny)
		{
			bool flag = false;
		}

		internal static void AllTimes()
		{
			if (!string.IsNullOrEmpty(timesLog))
			{
				Warning(timesLog);
				Warning(funnyLog);
			}
		}
	}
	[BepInPlugin("com.TheTimesweeper.MatchMaker", "MatchMaker", "0.3.0")]
	public class MatcherPlugin : BaseUnityPlugin
	{
		public const string MODUID = "com.TheTimesweeper.MatchMaker";

		public const string MODNAME = "MatchMaker";

		public const string MODVERSION = "0.3.0";

		public const string DEVELOPER_PREFIX = "HABIBI";

		public static MatcherPlugin instance;

		private void Awake()
		{
			instance = this;
			Log.Init(((BaseUnityPlugin)this).Logger);
			Materials.Init();
			Language.Init();
			new MatcherSurvivor().Initialize();
			new ContentPacks().Initialize();
		}
	}
}
namespace MatcherMod.Modules
{
	internal static class Asset
	{
		internal static Dictionary<string, AssetBundle> loadedBundles = new Dictionary<string, AssetBundle>();

		internal static Dictionary<string, Action<AssetBundle>> loadingBundles = new Dictionary<string, Action<AssetBundle>>();

		internal static AssetBundle LoadAssetBundle(string bundleName)
		{
			AssetBundle result = null;
			try
			{
				result = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)MatcherPlugin.instance).Info.Location), "AssetBundles", bundleName));
			}
			catch (Exception arg)
			{
				Log.Error($"Error loading asset bundle, {bundleName}. Your asset bundle must be in a folder next to your mod dll called 'AssetBundles'. Follow the guide to build and install your mod correctly!\n{arg}");
			}
			return result;
		}

		internal static void LoadAssetBundleAsync(string bundleName, Action<AssetBundle> onComplete)
		{
			if (bundleName == "myassetbundle")
			{
				Log.Error("AssetBundle name hasn't been changed. not loading any assets to avoid conflicts. Everything will now break.\nMake sure to rename your assetbundle filename and rename the AssetBundleName field in your character setup code.");
			}
			if (loadedBundles.ContainsKey(bundleName))
			{
				onComplete(loadedBundles[bundleName]);
				return;
			}
			if (loadingBundles.ContainsKey(bundleName))
			{
				Dictionary<string, Action<AssetBundle>> dictionary = loadingBundles;
				string key = bundleName;
				dictionary[key] = (Action<AssetBundle>)Delegate.Combine(dictionary[key], onComplete);
				return;
			}
			loadingBundles[bundleName] = onComplete;
			string path = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)MatcherPlugin.instance).Info.Location), "AssetBundles", bundleName);
			Action<AssetBundle> onComplete2 = delegate(AssetBundle bundle)
			{
				loadedBundles[bundleName] = bundle;
				if (loadingBundles.ContainsKey(bundleName))
				{
					loadingBundles[bundleName]?.Invoke(bundle);
					loadingBundles.Remove(bundleName);
				}
			};
			ContentPacks.asyncLoadCoroutines.Add(LoadAssetBundleFromPathAsync(path, onComplete2));
		}

		internal static IEnumerator LoadAssetBundleFromPathAsync(string path, Action<AssetBundle> onComplete)
		{
			AssetBundleCreateRequest request = AssetBundle.LoadFromFileAsync(path);
			while (!((AsyncOperation)request).isDone)
			{
				yield return null;
			}
			onComplete?.Invoke(request.assetBundle);
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		private static void RunShaderSwaper(AssetBundleCreateRequest request)
		{
			ContentPacks.asyncLoadCoroutines.Add(ShaderSwapper.UpgradeStubbedShadersAsync(request.assetBundle));
		}

		internal static void LoadAssetAsync<T>(this AssetBundle assetBundle, string name, Action<T> onComplete) where T : Object
		{
			ContentPacks.asyncLoadCoroutines.Add(assetBundle.LoadAssetCoroutine(name, onComplete));
		}

		internal static void LoadAssetAsync<T>(string Path, Action<T> onComplete) where T : Object
		{
			ContentPacks.asyncLoadCoroutines.Add(LoadAssetCoroutine(Path, onComplete));
		}

		internal static AsyncAsset<T> AddAsyncAsset<T>(this AssetBundle assetBundle, string name, Action<T> onComplete = null) where T : Object
		{
			return new AsyncAsset<T>(assetBundle, name, onComplete).AddCoroutine();
		}

		internal static AsyncAsset<T> AddAsyncAsset<T>(string path, Action<T> onComplete = null) where T : Object
		{
			return new AsyncAsset<T>(path, onComplete).AddCoroutine();
		}

		internal static IEnumerator LoadAssetCoroutine<T>(this AssetBundle assetBundle, string name, Action<T> onComplete) where T : Object
		{
			AssetBundleRequest request = assetBundle.LoadAssetAsync<T>(name);
			while (!((AsyncOperation)request).isDone)
			{
				yield return null;
			}
			onComplete?.Invoke((T)(object)/*isinst with value type is only supported in some contexts*/);
		}

		internal static IEnumerator LoadAssetCoroutine<T>(object key, Action<T> OnComplete) where T : Object
		{
			AsyncOperationHandle<T> loadAsset = Addressables.LoadAssetAsync<T>(key);
			while (!loadAsset.IsDone)
			{
				yield return null;
			}
			OnComplete?.Invoke(loadAsset.Result);
		}

		internal static void LoadAssetsAsync<T1>(AsyncAsset<T1> load1, Action<T1> onComplete) where T1 : Object
		{
			ContentPacks.asyncLoadCoroutines.Add(LoadAssetsAsyncCoroutine(load1, onComplete));
		}

		internal static IEnumerator LoadAssetsAsyncCoroutine<T1>(AsyncAsset<T1> load1, Action<T1> onComplete) where T1 : Object
		{
			while (!load1.coroutine.MoveNext())
			{
				yield return null;
			}
			onComplete(load1.result);
		}

		internal static void LoadAssetsAsync<T1, T2>(AsyncAsset<T1> load1, AsyncAsset<T2> load2, Action<T1, T2> onComplete) where T1 : Object where T2 : Object
		{
			ContentPacks.asyncLoadCoroutines.Add(LoadAssetsAsyncCoroutine(load1, load2, onComplete));
		}

		internal static IEnumerator LoadAssetsAsyncCoroutine<T1, T2>(AsyncAsset<T1> load1, AsyncAsset<T2> load2, Action<T1, T2> onComplete) where T1 : Object where T2 : Object
		{
			while (!load1.coroutine.MoveNext())
			{
				yield return null;
			}
			while (!load2.coroutine.MoveNext())
			{
				yield return null;
			}
			onComplete(load1.result, load2.result);
		}

		internal static void LoadAssetsAsync<T1, T2, T3>(AsyncAsset<T1> load1, AsyncAsset<T2> load2, AsyncAsset<T3> load3, Action<T1, T2, T3> onComplete) where T1 : Object where T2 : Object where T3 : Object
		{
			ContentPacks.asyncLoadCoroutines.Add(LoadAssetsAsyncCoroutine(load1, load2, load3, onComplete));
		}

		internal static IEnumerator LoadAssetsAsyncCoroutine<T1, T2, T3>(AsyncAsset<T1> load1, AsyncAsset<T2> load2, AsyncAsset<T3> load3, Action<T1, T2, T3> onComplete) where T1 : Object where T2 : Object where T3 : Object
		{
			while (!load1.coroutine.MoveNext())
			{
				yield return null;
			}
			while (!load2.coroutine.MoveNext())
			{
				yield return null;
			}
			while (!load3.coroutine.MoveNext())
			{
				yield return null;
			}
			onComplete(load1.result, load2.result, load3.result);
		}

		internal static void LoadAssetsAsync<T1, T2, T3, T4>(AsyncAsset<T1> load1, AsyncAsset<T2> load2, AsyncAsset<T3> load3, AsyncAsset<T4> load4, Action<T1, T2, T3, T4> onComplete) where T1 : Object where T2 : Object where T3 : Object where T4 : Object
		{
			ContentPacks.asyncLoadCoroutines.Add(LoadAssetsAsyncCoroutine(load1, load2, load3, load4, onComplete));
		}

		internal static IEnumerator LoadAssetsAsyncCoroutine<T1, T2, T3, T4>(AsyncAsset<T1> load1, AsyncAsset<T2> load2, AsyncAsset<T3> load3, AsyncAsset<T4> load4, Action<T1, T2, T3, T4> onComplete) where T1 : Object where T2 : Object where T3 : Object where T4 : Object
		{
			while (!load1.coroutine.MoveNext())
			{
				yield return null;
			}
			while (!load2.coroutine.MoveNext())
			{
				yield return null;
			}
			while (!load3.coroutine.MoveNext())
			{
				yield return null;
			}
			while (!load4.coroutine.MoveNext())
			{
				yield return null;
			}
			onComplete(load1.result, load2.result, load3.result, load4.result);
		}

		internal static IEnumerator LoadFromAddressableOrBundle<T>(AssetBundle assetBundle, string bundlePath, string addressablePath, Action<T> OnComplete) where T : Object
		{
			if (!string.IsNullOrEmpty(bundlePath))
			{
				return assetBundle.LoadAssetCoroutine(bundlePath, OnComplete);
			}
			if (!string.IsNullOrEmpty(addressablePath))
			{
				return LoadAssetCoroutine(addressablePath, OnComplete);
			}
			return null;
		}

		internal static IEnumerator PreLoadAssetsAsync<T>(AssetBundle assetBundle, params string[] paths) where T : Object
		{
			List<IEnumerator> coroutines = PreLoadAssetsAsyncCoroutines<T>(assetBundle, paths);
			for (int i = 0; i < coroutines.Count; i++)
			{
				while (coroutines[i].MoveNext())
				{
					yield return null;
				}
			}
		}

		internal static List<IEnumerator> PreLoadAssetsAsyncCoroutines<T>(AssetBundle assetBundle, params string[] paths) where T : Object
		{
			List<IEnumerator> list = new List<IEnumerator>();
			for (int i = 0; i < paths.Length; i++)
			{
				list.Add(assetBundle.LoadAssetCoroutine<T>(paths[i], null));
			}
			return list;
		}

		internal static IEnumerator LoadBuffIconAsync(BuffDef buffDef, AssetBundle assetBundle, string bundleLoadPath)
		{
			return assetBundle.LoadAssetCoroutine<Sprite>(bundleLoadPath, (Action<Sprite>)delegate(Sprite result)
			{
				buffDef.iconSprite = result;
			});
		}

		internal static IEnumerator LoadBuffIconAsync(BuffDef buffDef, string addressablePath)
		{
			return Asset.LoadAssetCoroutine<Sprite>((object)addressablePath, (Action<Sprite>)delegate(Sprite result)
			{
				buffDef.iconSprite = result;
			});
		}

		public static void RecolorEffects(Color color, GameObject MercSwordSlash)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			ParticleSystemRenderer[] componentsInChildren = MercSwordSlash.GetComponentsInChildren<ParticleSystemRenderer>();
			ParticleSystemRenderer[] array = componentsInChildren;
			foreach (ParticleSystemRenderer val in array)
			{
				((Renderer)val).sharedMaterial = new Material(((Renderer)val).sharedMaterial);
				((Renderer)val).sharedMaterial.SetColor("_MainColor", color);
				((Renderer)val).sharedMaterial.SetColor("_Color", color);
				((Renderer)val).sharedMaterial.SetColor("_TintColor", color);
			}
		}

		internal static GameObject DebugClone(this GameObject gameObject, bool network = false)
		{
			bool flag = false;
			return gameObject;
		}

		internal static GameObject CloneTracer(string originalTracerName, string newTracerName)
		{
			GameObject val = LegacyResourcesAPI.Load<GameObject>("Prefabs/Effects/Tracers/" + originalTracerName);
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			GameObject val2 = PrefabAPI.InstantiateClone(val, newTracerName, true);
			if (!Object.op_Implicit((Object)(object)val2.GetComponent<EffectComponent>()))
			{
				val2.AddComponent<EffectComponent>();
			}
			if (!Object.op_Implicit((Object)(object)val2.GetComponent<VFXAttributes>()))
			{
				val2.AddComponent<VFXAttributes>();
			}
			if (!Object.op_Implicit((Object)(object)val2.GetComponent<NetworkIdentity>()))
			{
				val2.AddComponent<NetworkIdentity>();
			}
			val2.GetComponent<Tracer>().speed = 250f;
			val2.GetComponent<Tracer>().length = 50f;
			Content.CreateAndAddEffectDef(val2);
			return val2;
		}

		internal static void ConvertAllRenderersToHopooShader(GameObject objectToConvert)
		{
			if (Object.op_Implicit((Object)(object)objectToConvert))
			{
				MeshRenderer[] componentsInChildren = objectToConvert.GetComponentsInChildren<MeshRenderer>();
				foreach (MeshRenderer val in componentsInChildren)
				{
					((Renderer)val).sharedMaterial?.ConvertDefaultShaderToHopoo();
				}
				SkinnedMeshRenderer[] componentsInChildren2 = objectToConvert.GetComponentsInChildren<SkinnedMeshRenderer>();
				foreach (SkinnedMeshRenderer val2 in componentsInChildren2)
				{
					((Renderer)val2).sharedMaterial?.ConvertDefaultShaderToHopoo();
				}
			}
		}

		internal static GameObject LoadCrosshair(string crosshairName)
		{
			GameObject val = LegacyResourcesAPI.Load<GameObject>("Prefabs/Crosshair/" + crosshairName + "Crosshair");
			if ((Object)(object)val == (Object)null)
			{
				Log.Error("could not load crosshair with the name " + crosshairName + ". defaulting to Standard");
				return LegacyResourcesAPI.Load<GameObject>("Prefabs/Crosshair/StandardCrosshair");
			}
			return val;
		}

		internal static GameObject LoadEffect(this AssetBundle assetBundle, string resourceName, bool parentToTransform)
		{
			return assetBundle.LoadEffect(resourceName, "", parentToTransform);
		}

		internal static GameObject LoadEffect(this AssetBundle assetBundle, string resourceName, string soundName = "", bool parentToTransform = false)
		{
			GameObject val = assetBundle.LoadAsset<GameObject>(resourceName);
			if (!Object.op_Implicit((Object)(object)val))
			{
				Log.ErrorAssetBundle(resourceName, ((Object)assetBundle).name);
				return null;
			}
			CreateEffectFromObject(val, soundName, parentToTransform);
			return val;
		}

		internal static void CreateEffectFromObject(GameObject newEffect, string soundName, bool parentToTransform)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			newEffect.AddComponent<DestroyOnTimer>().duration = 6f;
			newEffect.AddComponent<NetworkIdentity>();
			if (!Object.op_Implicit((Object)(object)newEffect.GetComponent<VFXAttributes>()))
			{
				newEffect.AddComponent<VFXAttributes>().vfxPriority = (VFXPriority)2;
			}
			EffectComponent component = newEffect.GetComponent<EffectComponent>();
			if (!Object.op_Implicit((Object)(object)component))
			{
				component = newEffect.AddComponent<EffectComponent>();
				component.applyScale = true;
				component.effectIndex = (EffectIndex)(-1);
				component.parentToReferencedTransform = parentToTransform;
				component.positionAtReferencedTransform = true;
				component.soundName = soundName;
			}
			Content.CreateAndAddEffectDef(newEffect);
		}

		internal static GameObject CreateProjectileGhostPrefab(this AssetBundle assetBundle, string ghostName)
		{
			GameObject val = assetBundle.LoadAsset<GameObject>(ghostName);
			if ((Object)(object)val == (Object)null)
			{
				Log.Error("Failed to load ghost prefab " + ghostName);
			}
			if (!Object.op_Implicit((Object)(object)val.GetComponent<NetworkIdentity>()))
			{
				val.AddComponent<NetworkIdentity>();
			}
			if (!Object.op_Implicit((Object)(object)val.GetComponent<ProjectileGhostController>()))
			{
				val.AddComponent<ProjectileGhostController>();
			}
			ConvertAllRenderersToHopooShader(val);
			return val;
		}

		internal static GameObject CloneProjectilePrefab(string prefabName, string newPrefabName)
		{
			return PrefabAPI.InstantiateClone(LegacyResourcesAPI.Load<GameObject>("Prefabs/Projectiles/" + prefabName), newPrefabName);
		}

		internal static GameObject LoadAndAddProjectilePrefab(this AssetBundle assetBundle, string newPrefabName)
		{
			GameObject val = assetBundle.LoadAsset<GameObject>(newPrefabName);
			if ((Object)(object)val == (Object)null)
			{
				Log.ErrorAssetBundle(newPrefabName, ((Object)assetBundle).name);
				return null;
			}
			Content.AddProjectilePrefab(val);
			return val;
		}
	}
	public class AsyncAsset<T> where T : Object
	{
		public T result;

		public bool isDone;

		public IEnumerator coroutine;

		public Action<T> onComplete;

		public static implicit operator T(AsyncAsset<T> asset)
		{
			return asset.result;
		}

		public AsyncAsset(string path_, Action<T> onComplete_ = null)
		{
			onComplete = onComplete_;
			coroutine = Asset.LoadAssetCoroutine<T>(path_, OnCoroutineComplete);
		}

		public AsyncAsset(AssetBundle bundle_, string name_, Action<T> onComplete_ = null)
		{
			onComplete = onComplete_;
			coroutine = bundle_.LoadAssetCoroutine<T>(name_, OnCoroutineComplete);
		}

		public AsyncAsset<T> AddCoroutine()
		{
			ContentPacks.asyncLoadCoroutines.Add(coroutine);
			return this;
		}

		public void OnCoroutineComplete(T loadResult)
		{
			result = loadResult;
			isDone = true;
			onComplete?.Invoke(result);
		}
	}
	internal static class CameraParams
	{
		internal static CharacterCameraParamsData CreateCameraParams(float pivotVerticalOffset, Vector3 idealPosition, float pitch = 70f, float wallCushion = 0.1f, float fov = 0f)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: 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_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: 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_007b: 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_0086: Unknown result type (might be due to invalid IL or missing references)
			CharacterCameraParamsData result = default(CharacterCameraParamsData);
			result.maxPitch = BlendableFloat.op_Implicit(pitch);
			result.minPitch = BlendableFloat.op_Implicit(0f - pitch);
			result.pivotVerticalOffset = BlendableFloat.op_Implicit(pivotVerticalOffset);
			result.idealLocalCameraPos = BlendableVector3.op_Implicit(idealPosition);
			result.wallCushion = BlendableFloat.op_Implicit(wallCushion);
			if (fov != 0f)
			{
				result.fov = new BlendableFloat
				{
					value = fov,
					alpha = 1f
				};
			}
			return result;
		}

		internal static CameraParamsOverrideHandle OverrideCameraParams(CameraTargetParams camParams, CharacterCameraParamsData paramsData, float transitionDuration = 0.5f)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			CameraParamsOverrideRequest val = default(CameraParamsOverrideRequest);
			val.cameraParamsData = paramsData;
			val.priority = 1f;
			CameraParamsOverrideRequest val2 = val;
			return camParams.AddParamsOverride(val2, transitionDuration);
		}
	}
	public class ConfigEntry
	{
	}
	public class ConfigEntry<T> : ConfigEntry
	{
		public ConfigEntry<T> ActualConfigEntry;

		public T DefaultValue;

		public T Value
		{
			get
			{
				if (ActualConfigEntry != null)
				{
					return ActualConfigEntry.Value;
				}
				return DefaultValue;
			}
		}

		public static implicit operator T(ConfigEntry<T> config)
		{
			return config.Value;
		}

		public ConfigEntry(T defaultValue)
		{
			ActualConfigEntry = null;
			DefaultValue = defaultValue;
		}

		public ConfigEntry(ConfigEntry<T> actualConfigEntry, T defaultValue)
		{
			ActualConfigEntry = actualConfigEntry;
			DefaultValue = defaultValue;
		}
	}
	public static class Config
	{
		public static ConfigFile MyConfig = ((BaseUnityPlugin)MatcherPlugin.instance).Config;

		private static List<string> disabledSections = new List<string>();

		private static bool enableAll = true;

		private static bool loadedIcon;

		public static void DisableSection(string section)
		{
			disabledSections.Add(section);
		}

		private static bool SectionDisabled(string section)
		{
			return disabledSections.Contains(section);
		}

		public static void ConfigureBody(CharacterBody bodyComponent, string section, string bodyInfoTitle = "")
		{
			if (string.IsNullOrEmpty(bodyInfoTitle))
			{
				bodyInfoTitle = ((Object)bodyComponent).name;
			}
			bodyComponent.baseMaxHealth = BindAndOptions(section, bodyInfoTitle + " Base Max Health", bodyComponent.baseMaxHealth, 0f, 1000f, "levelMaxHealth will be adjusted accordingly (baseMaxHealth * 0.3)", restartRequired: true).Value;
			bodyComponent.levelMaxHealth = Mathf.Round(bodyComponent.baseMaxHealth * 0.3f);
			bodyComponent.baseRegen = BindAndOptions(section, bodyInfoTitle + " Base Regen", bodyComponent.baseRegen, "levelRegen will be adjusted accordingly (baseRegen * 0.2)", restartRequired: true).Value;
			bodyComponent.levelRegen = bodyComponent.baseRegen * 0.2f;
			bodyComponent.baseArmor = BindAndOptions(section, bodyInfoTitle + " Armor", bodyComponent.baseArmor, "", restartRequired: true).Value;
			bodyComponent.baseDamage = BindAndOptions(section, bodyInfoTitle + " Base Damage", bodyComponent.baseDamage, "pretty much all survivors are 12. If you want to change damage, change damage of the moves instead.\nlevelDamage will be adjusted accordingly (baseDamage * 0.2)", restartRequired: true).Value;
			bodyComponent.levelDamage = bodyComponent.baseDamage * 0.2f;
			bodyComponent.baseJumpCount = BindAndOptions(section, bodyInfoTitle + " Jump Count", bodyComponent.baseJumpCount, "", restartRequired: true).Value;
		}

		public static void ConfigureSkillDef(SkillDef skillDef, string section, string skillTitle, bool cooldown = true, bool maxStock = true, bool rechargeStock = false)
		{
			if (cooldown)
			{
				skillDef.baseRechargeInterval = BindAndOptions(section, skillTitle + " cooldown", skillDef.baseRechargeInterval, 0f, 20f, "", restartRequired: true).Value;
			}
			if (maxStock)
			{
				skillDef.baseMaxStock = BindAndOptions(section, skillTitle + " stocks", skillDef.baseMaxStock, 0f, 100f, "", restartRequired: true).Value;
			}
			if (rechargeStock)
			{
				skillDef.rechargeStock = BindAndOptions(section, skillTitle + " recharge stocks", skillDef.baseMaxStock, 0f, 100f, "", restartRequired: true).Value;
			}
			if (skillDef is MatchBoostedSkillDef)
			{
				MatchBoostedSkillDef matchBoostedSkillDef = skillDef as MatchBoostedSkillDef;
				matchBoostedSkillDef.matchConsumptionCost = BindAndOptions(section, skillTitle + " matchConsumptionCost", matchBoostedSkillDef.matchConsumptionCost, 0f, 20f, "", restartRequired: true).Value;
				matchBoostedSkillDef.matchConsumptionMinimum = BindAndOptions(section, skillTitle + " matchConsumptionMinimum", matchBoostedSkillDef.matchConsumptionMinimum, 0f, 100f, "", restartRequired: true).Value;
				matchBoostedSkillDef.matchMaxConsumptions = BindAndOptions(section, skillTitle + " matchMaxConsumptions", matchBoostedSkillDef.matchMaxConsumptions, 0f, 100f, "", restartRequired: true).Value;
			}
		}

		public static ConfigEntry<bool> CharacterEnableConfig(string section, string characterName, string description = "", bool enabledByDefault = true)
		{
			if (string.IsNullOrEmpty(description))
			{
				description = "Set to false to disable this character and as much of its code and content as possible";
			}
			return BindAndOptions(section, "Enable " + characterName, enabledByDefault, description, restartRequired: true);
		}

		public static ConfigEntry<T> BindAndOptionsSlider<T>(string section, string name, T defaultValue, float min = 0f, float max = 20f, string description = "", bool restartRequired = false)
		{
			return BindAndOptions(section, name, defaultValue, min, max, description, restartRequired);
		}

		public static ConfigEntry<T> BindAndOptions<T>(string section, string name, T defaultValue, string description = "", bool restartRequired = false)
		{
			return BindAndOptions(section, name, defaultValue, 0f, 20f, description, restartRequired);
		}

		public static ConfigEntry<T> BindAndOptions<T>(string section, string name, T defaultValue, float min, float max, string description = "", bool restartRequired = false)
		{
			if (string.IsNullOrEmpty(description))
			{
				description = name;
			}
			description += $"\nDefault: {defaultValue}";
			if (restartRequired)
			{
				description += "\n(restart required)";
			}
			if (!enableAll && SectionDisabled(section))
			{
				return new ConfigEntry<T>(null, defaultValue);
			}
			ConfigEntry<T> val = MyConfig.Bind<T>(section, name, defaultValue, description);
			if (Chainloader.PluginInfos.ContainsKey("com.rune580.riskofoptions"))
			{
				TryRegisterOption<T>(val, min, max, restartRequired);
			}
			return new ConfigEntry<T>(val, defaultValue);
		}

		public static ConfigEntry BindAndOptions(string section, string name, ValueType defaultValue, float min, float max, string description = "", bool restartRequired = false)
		{
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			if (defaultValue is float)
			{
				return BindAndOptions(section, name, (float)(object)defaultValue, min, max, description, restartRequired);
			}
			if (defaultValue is int)
			{
				return BindAndOptions(section, name, (int)(object)defaultValue, min, max, description, restartRequired);
			}
			if (defaultValue is bool)
			{
				return BindAndOptions(section, name, (bool)(object)defaultValue, min, max, description, restartRequired);
			}
			if (defaultValue is KeyboardShortcut)
			{
				return BindAndOptions<KeyboardShortcut>(section, name, (KeyboardShortcut)(object)defaultValue, min, max, description, restartRequired);
			}
			if (defaultValue == null)
			{
				Log.Error($"defaultvalue was null somehow for {section}:{name} {defaultValue}");
			}
			Log.Error($"Configuring a field with unsupported type {defaultValue.GetType()} for {section}:{name}");
			return null;
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		private static void TryRegisterOption<T>(ConfigEntry<T> entry, float min, float max, bool restartRequired)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: 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_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Expected O, but got Unknown
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			//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_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_007b: Expected O, but got Unknown
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Expected O, but got Unknown
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Expected O, but got Unknown
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Expected O, but got Unknown
			if (entry is ConfigEntry<float>)
			{
				ModSettingsManager.AddOption((BaseOption)new SliderOption(entry as ConfigEntry<float>, new SliderConfig
				{
					min = min,
					max = max,
					formatString = "{0:0.00}",
					restartRequired = restartRequired
				}));
			}
			if (entry is ConfigEntry<int>)
			{
				ModSettingsManager.AddOption((BaseOption)new IntSliderOption(entry as ConfigEntry<int>, new IntSliderConfig
				{
					min = (int)min,
					max = (int)max,
					restartRequired = restartRequired
				}));
			}
			if (entry is ConfigEntry<bool>)
			{
				ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(entry as ConfigEntry<bool>, restartRequired));
			}
			if (entry is ConfigEntry<KeyboardShortcut>)
			{
				ModSettingsManager.AddOption((BaseOption)new KeyBindOption(entry as ConfigEntry<KeyboardShortcut>, restartRequired));
			}
			if (!loadedIcon)
			{
				loadedIcon = true;
				try
				{
					ModSettingsManager.SetModIcon(ImgHandler.LoadSpriteFromModFolder("icon.png"));
				}
				catch (Exception ex)
				{
					Log.Error("error adding ROO mod icon\n" + ex);
				}
			}
		}

		public static void InitConfigAttributes(Type typeWithStaticConfigFieldsMakeSureTheyreStatic)
		{
			FieldInfo[] fields = typeWithStaticConfigFieldsMakeSureTheyreStatic.GetFields();
			FieldInfo[] array = fields;
			foreach (FieldInfo fieldInfo in array)
			{
				ConfigureAttribute customAttribute = fieldInfo.GetCustomAttribute<ConfigureAttribute>();
				if (customAttribute != null)
				{
					customAttribute.InitFromField(fieldInfo);
					try
					{
						fieldInfo.SetValue(null, BindAndOptions(customAttribute.section, customAttribute.name, customAttribute.defaultValue, customAttribute.min, customAttribute.max, customAttribute.description, customAttribute.restartRequired));
					}
					catch
					{
						throw new Exception("Error adding config " + customAttribute.section + ": " + customAttribute.name + ".");
					}
				}
			}
		}

		public static bool GetKeyPressed(KeyboardShortcut entry)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			foreach (KeyCode modifier in ((KeyboardShortcut)(ref entry)).Modifiers)
			{
				if (!Input.GetKey(modifier))
				{
					return false;
				}
			}
			return Input.GetKeyDown(((KeyboardShortcut)(ref entry)).MainKey);
		}
	}
	[AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = true)]
	public class ConfigureAttribute : Attribute
	{
		public string name;

		public string description;

		public float min = 0f;

		public float max = 20f;

		public bool restartRequired = false;

		public string section { get; private set; }

		public ValueType defaultValue { get; private set; }

		public ConfigureAttribute(string section, float defaultValue)
		{
			this.section = section;
			this.defaultValue = defaultValue;
		}

		public ConfigureAttribute(string section, int defaultValue)
		{
			this.section = section;
			this.defaultValue = defaultValue;
		}

		public ConfigureAttribute(string section, bool defaultValue)
		{
			this.section = section;
			this.defaultValue = defaultValue;
		}

		public ConfigureAttribute(string section, KeyboardShortcut defaultValue)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			this.section = section;
			this.defaultValue = (ValueType)(object)defaultValue;
		}

		public void InitFromField(FieldInfo fieldInfo)
		{
			if (string.IsNullOrEmpty(name))
			{
				name = fieldInfo.Name;
			}
			if (string.IsNullOrEmpty(description))
			{
				description = name;
			}
		}
	}
	internal class Content
	{
		internal static void AddCharacterBodyPrefab(GameObject bprefab)
		{
			ContentPacks.bodyPrefabs.Add(bprefab);
		}

		internal static void AddMasterPrefab(GameObject prefab)
		{
			ContentPacks.masterPrefabs.Add(prefab);
		}

		internal static void AddProjectilePrefab(GameObject prefab)
		{
			ContentPacks.projectilePrefabs.Add(prefab);
		}

		internal static void NetworkAndAddProjectilePrefab(GameObject prefab)
		{
			PrefabAPI.RegisterNetworkPrefab(prefab);
			AddProjectilePrefab(prefab);
		}

		internal static void AddSurvivorDef(SurvivorDef survivorDef)
		{
			ContentPacks.survivorDefs.Add(survivorDef);
		}

		internal static void CreateSurvivor(GameObject bodyPrefab, GameObject displayPrefab, Color charColor, string tokenPrefix)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			CreateSurvivor(bodyPrefab, displayPrefab, charColor, tokenPrefix, null, 100f);
		}

		internal static void CreateSurvivor(GameObject bodyPrefab, GameObject displayPrefab, Color charColor, string tokenPrefix, float sortPosition)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			CreateSurvivor(bodyPrefab, displayPrefab, charColor, tokenPrefix, null, sortPosition);
		}

		internal static void CreateSurvivor(GameObject bodyPrefab, GameObject displayPrefab, Color charColor, string tokenPrefix, UnlockableDef unlockableDef)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			CreateSurvivor(bodyPrefab, displayPrefab, charColor, tokenPrefix, unlockableDef, 100f);
		}

		internal static void CreateSurvivor(GameObject bodyPrefab, GameObject displayPrefab, Color charColor, string tokenPrefix, UnlockableDef unlockableDef, float sortPosition)
		{
			//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)
			SurvivorDef val = ScriptableObject.CreateInstance<SurvivorDef>();
			val.bodyPrefab = bodyPrefab;
			val.displayPrefab = displayPrefab;
			val.primaryColor = charColor;
			val.cachedName = ((Object)bodyPrefab).name.Replace("Body", "");
			val.displayNameToken = tokenPrefix + "NAME";
			val.descriptionToken = tokenPrefix + "DESCRIPTION";
			val.outroFlavorToken = tokenPrefix + "OUTRO_FLAVOR";
			val.mainEndingEscapeFailureFlavorToken = tokenPrefix + "OUTRO_FAILURE";
			val.desiredSortPosition = sortPosition;
			val.unlockableDef = unlockableDef;
			AddSurvivorDef(val);
		}

		internal static void AddUnlockableDef(UnlockableDef unlockableDef)
		{
			ContentPacks.unlockableDefs.Add(unlockableDef);
		}

		internal static UnlockableDef CreateAndAddUnlockbleDef(string identifier, string nameToken, Sprite achievementIcon)
		{
			UnlockableDef val = ScriptableObject.CreateInstance<UnlockableDef>();
			val.cachedName = identifier;
			val.nameToken = nameToken;
			val.achievementIcon = achievementIcon;
			AddUnlockableDef(val);
			return val;
		}

		internal static void AddNetworkedObject(GameObject gameObject)
		{
			ContentPacks.networkedObjects.Add(gameObject);
		}

		internal static void AddSkillDef(SkillDef skillDef)
		{
			ContentPacks.skillDefs.Add(skillDef);
		}

		internal static void AddSkillFamily(SkillFamily skillFamily)
		{
			ContentPacks.skillFamilies.Add(skillFamily);
		}

		internal static void AddEntityState(Type entityState)
		{
			ContentPacks.entityStates.Add(entityState);
		}

		internal static void AddBuffDef(BuffDef buffDef)
		{
			ContentPacks.buffDefs.Add(buffDef);
		}

		internal static BuffDef CreateAndAddBuff(string buffName, Sprite buffIcon, Color buffColor, bool canStack, bool isDebuff)
		{
			//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)
			BuffDef val = ScriptableObject.CreateInstance<BuffDef>();
			((Object)val).name = buffName;
			val.buffColor = buffColor;
			val.canStack = canStack;
			val.isDebuff = isDebuff;
			val.eliteDef = null;
			val.iconSprite = buffIcon;
			AddBuffDef(val);
			return val;
		}

		internal static void AddItemDef(ItemDef itemDef)
		{
			ContentPacks.itemDefs.Add(itemDef);
		}

		internal static ItemDef CreateAndAddItemDef(string itemName, Sprite iconSprite, ItemTier itemTier, bool hidden = false, bool canRemove = false)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			return CreateAndAddItemDef("HABIBI" + itemName + "Item", itemName, iconSprite, itemTier, hidden, canRemove);
		}

		internal static ItemDef CreateAndAddItemDef(string itemname, string token, Sprite iconSprite, ItemTier itemTier, bool hidden = false, bool canRemove = false)
		{
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			ItemDef val = ScriptableObject.CreateInstance<ItemDef>();
			((Object)val).name = itemname;
			val.nameToken = "HABIBI_MATCHER_ITEM_" + token.ToUpperInvariant() + "_NAME";
			val.descriptionToken = "HABIBI_MATCHER_ITEM_" + token.ToUpperInvariant() + "_DESCRIPTION";
			val.pickupToken = "HABIBI_MATCHER_ITEM_" + token.ToUpperInvariant() + "_PICKUP";
			val.loreToken = "HABIBI_MATCHER_ITEM_" + token.ToUpperInvariant() + "_LORE";
			val.canRemove = canRemove;
			val.pickupIconSprite = iconSprite;
			val.hidden = hidden;
			val.tier = itemTier;
			val.deprecatedTier = itemTier;
			AddItemDef(val);
			return val;
		}

		internal static void AddEffectDef(EffectDef effectDef)
		{
			ContentPacks.effectDefs.Add(effectDef);
		}

		internal static EffectDef CreateAndAddEffectDef(GameObject effectPrefab, bool donotPool = false)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			if (donotPool)
			{
				VFXAttributes orAddComponent = effectPrefab.GetOrAddComponent<VFXAttributes>();
				orAddComponent.DoNotPool = true;
			}
			EffectDef val = new EffectDef(effectPrefab);
			AddEffectDef(val);
			return val;
		}

		internal static void AddNetworkSoundEventDef(NetworkSoundEventDef networkSoundEventDef)
		{
			ContentPacks.networkSoundEventDefs.Add(networkSoundEventDef);
		}

		internal static NetworkSoundEventDef CreateAndAddNetworkSoundEventDef(string eventName)
		{
			NetworkSoundEventDef val = ScriptableObj