Decompiled source of Panel de Pon v1.0.0

plugins/Panel_de_Pon/PanelDePonPlugin.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text.RegularExpressions;
using BepInEx;
using CommonAPI;
using CommonAPI.Phone;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Reptile;
using Reptile.Phone;
using TMPro;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.6", FrameworkDisplayName = ".NET Framework 4.6")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: AssemblyCompany("PanelDePonPlugin")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Adds the best puzzle game onto your phone.")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("PanelDePonPlugin")]
[assembly: AssemblyTitle("PanelDePonPlugin")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace PanelDePon
{
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "PanelDePonPlugin";

		public const string PLUGIN_NAME = "PanelDePonPlugin";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace BRCPanelPon
{
	public class AppPanelPon : CustomApp
	{
		private static Sprite IconSprite;

		private PanelPonGame _game;

		private PanelPonRenderer _renderer;

		private float _repeatDelayTimerX;

		private float _repeatDelayTimerY;

		private float _repeatRateTimerX;

		private float _repeatRateTimerY;

		private const float FirstRepeatDelay = 0.18f;

		private const float HeldRepeatRate = 0.09f;

		private bool _restartRightHeld;

		public override bool Available => true;

		public static void Initialize()
		{
			string text = Path.Combine(PanelPonPlugin.Instance.Directory, "panelattack-appicon.png");
			if (File.Exists(text))
			{
				IconSprite = TextureUtility.LoadSprite(text);
			}
			if ((Object)(object)IconSprite != (Object)null)
			{
				PhoneAPI.RegisterApp<AppPanelPon>("panel atk", IconSprite);
			}
			else
			{
				PhoneAPI.RegisterApp<AppPanelPon>("panel atk", (Sprite)null);
			}
		}

		public override void OnAppInit()
		{
			((CustomApp)this).OnAppInit();
			if ((Object)(object)IconSprite != (Object)null)
			{
				((CustomApp)this).CreateTitleBar("<size=75%>Panel de Pon</size>", IconSprite, 80f);
			}
			else
			{
				((CustomApp)this).CreateIconlessTitleBar("size=75%>Panel de Pon</size>", 80f);
			}
			_game = new PanelPonGame();
			_game.NewGame(Environment.TickCount);
			_renderer = new PanelPonRenderer(this);
			_renderer.Build();
			_renderer.Render(_game);
		}

		public override void OnAppEnable()
		{
			((App)this).OnAppEnable();
			ResetInputRepeat();
			_restartRightHeld = false;
			PanelPonState.AppActive = true;
			FlushCurrentPlayerInput();
			if (_game == null)
			{
				_game = new PanelPonGame();
				_game.NewGame(Environment.TickCount);
			}
			if (_renderer == null)
			{
				_renderer = new PanelPonRenderer(this);
				_renderer.Build();
			}
			_renderer.Render(_game);
		}

		public override void OnAppDisable()
		{
			((App)this).OnAppDisable();
			ResetInputRepeat();
			_restartRightHeld = false;
			PanelPonState.AppActive = false;
			FlushCurrentPlayerInput();
		}

		public override void OnAppUpdate()
		{
			((App)this).OnAppUpdate();
			if (_game == null || _renderer == null)
			{
				return;
			}
			if (_game.IsGameOver)
			{
				if (PressedRestartRight())
				{
					StartNewGame();
				}
			}
			else
			{
				HandleMovementInput(Time.unscaledDeltaTime);
				HandleActionInput();
			}
			_game.Tick(Time.unscaledDeltaTime);
			if (_game.GameOverThisTick)
			{
				PlayGameOverSfx();
			}
			_renderer.Render(_game);
		}

		private void FlushCurrentPlayerInput()
		{
			WorldHandler instance = WorldHandler.instance;
			Player val = ((instance != null) ? instance.GetCurrentPlayer() : null);
			if ((Object)(object)val != (Object)null)
			{
				val.FlushInput();
			}
		}

		private void HandleMovementInput(float dt)
		{
			float num = ReadHorizontal();
			float num2 = ReadVertical();
			if (num < -0.5f)
			{
				HandleHeldAxis(ref _repeatDelayTimerX, ref _repeatRateTimerX, dt, -1, 0);
			}
			else if (num > 0.5f)
			{
				HandleHeldAxis(ref _repeatDelayTimerX, ref _repeatRateTimerX, dt, 1, 0);
			}
			else
			{
				ResetHorizontalRepeat();
			}
			if (num2 > 0.5f)
			{
				HandleHeldAxis(ref _repeatDelayTimerY, ref _repeatRateTimerY, dt, 0, 1);
			}
			else if (num2 < -0.5f)
			{
				HandleHeldAxis(ref _repeatDelayTimerY, ref _repeatRateTimerY, dt, 0, -1);
			}
			else
			{
				ResetVerticalRepeat();
			}
		}

		private void HandleHeldAxis(ref float delayTimer, ref float rateTimer, float dt, int dx, int dy)
		{
			if (delayTimer <= 0f && rateTimer <= 0f)
			{
				if (CanMoveCursor(dx, dy))
				{
					PlayMoveSfx();
					_game.MoveCursor(dx, dy);
				}
				delayTimer = 0.18f;
				rateTimer = 0f;
				return;
			}
			if (delayTimer > 0f)
			{
				delayTimer -= dt;
				return;
			}
			rateTimer -= dt;
			if (rateTimer <= 0f)
			{
				if (CanMoveCursor(dx, dy))
				{
					PlayMoveSfx();
					_game.MoveCursor(dx, dy);
				}
				rateTimer = 0.09f;
			}
		}

		private bool CanMoveCursor(int dx, int dy)
		{
			if (_game == null || _game.IsGameOver)
			{
				return false;
			}
			int num = _game.CursorX + dx;
			int num2 = _game.CursorY + dy;
			if (num < 0 || num > 4)
			{
				return false;
			}
			if (num2 < 0 || num2 > 11)
			{
				return false;
			}
			return true;
		}

		private void HandleActionInput()
		{
			if (PressedSwap() && _game.TrySwap())
			{
				PlaySwapSfx();
			}
			if (HeldRaise())
			{
				_game.ManualRaise();
			}
		}

		private bool HeldRaise()
		{
			return Input.GetKey((KeyCode)304) || Input.GetKey((KeyCode)107) || Input.GetKey((KeyCode)331);
		}

		private float ReadHorizontal()
		{
			float num = 0f;
			if (Input.GetKey((KeyCode)97))
			{
				num = -1f;
			}
			else if (Input.GetKey((KeyCode)100))
			{
				num = 1f;
			}
			float axisRaw = Input.GetAxisRaw("Horizontal");
			if (Mathf.Abs(axisRaw) > Mathf.Abs(num))
			{
				num = axisRaw;
			}
			return num;
		}

		private float ReadVertical()
		{
			float num = 0f;
			if (Input.GetKey((KeyCode)115))
			{
				num = -1f;
			}
			else if (Input.GetKey((KeyCode)119))
			{
				num = 1f;
			}
			float axisRaw = Input.GetAxisRaw("Vertical");
			if (Mathf.Abs(axisRaw) > Mathf.Abs(num))
			{
				num = axisRaw;
			}
			return num;
		}

		private bool PressedSwap()
		{
			return Input.GetKeyDown((KeyCode)106) || Input.GetKeyDown((KeyCode)32) || Input.GetKeyDown((KeyCode)330);
		}

		private bool PressedRestartRight()
		{
			bool flag = Input.GetKeyDown((KeyCode)275) || Input.GetKeyDown((KeyCode)100);
			float axisRaw = Input.GetAxisRaw("Horizontal");
			bool flag2 = axisRaw > 0.5f;
			bool flag3 = flag2 && !_restartRightHeld;
			_restartRightHeld = flag2;
			return flag || flag3;
		}

		private void StartNewGame()
		{
			_game.NewGame(Environment.TickCount);
			ResetInputRepeat();
			_restartRightHeld = false;
		}

		private void PlayMoveSfx()
		{
			if ((Object)(object)PanelPonPlugin.Instance != (Object)null)
			{
				PanelPonPlugin.Instance.PlayCursorSfx();
			}
		}

		private void PlaySwapSfx()
		{
			if ((Object)(object)PanelPonPlugin.Instance != (Object)null)
			{
				PanelPonPlugin.Instance.PlaySwapSfx();
			}
		}

		private void PlayGameOverSfx()
		{
			if ((Object)(object)PanelPonPlugin.Instance != (Object)null)
			{
				PanelPonPlugin.Instance.PlayDieSfx();
			}
		}

		private void ResetInputRepeat()
		{
			ResetHorizontalRepeat();
			ResetVerticalRepeat();
		}

		private void ResetHorizontalRepeat()
		{
			_repeatDelayTimerX = 0f;
			_repeatRateTimerX = 0f;
		}

		private void ResetVerticalRepeat()
		{
			_repeatDelayTimerY = 0f;
			_repeatRateTimerY = 0f;
		}
	}
	public class ClearResult
	{
		public int Combo;

		public bool Chain;

		public ClearResult(int combo, bool chain)
		{
			Combo = combo;
			Chain = chain;
		}
	}
	public enum BlockType
	{
		Empty,
		Red,
		Blue,
		Green,
		Yellow,
		Purple,
		DarkBlue
	}
	public enum PanelBlockState
	{
		Static,
		Hang,
		Fall,
		Swap,
		Clear
	}
	public enum PanelBlockAnim
	{
		None = -1,
		SwapLeft,
		SwapRight,
		Land,
		ClearFace,
		ClearHighlight,
		ClearDead,
		Danger
	}
	[Serializable]
	public class PanelBlock
	{
		public BlockType Type = BlockType.Empty;

		public PanelBlockState State = PanelBlockState.Static;

		public int Counter = 0;

		public PanelBlockAnim AnimState = PanelBlockAnim.None;

		public int AnimCounter = 0;

		public int ExplodeCounter = 0;

		public bool Chain = false;

		public int ClearComboSize = 0;

		public bool IsEmpty()
		{
			return Counter == 0 && Type == BlockType.Empty;
		}

		public bool IsSupport()
		{
			return State != PanelBlockState.Fall && Type != BlockType.Empty;
		}
	}
	public class PanelPonGame
	{
		public const int Width = 6;

		public const int Height = 12;

		public const int HANGTIME = 11;

		public const int FALLTIME = 4;

		public const int SWAPTIME = 4;

		public const int CLEARBLINKTIME = 38;

		public const int CLEARPAUSETIME = 20;

		public const int CLEAREXPLODETIME = 8;

		public const int PUSHTIME = 1000;

		public PanelBlock[,] Grid = new PanelBlock[6, 12];

		public PanelBlock[] NextLine = new PanelBlock[6];

		private Random _rng;

		private float _tickAccumulator;

		private bool _playedLandSfxThisFrame;

		private int _activeClearSoundChain;

		private int _activeClearSoundStep;

		private int _activeClearSoundMaxSteps;

		public int CursorX { get; private set; } = 2;


		public int CursorY { get; private set; } = 5;


		public bool IsGameOver { get; private set; }

		public bool ClearedThisTick { get; private set; }

		public bool GameOverThisTick { get; private set; }

		public int Score { get; private set; }

		public int PersonalBest { get; private set; }

		public int CurrentChain { get; private set; }

		public int PushTime => 1000;

		public int PushCounter { get; private set; }

		public long TotalTicks { get; private set; }

		public PanelPonGame()
		{
			for (int i = 0; i < 6; i++)
			{
				for (int j = 0; j < 12; j++)
				{
					Grid[i, j] = new PanelBlock();
				}
				NextLine[i] = new PanelBlock();
			}
		}

		public void NewGame(int seed)
		{
			_rng = new Random(seed);
			_tickAccumulator = 0f;
			TotalTicks = 0L;
			ClearBoard();
			FillStartingRows(4);
			FillNextLine();
			CursorX = 2;
			CursorY = 5;
			PushCounter = 1000;
			IsGameOver = false;
			ClearedThisTick = false;
			GameOverThisTick = false;
			Score = 0;
			CurrentChain = 0;
			_activeClearSoundChain = 1;
			_activeClearSoundStep = 0;
			_activeClearSoundMaxSteps = 0;
			for (int i = 0; i < 20; i++)
			{
				UpdateStateStep();
				ClearResult clearResult = UpdateCombosAndChains();
				if (clearResult.Combo == 0)
				{
					break;
				}
			}
		}

		public void Tick(float dt)
		{
			ClearedThisTick = false;
			GameOverThisTick = false;
			if (IsGameOver)
			{
				return;
			}
			_tickAccumulator += dt * 60f;
			while (_tickAccumulator >= 1f)
			{
				_tickAccumulator -= 1f;
				TickOneFrame();
				if (IsGameOver)
				{
					break;
				}
			}
		}

		private void TickOneFrame()
		{
			TotalTicks++;
			_playedLandSfxThisFrame = false;
			UpdateStateStep();
			ClearResult clearResult = UpdateCombosAndChains();
			if (clearResult.Combo > 0)
			{
				ClearedThisTick = true;
				AddScoreForClear(clearResult.Combo, clearResult.Chain);
				if ((Object)(object)PanelPonPlugin.Instance != (Object)null)
				{
					PanelPonPlugin.Instance.PlayClearSfx();
				}
				_activeClearSoundChain = Mathf.Clamp(CurrentChain, 1, 4);
				_activeClearSoundStep = 0;
				_activeClearSoundMaxSteps = clearResult.Combo;
			}
			else if (!HasPendingChainBlocks())
			{
				CurrentChain = 0;
			}
			PushCounter--;
			if (PushCounter <= 0)
			{
				PushCounter = 1000;
				Push();
			}
			CheckGameOverImmediate();
		}

		public bool MoveCursor(int dx, int dy)
		{
			if (IsGameOver)
			{
				return false;
			}
			int cursorX = CursorX;
			int cursorY = CursorY;
			CursorX = Mathf.Clamp(CursorX + dx, 0, 4);
			CursorY = Mathf.Clamp(CursorY + dy, 0, 11);
			return CursorX != cursorX || CursorY != cursorY;
		}

		public bool TrySwap()
		{
			if (IsGameOver)
			{
				return false;
			}
			if (!IsSwappable(CursorX, CursorY) || !IsSwappable(CursorX + 1, CursorY))
			{
				return false;
			}
			SwapBlocks(CursorX, CursorY);
			return true;
		}

		public void ManualRaise()
		{
			if (!IsGameOver)
			{
				PushCounter -= 20;
				if (PushCounter < 1)
				{
					PushCounter = 1;
				}
			}
		}

		public float GetPushVisualOffsetPixels()
		{
			float num = (float)(1000 - Mathf.Clamp(PushCounter, 0, 1000)) / 1000f;
			return num * 16f;
		}

		public bool IsIncomingRowDarkened()
		{
			return true;
		}

		private void SwapBlocks(int x, int y)
		{
			PanelBlock panelBlock = Grid[x, y];
			PanelBlock panelBlock2 = Grid[x + 1, y];
			BlockType type = panelBlock2.Type;
			bool chain = panelBlock2.Chain;
			panelBlock2.Type = panelBlock.Type;
			panelBlock2.Chain = false;
			panelBlock.Type = type;
			panelBlock.Chain = false;
			panelBlock.State = PanelBlockState.Swap;
			panelBlock2.State = PanelBlockState.Swap;
			if (panelBlock.Type == BlockType.Empty)
			{
				panelBlock.Counter = 0;
				panelBlock.AnimState = PanelBlockAnim.None;
				panelBlock.AnimCounter = 0;
			}
			else
			{
				panelBlock.Counter = 4;
				panelBlock.AnimState = PanelBlockAnim.SwapLeft;
				panelBlock.AnimCounter = 4;
				panelBlock.Chain = chain;
			}
			if (panelBlock2.Type == BlockType.Empty)
			{
				panelBlock2.Counter = 0;
				panelBlock2.AnimState = PanelBlockAnim.None;
				panelBlock2.AnimCounter = 0;
			}
			else
			{
				panelBlock2.Counter = 4;
				panelBlock2.AnimState = PanelBlockAnim.SwapRight;
				panelBlock2.AnimCounter = 4;
				panelBlock2.Chain = false;
			}
		}

		private void UpdateStateStep()
		{
			for (int i = 0; i < 6; i++)
			{
				for (int j = 0; j < 12; j++)
				{
					UpdateBlockState(i, j);
				}
			}
		}

		private void UpdateBlockState(int x, int y)
		{
			PanelBlock panelBlock = Grid[x, y];
			if (panelBlock.AnimCounter > 0)
			{
				panelBlock.AnimCounter--;
			}
			if (panelBlock.State == PanelBlockState.Clear)
			{
				if (panelBlock.ClearComboSize > 3 && panelBlock.AnimState == PanelBlockAnim.ClearHighlight && panelBlock.Counter <= panelBlock.ExplodeCounter + 18)
				{
					panelBlock.AnimState = PanelBlockAnim.ClearFace;
					panelBlock.AnimCounter = 18;
				}
			}
			else if (panelBlock.AnimCounter <= 0 && panelBlock.AnimState == PanelBlockAnim.Land)
			{
				panelBlock.AnimState = PanelBlockAnim.None;
			}
			if (panelBlock.Counter > 0)
			{
				panelBlock.Counter--;
				if (panelBlock.Counter > 0)
				{
					ApplyDangerAnimationIfNeeded(x, y, panelBlock);
					return;
				}
			}
			switch (panelBlock.State)
			{
			case PanelBlockState.Static:
			case PanelBlockState.Swap:
				if (panelBlock.Type == BlockType.Empty)
				{
					panelBlock.State = PanelBlockState.Static;
					panelBlock.Chain = false;
				}
				else if (y == 0)
				{
					panelBlock.State = PanelBlockState.Static;
					panelBlock.Chain = false;
				}
				else if (Grid[x, y - 1].State == PanelBlockState.Hang)
				{
					panelBlock.State = PanelBlockState.Hang;
					panelBlock.Counter = Grid[x, y - 1].Counter;
					panelBlock.Chain = Grid[x, y - 1].Chain;
				}
				else if (Grid[x, y - 1].IsEmpty())
				{
					panelBlock.State = PanelBlockState.Hang;
					panelBlock.Counter = 11;
				}
				else
				{
					panelBlock.Chain = false;
				}
				break;
			case PanelBlockState.Hang:
				panelBlock.State = PanelBlockState.Fall;
				goto case PanelBlockState.Fall;
			case PanelBlockState.Fall:
				if (y > 0 && Grid[x, y - 1].IsEmpty())
				{
					FallOneCell(x, y);
					return;
				}
				if (y > 0 && Grid[x, y - 1].State == PanelBlockState.Clear)
				{
					panelBlock.State = PanelBlockState.Static;
				}
				else if (y > 0)
				{
					panelBlock.State = Grid[x, y - 1].State;
					panelBlock.Counter = Grid[x, y - 1].Counter;
					if (Grid[x, y - 1].Chain)
					{
						panelBlock.Chain = true;
					}
				}
				else
				{
					panelBlock.State = PanelBlockState.Static;
				}
				if ((panelBlock.State != 0 && panelBlock.State != PanelBlockState.Swap) || panelBlock.Type == BlockType.Empty)
				{
					break;
				}
				panelBlock.AnimState = PanelBlockAnim.Land;
				panelBlock.AnimCounter = 4;
				if (!_playedLandSfxThisFrame)
				{
					_playedLandSfxThisFrame = true;
					if ((Object)(object)PanelPonPlugin.Instance != (Object)null)
					{
						PanelPonPlugin.Instance.PlayThumpSfx();
					}
				}
				break;
			case PanelBlockState.Clear:
				EraseBlock(x, y);
				return;
			}
			ApplyDangerAnimationIfNeeded(x, y, panelBlock);
		}

		private void ApplyDangerAnimationIfNeeded(int x, int y, PanelBlock block)
		{
			if (block.Type != 0 && block.State != PanelBlockState.Clear && block.AnimState != PanelBlockAnim.Land)
			{
				if (IsDangerColumnBlock(x))
				{
					block.AnimState = PanelBlockAnim.Danger;
				}
				else if (block.AnimState == PanelBlockAnim.Danger)
				{
					block.AnimState = PanelBlockAnim.None;
				}
			}
		}

		private bool IsDangerColumnBlock(int x)
		{
			int num = 2;
			for (int num2 = 11; num2 > 11 - num; num2--)
			{
				if (Grid[x, num2].Type != 0)
				{
					return true;
				}
			}
			return false;
		}

		private void FallOneCell(int x, int y)
		{
			PanelBlock panelBlock = Grid[x, y];
			PanelBlock panelBlock2 = Grid[x, y - 1];
			panelBlock2.Type = panelBlock.Type;
			panelBlock2.State = panelBlock.State;
			panelBlock2.Counter = panelBlock.Counter;
			panelBlock2.Chain = panelBlock.Chain;
			panelBlock2.AnimState = panelBlock.AnimState;
			panelBlock2.AnimCounter = panelBlock.AnimCounter;
			panelBlock2.ExplodeCounter = panelBlock.ExplodeCounter;
			panelBlock2.ClearComboSize = panelBlock.ClearComboSize;
			panelBlock.Type = BlockType.Empty;
			panelBlock.State = PanelBlockState.Static;
			panelBlock.Counter = 0;
			panelBlock.Chain = false;
			panelBlock.AnimState = PanelBlockAnim.None;
			panelBlock.AnimCounter = 0;
			panelBlock.ExplodeCounter = 0;
			panelBlock.ClearComboSize = 0;
		}

		private void EraseBlock(int x, int y)
		{
			PanelBlock panelBlock = Grid[x, y];
			if (_activeClearSoundStep < _activeClearSoundMaxSteps)
			{
				_activeClearSoundStep++;
				if ((Object)(object)PanelPonPlugin.Instance != (Object)null)
				{
					PanelPonPlugin.Instance.PlayChainStepSfx(_activeClearSoundChain, _activeClearSoundStep);
				}
			}
			panelBlock.Type = BlockType.Empty;
			panelBlock.State = PanelBlockState.Static;
			panelBlock.Counter = 0;
			panelBlock.Chain = false;
			panelBlock.AnimState = PanelBlockAnim.None;
			panelBlock.AnimCounter = 0;
			panelBlock.ExplodeCounter = 0;
			panelBlock.ClearComboSize = 0;
			if (y + 1 < 12 && Grid[x, y + 1].Type != 0)
			{
				Grid[x, y + 1].Chain = true;
			}
		}

		private ClearResult UpdateCombosAndChains()
		{
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			List<Vector2Int> list = new List<Vector2Int>();
			bool flag = false;
			for (int i = 0; i < 6; i++)
			{
				for (int j = 0; j < 12; j++)
				{
					if (TryMarkComboAt(i, j, list))
					{
						flag = flag || Grid[i, j].Chain;
					}
				}
			}
			list.Sort(delegate(Vector2Int a, Vector2Int b)
			{
				if (((Vector2Int)(ref a)).y < ((Vector2Int)(ref b)).y)
				{
					return 1;
				}
				if (((Vector2Int)(ref a)).y > ((Vector2Int)(ref b)).y)
				{
					return -1;
				}
				if (((Vector2Int)(ref a)).x > ((Vector2Int)(ref b)).x)
				{
					return 1;
				}
				return (((Vector2Int)(ref a)).x < ((Vector2Int)(ref b)).x) ? (-1) : 0;
			});
			int count = list.Count;
			if (count == 0)
			{
				return new ClearResult(0, chain: false);
			}
			for (int num = list.Count - 1; num >= 0; num--)
			{
				Vector2Int val = list[num];
				PanelBlock panelBlock = Grid[((Vector2Int)(ref val)).x, ((Vector2Int)(ref val)).y];
				panelBlock.State = PanelBlockState.Clear;
				panelBlock.ClearComboSize = count;
				panelBlock.ExplodeCounter = (num + 1) * 8;
				int num2 = ((count > 3) ? 10 : 0);
				panelBlock.Counter = panelBlock.ExplodeCounter + 18 + num2;
				panelBlock.AnimState = ((count > 3) ? PanelBlockAnim.ClearHighlight : PanelBlockAnim.ClearFace);
				panelBlock.AnimCounter = ((num2 > 0) ? 10 : 18);
			}
			return new ClearResult(count, flag);
		}

		private bool TryMarkComboAt(int x, int y, List<Vector2Int> combo)
		{
			if (!IsClearable(x, y))
			{
				return false;
			}
			bool result = false;
			PanelBlock panelBlock = Grid[x, y];
			if (x > 0 && x < 5 && IsClearable(x - 1, y) && IsClearable(x + 1, y) && Grid[x - 1, y].Type == panelBlock.Type && Grid[x + 1, y].Type == panelBlock.Type)
			{
				AddUnique(combo, x - 1, y);
				AddUnique(combo, x, y);
				AddUnique(combo, x + 1, y);
				if (Grid[x - 1, y].Chain || Grid[x, y].Chain || Grid[x + 1, y].Chain)
				{
					result = true;
				}
			}
			if (y > 0 && y < 11 && IsClearable(x, y - 1) && IsClearable(x, y + 1) && Grid[x, y - 1].Type == panelBlock.Type && Grid[x, y + 1].Type == panelBlock.Type)
			{
				AddUnique(combo, x, y - 1);
				AddUnique(combo, x, y);
				AddUnique(combo, x, y + 1);
				if (Grid[x, y - 1].Chain || Grid[x, y].Chain || Grid[x, y + 1].Chain)
				{
					result = true;
				}
			}
			return result;
		}

		private void AddUnique(List<Vector2Int> combo, int x, int y)
		{
			//IL_000b: 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)
			Vector2Int item = default(Vector2Int);
			((Vector2Int)(ref item))..ctor(x, y);
			if (!combo.Contains(item))
			{
				combo.Add(item);
			}
		}

		private bool IsClearable(int x, int y)
		{
			PanelBlock panelBlock = Grid[x, y];
			if (panelBlock.Type == BlockType.Empty)
			{
				return false;
			}
			if (!IsSwappable(x, y))
			{
				return false;
			}
			if (y == 0)
			{
				return true;
			}
			return Grid[x, y - 1].IsSupport();
		}

		private bool IsSwappable(int x, int y)
		{
			if (y + 1 < 12 && Grid[x, y + 1].State == PanelBlockState.Hang)
			{
				return false;
			}
			return Grid[x, y].Counter == 0;
		}

		private bool HasPendingChainBlocks()
		{
			for (int i = 0; i < 6; i++)
			{
				for (int j = 0; j < 12; j++)
				{
					if (Grid[i, j].Type != 0 && Grid[i, j].Chain)
					{
						return true;
					}
				}
			}
			return false;
		}

		private void AddScoreForClear(int comboCount, bool wasChain)
		{
			Score += comboCount * 10;
			Score += ComboToScore(comboCount);
			if (wasChain)
			{
				CurrentChain++;
			}
			else
			{
				CurrentChain = 1;
			}
			if (CurrentChain >= 2)
			{
				Score += ChainToScore(CurrentChain);
			}
		}

		private int ComboToScore(int combo)
		{
			return combo switch
			{
				4 => 20, 
				5 => 30, 
				6 => 50, 
				7 => 60, 
				8 => 70, 
				9 => 80, 
				10 => 100, 
				11 => 140, 
				12 => 170, 
				_ => 0, 
			};
		}

		private int ChainToScore(int chain)
		{
			return chain switch
			{
				2 => 50, 
				3 => 80, 
				4 => 150, 
				5 => 300, 
				6 => 400, 
				7 => 500, 
				8 => 700, 
				9 => 900, 
				10 => 1100, 
				11 => 1300, 
				12 => 1500, 
				13 => 1800, 
				_ => 0, 
			};
		}

		private void Push()
		{
			for (int i = 0; i < 6; i++)
			{
				if (Grid[i, 11].Type != 0)
				{
					TriggerGameOver();
					return;
				}
			}
			for (int num = 11; num >= 1; num--)
			{
				for (int j = 0; j < 6; j++)
				{
					CopyBlock(Grid[j, num - 1], Grid[j, num]);
				}
			}
			for (int k = 0; k < 6; k++)
			{
				CopyBlock(NextLine[k], Grid[k, 0]);
			}
			FillNextLine();
			CursorY = Mathf.Clamp(CursorY + 1, 0, 11);
		}

		private void CopyBlock(PanelBlock src, PanelBlock dst)
		{
			dst.Type = src.Type;
			dst.State = src.State;
			dst.Counter = src.Counter;
			dst.AnimState = src.AnimState;
			dst.AnimCounter = src.AnimCounter;
			dst.ExplodeCounter = src.ExplodeCounter;
			dst.Chain = src.Chain;
			dst.ClearComboSize = src.ClearComboSize;
		}

		private void CheckGameOverImmediate()
		{
			for (int i = 0; i < 6; i++)
			{
				if (Grid[i, 11].Type != 0)
				{
					TriggerGameOver();
					break;
				}
			}
		}

		private void TriggerGameOver()
		{
			if (!IsGameOver)
			{
				IsGameOver = true;
				GameOverThisTick = true;
				if (Score > PersonalBest)
				{
					PersonalBest = Score;
				}
			}
		}

		private void ClearBoard()
		{
			for (int i = 0; i < 6; i++)
			{
				for (int j = 0; j < 12; j++)
				{
					Grid[i, j] = new PanelBlock();
				}
				NextLine[i] = new PanelBlock();
			}
		}

		private void FillStartingRows(int rows)
		{
			for (int i = 0; i < rows; i++)
			{
				for (int j = 0; j < 6; j++)
				{
					Grid[j, i].Type = RandomBlockForStartGrid(j, i);
					Grid[j, i].State = PanelBlockState.Static;
					Grid[j, i].Counter = 0;
					Grid[j, i].Chain = false;
					Grid[j, i].AnimState = PanelBlockAnim.None;
					Grid[j, i].AnimCounter = 0;
					Grid[j, i].ExplodeCounter = 0;
					Grid[j, i].ClearComboSize = 0;
				}
			}
		}

		private void FillNextLine()
		{
			for (int i = 0; i < 6; i++)
			{
				NextLine[i].Type = RandomBlockForNextLine(i);
				NextLine[i].State = PanelBlockState.Static;
				NextLine[i].Counter = 0;
				NextLine[i].Chain = false;
				NextLine[i].AnimState = PanelBlockAnim.None;
				NextLine[i].AnimCounter = 0;
				NextLine[i].ExplodeCounter = 0;
				NextLine[i].ClearComboSize = 0;
			}
		}

		private BlockType RandomBlockForStartGrid(int x, int y)
		{
			List<BlockType> allBlockCandidates = GetAllBlockCandidates();
			if (x >= 2)
			{
				BlockType type = Grid[x - 1, y].Type;
				BlockType type2 = Grid[x - 2, y].Type;
				if (type != 0 && type == type2)
				{
					allBlockCandidates.Remove(type);
				}
			}
			if (y >= 2)
			{
				BlockType type3 = Grid[x, y - 1].Type;
				BlockType type4 = Grid[x, y - 2].Type;
				if (type3 != 0 && type3 == type4)
				{
					allBlockCandidates.Remove(type3);
				}
			}
			return PickRandomCandidate(allBlockCandidates);
		}

		private BlockType RandomBlockForNextLine(int x)
		{
			List<BlockType> allBlockCandidates = GetAllBlockCandidates();
			if (x >= 2)
			{
				BlockType type = NextLine[x - 1].Type;
				BlockType type2 = NextLine[x - 2].Type;
				if (type != 0 && type == type2)
				{
					allBlockCandidates.Remove(type);
				}
			}
			bool flag = true;
			BlockType type3 = Grid[x, 1].Type;
			BlockType type4 = Grid[x, 2].Type;
			if (type3 != 0 && type3 == type4)
			{
				allBlockCandidates.Remove(type3);
			}
			return PickRandomCandidate(allBlockCandidates);
		}

		private List<BlockType> GetAllBlockCandidates()
		{
			return new List<BlockType>
			{
				BlockType.Red,
				BlockType.Blue,
				BlockType.Green,
				BlockType.Yellow,
				BlockType.Purple,
				BlockType.DarkBlue
			};
		}

		private BlockType PickRandomCandidate(List<BlockType> candidates)
		{
			if (candidates == null || candidates.Count == 0)
			{
				return RandomBlock();
			}
			return candidates[_rng.Next(candidates.Count)];
		}

		private BlockType RandomBlock()
		{
			return (BlockType)_rng.Next(1, 7);
		}
	}
	[BepInPlugin("transrights.paneldepon", "Panel de Pon", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class PanelPonPlugin : BaseUnityPlugin
	{
		[CompilerGenerated]
		private sealed class <>c__DisplayClass43_0
		{
			public string key;

			public string fileName;

			public PanelPonPlugin <>4__this;

			internal void <LoadSfx>b__15(AudioClip clip)
			{
				<>4__this._chainClips[key] = clip;
				((BaseUnityPlugin)<>4__this).Logger.LogInfo((object)("Loaded chain SFX: " + key + " from " + fileName));
			}
		}

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

			private object <>2__current;

			public string fullPath;

			public Action<AudioClip> assign;

			public PanelPonPlugin <>4__this;

			private string <url>5__1;

			private AudioType <audioType>5__2;

			private UnityWebRequest <request>5__3;

			private bool <failed>5__4;

			private AudioClip <clip>5__5;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if (num == -3 || num == 1)
				{
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<url>5__1 = null;
				<request>5__3 = null;
				<clip>5__5 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0095: 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_00a7: Unknown result type (might be due to invalid IL or missing references)
				bool result;
				try
				{
					switch (<>1__state)
					{
					default:
						result = false;
						break;
					case 0:
						<>1__state = -1;
						if (!File.Exists(fullPath))
						{
							((BaseUnityPlugin)<>4__this).Logger.LogWarning((object)("Missing SFX file: " + fullPath));
							result = false;
							break;
						}
						<url>5__1 = "file:///" + fullPath.Replace("\\", "/");
						<audioType>5__2 = <>4__this.GetAudioTypeFromExtension(fullPath);
						<request>5__3 = UnityWebRequestMultimedia.GetAudioClip(<url>5__1, <audioType>5__2);
						<>1__state = -3;
						<>2__current = <request>5__3.SendWebRequest();
						<>1__state = 1;
						result = true;
						break;
					case 1:
						<>1__state = -3;
						<failed>5__4 = <request>5__3.isNetworkError || <request>5__3.isHttpError;
						if (<failed>5__4)
						{
							((BaseUnityPlugin)<>4__this).Logger.LogWarning((object)("Failed to load SFX: " + fullPath + " | " + <request>5__3.error));
							result = false;
						}
						else
						{
							<clip>5__5 = DownloadHandlerAudioClip.GetContent(<request>5__3);
							if (!((Object)(object)<clip>5__5 == (Object)null))
							{
								((Object)<clip>5__5).name = Path.GetFileNameWithoutExtension(fullPath);
								assign(<clip>5__5);
								((BaseUnityPlugin)<>4__this).Logger.LogInfo((object)("Loaded SFX: " + ((Object)<clip>5__5).name));
								<clip>5__5 = null;
								<>m__Finally1();
								<request>5__3 = null;
								result = false;
								break;
							}
							((BaseUnityPlugin)<>4__this).Logger.LogWarning((object)("Loaded null AudioClip: " + fullPath));
							result = false;
						}
						<>m__Finally1();
						break;
					}
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
				return result;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			private void <>m__Finally1()
			{
				<>1__state = -1;
				if (<request>5__3 != null)
				{
					((IDisposable)<request>5__3).Dispose();
				}
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

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

			private object <>2__current;

			public string fullPath;

			public Action<AudioClip> assign;

			public PanelPonPlugin <>4__this;

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

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

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

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

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					if (!File.Exists(fullPath))
					{
						return false;
					}
					<>2__current = ((MonoBehaviour)<>4__this).StartCoroutine(<>4__this.LoadClip(fullPath, assign));
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

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

			private object <>2__current;

			public PanelPonPlugin <>4__this;

			private string <sfxFolder>5__1;

			private string[] <files>5__2;

			private string[] <>s__3;

			private int <>s__4;

			private string <fullPath>5__5;

			private <>c__DisplayClass43_0 <>8__6;

			private Match <match>5__7;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<sfxFolder>5__1 = null;
				<files>5__2 = null;
				<>s__3 = null;
				<fullPath>5__5 = null;
				<>8__6 = null;
				<match>5__7 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<sfxFolder>5__1 = Path.Combine(<>4__this.Directory, "SFX");
					<>2__current = ((MonoBehaviour)<>4__this).StartCoroutine(<>4__this.LoadClipIfExists(Path.Combine(<sfxFolder>5__1, "swap.wav"), delegate(AudioClip clip)
					{
						<>4__this.SwapClip = clip;
					}));
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					<>2__current = ((MonoBehaviour)<>4__this).StartCoroutine(<>4__this.LoadClipIfExists(Path.Combine(<sfxFolder>5__1, "swap.wave"), delegate(AudioClip clip)
					{
						<>4__this.SwapClip = clip;
					}));
					<>1__state = 2;
					return true;
				case 2:
					<>1__state = -1;
					<>2__current = ((MonoBehaviour)<>4__this).StartCoroutine(<>4__this.LoadClipIfExists(Path.Combine(<sfxFolder>5__1, "swap.ogg"), delegate(AudioClip clip)
					{
						<>4__this.SwapClip = clip;
					}));
					<>1__state = 3;
					return true;
				case 3:
					<>1__state = -1;
					<>2__current = ((MonoBehaviour)<>4__this).StartCoroutine(<>4__this.LoadClipIfExists(Path.Combine(<sfxFolder>5__1, "cursor.wav"), delegate(AudioClip clip)
					{
						<>4__this.CursorClip = clip;
					}));
					<>1__state = 4;
					return true;
				case 4:
					<>1__state = -1;
					<>2__current = ((MonoBehaviour)<>4__this).StartCoroutine(<>4__this.LoadClipIfExists(Path.Combine(<sfxFolder>5__1, "cursor.wave"), delegate(AudioClip clip)
					{
						<>4__this.CursorClip = clip;
					}));
					<>1__state = 5;
					return true;
				case 5:
					<>1__state = -1;
					<>2__current = ((MonoBehaviour)<>4__this).StartCoroutine(<>4__this.LoadClipIfExists(Path.Combine(<sfxFolder>5__1, "cursor.ogg"), delegate(AudioClip clip)
					{
						<>4__this.CursorClip = clip;
					}));
					<>1__state = 6;
					return true;
				case 6:
					<>1__state = -1;
					<>2__current = ((MonoBehaviour)<>4__this).StartCoroutine(<>4__this.LoadClipIfExists(Path.Combine(<sfxFolder>5__1, "thump.wav"), delegate(AudioClip clip)
					{
						<>4__this.ThumpClip = clip;
					}));
					<>1__state = 7;
					return true;
				case 7:
					<>1__state = -1;
					<>2__current = ((MonoBehaviour)<>4__this).StartCoroutine(<>4__this.LoadClipIfExists(Path.Combine(<sfxFolder>5__1, "thump.wave"), delegate(AudioClip clip)
					{
						<>4__this.ThumpClip = clip;
					}));
					<>1__state = 8;
					return true;
				case 8:
					<>1__state = -1;
					<>2__current = ((MonoBehaviour)<>4__this).StartCoroutine(<>4__this.LoadClipIfExists(Path.Combine(<sfxFolder>5__1, "thump.ogg"), delegate(AudioClip clip)
					{
						<>4__this.ThumpClip = clip;
					}));
					<>1__state = 9;
					return true;
				case 9:
					<>1__state = -1;
					<>2__current = ((MonoBehaviour)<>4__this).StartCoroutine(<>4__this.LoadClipIfExists(Path.Combine(<sfxFolder>5__1, "clear.wav"), delegate(AudioClip clip)
					{
						<>4__this.ClearClip = clip;
					}));
					<>1__state = 10;
					return true;
				case 10:
					<>1__state = -1;
					<>2__current = ((MonoBehaviour)<>4__this).StartCoroutine(<>4__this.LoadClipIfExists(Path.Combine(<sfxFolder>5__1, "clear.wave"), delegate(AudioClip clip)
					{
						<>4__this.ClearClip = clip;
					}));
					<>1__state = 11;
					return true;
				case 11:
					<>1__state = -1;
					<>2__current = ((MonoBehaviour)<>4__this).StartCoroutine(<>4__this.LoadClipIfExists(Path.Combine(<sfxFolder>5__1, "clear.ogg"), delegate(AudioClip clip)
					{
						<>4__this.ClearClip = clip;
					}));
					<>1__state = 12;
					return true;
				case 12:
					<>1__state = -1;
					<>2__current = ((MonoBehaviour)<>4__this).StartCoroutine(<>4__this.LoadClipIfExists(Path.Combine(<sfxFolder>5__1, "die.wav"), delegate(AudioClip clip)
					{
						<>4__this.DieClip = clip;
					}));
					<>1__state = 13;
					return true;
				case 13:
					<>1__state = -1;
					<>2__current = ((MonoBehaviour)<>4__this).StartCoroutine(<>4__this.LoadClipIfExists(Path.Combine(<sfxFolder>5__1, "die.wave"), delegate(AudioClip clip)
					{
						<>4__this.DieClip = clip;
					}));
					<>1__state = 14;
					return true;
				case 14:
					<>1__state = -1;
					<>2__current = ((MonoBehaviour)<>4__this).StartCoroutine(<>4__this.LoadClipIfExists(Path.Combine(<sfxFolder>5__1, "die.ogg"), delegate(AudioClip clip)
					{
						<>4__this.DieClip = clip;
					}));
					<>1__state = 15;
					return true;
				case 15:
					<>1__state = -1;
					if (!System.IO.Directory.Exists(<sfxFolder>5__1))
					{
						break;
					}
					<files>5__2 = System.IO.Directory.GetFiles(<sfxFolder>5__1);
					<>s__3 = <files>5__2;
					<>s__4 = 0;
					goto IL_06b2;
				case 16:
					{
						<>1__state = -1;
						<>8__6 = null;
						<match>5__7 = null;
						<fullPath>5__5 = null;
						goto IL_06a4;
					}
					IL_06b2:
					if (<>s__4 < <>s__3.Length)
					{
						<fullPath>5__5 = <>s__3[<>s__4];
						<>8__6 = new <>c__DisplayClass43_0();
						<>8__6.<>4__this = <>4__this;
						<>8__6.fileName = Path.GetFileName(<fullPath>5__5);
						<match>5__7 = ChainClipRegex.Match(<>8__6.fileName);
						if (!<match>5__7.Success)
						{
							goto IL_06a4;
						}
						<>8__6.key = <match>5__7.Groups[1].Value + "x" + <match>5__7.Groups[2].Value;
						<>2__current = ((MonoBehaviour)<>4__this).StartCoroutine(<>4__this.LoadClip(<fullPath>5__5, delegate(AudioClip clip)
						{
							<>8__6.<>4__this._chainClips[<>8__6.key] = clip;
							((BaseUnityPlugin)<>8__6.<>4__this).Logger.LogInfo((object)("Loaded chain SFX: " + <>8__6.key + " from " + <>8__6.fileName));
						}));
						<>1__state = 16;
						return true;
					}
					<>s__3 = null;
					<files>5__2 = null;
					break;
					IL_06a4:
					<>s__4++;
					goto IL_06b2;
				}
				((BaseUnityPlugin)<>4__this).Logger.LogInfo((object)("PanelPon chain clip count: " + <>4__this._chainClips.Count));
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		private Harmony _harmony;

		private readonly Dictionary<string, AudioClip> _chainClips = new Dictionary<string, AudioClip>();

		private static readonly Regex ChainClipRegex = new Regex("^([1-4])x([1-9]|10)\\.(wav|wave|ogg)$", RegexOptions.IgnoreCase);

		private AudioSource _cursorSource;

		private AudioSource _swapSource;

		private AudioSource _thumpSource;

		private AudioSource _clearSource;

		private float _lastThumpTime = -999f;

		private const float SwapVolume = 1f;

		private const float CursorVolume = 0.9f;

		private const float ThumpVolume = 0.32f;

		private const float ClearVolume = 0.9f;

		private const float ChainVolume = 0.8f;

		private const float DieVolume = 1f;

		private const float ThumpCooldown = 0.03f;

		public static PanelPonPlugin Instance { get; private set; }

		public string Directory => Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);

		public AudioClip SwapClip { get; private set; }

		public AudioClip CursorClip { get; private set; }

		public AudioClip ThumpClip { get; private set; }

		public AudioClip ClearClip { get; private set; }

		public AudioClip DieClip { get; private set; }

		private void Awake()
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			Instance = this;
			_harmony = new Harmony("com.yourname.paneldepon");
			_harmony.PatchAll();
			_cursorSource = CreateUiAudioSource("PanelPonCursorAudio", 0);
			_swapSource = CreateUiAudioSource("PanelPonSwapAudio", 16);
			_thumpSource = CreateUiAudioSource("PanelPonThumpAudio", 32);
			_clearSource = CreateUiAudioSource("PanelPonClearAudio", 8);
			((MonoBehaviour)this).StartCoroutine(LoadSfx());
			AppPanelPon.Initialize();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Panel de Pon loaded.");
		}

		private void OnDestroy()
		{
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}

		[IteratorStateMachine(typeof(<LoadSfx>d__43))]
		private IEnumerator LoadSfx()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <LoadSfx>d__43(0)
			{
				<>4__this = this
			};
		}

		[IteratorStateMachine(typeof(<LoadClipIfExists>d__44))]
		private IEnumerator LoadClipIfExists(string fullPath, Action<AudioClip> assign)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <LoadClipIfExists>d__44(0)
			{
				<>4__this = this,
				fullPath = fullPath,
				assign = assign
			};
		}

		[IteratorStateMachine(typeof(<LoadClip>d__45))]
		private IEnumerator LoadClip(string fullPath, Action<AudioClip> assign)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <LoadClip>d__45(0)
			{
				<>4__this = this,
				fullPath = fullPath,
				assign = assign
			};
		}

		private AudioType GetAudioTypeFromExtension(string fullPath)
		{
			//IL_003c: 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_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			switch (Path.GetExtension(fullPath).ToLowerInvariant())
			{
			case ".ogg":
				return (AudioType)14;
			case ".wav":
			case ".wave":
				return (AudioType)20;
			default:
				return (AudioType)0;
			}
		}

		private AudioSource CreateUiAudioSource(string name, int priority)
		{
			AudioSource val = ((Component)this).gameObject.AddComponent<AudioSource>();
			((Object)val).name = name;
			val.playOnAwake = false;
			val.loop = false;
			val.spatialBlend = 0f;
			val.panStereo = 0f;
			val.spread = 0f;
			val.dopplerLevel = 0f;
			val.reverbZoneMix = 0f;
			val.rolloffMode = (AudioRolloffMode)1;
			val.minDistance = 1f;
			val.maxDistance = 1f;
			val.bypassEffects = true;
			val.bypassListenerEffects = true;
			val.bypassReverbZones = true;
			val.priority = priority;
			val.volume = 1f;
			return val;
		}

		public void PlaySwapSfx()
		{
			PlayClip(_swapSource, SwapClip, 1f);
		}

		public void PlayCursorSfx()
		{
			PlayClip(_cursorSource, CursorClip, 0.9f);
		}

		public void PlayThumpSfx()
		{
			float unscaledTime = Time.unscaledTime;
			if (!(unscaledTime - _lastThumpTime < 0.03f))
			{
				_lastThumpTime = unscaledTime;
				PlayClip(_thumpSource, ThumpClip, 0.32f);
			}
		}

		public void PlayDieSfx()
		{
			PlayOneShotClip(_clearSource, DieClip, 1f);
		}

		public void PlayClearSfx()
		{
			PlayOneShotClip(_clearSource, ClearClip, 0.9f);
		}

		public void PlayChainStepSfx(int chain, int step)
		{
			int num = Mathf.Clamp(chain, 1, 4);
			int num2 = Mathf.Clamp(step, 1, 10);
			string key = num + "x" + num2;
			if (_chainClips.TryGetValue(key, out var value) && (Object)(object)value != (Object)null)
			{
				PlayOneShotClip(_clearSource, value, 0.8f);
			}
		}

		private void PlayOneShotClip(AudioSource source, AudioClip clip, float volume)
		{
			if (!((Object)(object)source == (Object)null) && !((Object)(object)clip == (Object)null))
			{
				source.PlayOneShot(clip, volume);
			}
		}

		private void PlayClip(AudioSource source, AudioClip clip, float volume)
		{
			if (!((Object)(object)source == (Object)null) && !((Object)(object)clip == (Object)null))
			{
				source.Stop();
				source.clip = clip;
				source.volume = volume;
				source.time = 0f;
				source.Play();
			}
		}
	}
	public class PanelPonRenderer
	{
		private readonly AppPanelPon _app;

		private GameObject _root;

		private RectTransform _rootRect;

		private Image _boardBackground;

		private GameObject _playfieldMaskObject;

		private RectTransform _playfieldMaskRect;

		private Image[,] _cells;

		private Image[] _incomingCells;

		private Image _cursorImage;

		private Image _overlayBackground;

		private TextMeshProUGUI _gameOverText;

		private TextMeshProUGUI _scoreText;

		private TextMeshProUGUI _personalBestText;

		private TextMeshProUGUI _restartText;

		private TextMeshProUGUI _quitText;

		private const int Width = 6;

		private const int Height = 12;

		private const float RootScale = 7f;

		private const int BlockFrameWidth = 16;

		private const int BlockFrameHeight = 16;

		private const int CursorFrameWidth = 38;

		private const int CursorFrameHeight = 22;

		private const int CursorFrameCount = 2;

		private const float CursorAnimFps = 6f;

		private static readonly int[] LandFrames = new int[4] { 2, 1, 0, 1 };

		private static readonly int[] DangerFrames = new int[3] { 2, 3, 4 };

		private const int IdleFrame = 0;

		private const int IncomingFrame = 1;

		private const int ClearFaceFrame = 5;

		private const int ClearHighlightFrame = 6;

		private float _cellSize;

		private float _cellGap;

		private float _boardWidth;

		private float _boardHeight;

		private readonly Dictionary<BlockType, Texture2D> _blockTextures = new Dictionary<BlockType, Texture2D>();

		private readonly List<Sprite> _cursorFrames = new List<Sprite>();

		private readonly Dictionary<string, Sprite> _spriteCache = new Dictionary<string, Sprite>();

		public PanelPonRenderer(AppPanelPon app)
		{
			_app = app;
		}

		public void Build()
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected O, but got Unknown
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Expected O, but got Unknown
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0218: Unknown result type (might be due to invalid IL or missing references)
			//IL_0268: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cb: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_root != (Object)null)
			{
				Object.Destroy((Object)(object)_root);
			}
			_spriteCache.Clear();
			LoadSprites();
			CalculateLayout();
			_root = new GameObject("PanelDePonRoot", new Type[1] { typeof(RectTransform) });
			_rootRect = _root.GetComponent<RectTransform>();
			((Transform)_rootRect).SetParent(((Component)_app).transform, false);
			_rootRect.anchorMin = new Vector2(0.5f, 0.5f);
			_rootRect.anchorMax = new Vector2(0.5f, 0.5f);
			_rootRect.pivot = new Vector2(0.5f, 0.5f);
			_rootRect.sizeDelta = new Vector2(_boardWidth + 12f, _boardHeight + 12f);
			_rootRect.anchoredPosition = new Vector2(0f, -80f);
			((Transform)_rootRect).localScale = Vector3.one * 7f;
			GameObject val = new GameObject("BoardBackground", new Type[3]
			{
				typeof(RectTransform),
				typeof(CanvasRenderer),
				typeof(Image)
			});
			RectTransform component = val.GetComponent<RectTransform>();
			((Transform)component).SetParent((Transform)(object)_rootRect, false);
			component.anchorMin = new Vector2(0.5f, 0.5f);
			component.anchorMax = new Vector2(0.5f, 0.5f);
			component.pivot = new Vector2(0.5f, 0.5f);
			component.sizeDelta = new Vector2(_boardWidth + 4f, _boardHeight + 4f);
			component.anchoredPosition = Vector2.zero;
			_boardBackground = val.GetComponent<Image>();
			((Graphic)_boardBackground).color = new Color(0.05f, 0.05f, 0.08f, 0.96f);
			CreatePlayfieldMask();
			_cells = new Image[6, 12];
			for (int i = 0; i < 6; i++)
			{
				for (int j = 0; j < 12; j++)
				{
					_cells[i, j] = CreateBlockImage($"Cell_{i}_{j}", GetCellPosition(i, j), _playfieldMaskRect);
				}
			}
			_incomingCells = (Image[])(object)new Image[6];
			for (int k = 0; k < 6; k++)
			{
				_incomingCells[k] = CreateBlockImage($"Incoming_{k}", Vector2.zero, _playfieldMaskRect);
			}
			_cursorImage = CreateCursorImage();
			CreateOverlayBackground();
			CreateGameOverText();
			CreateScoreText();
			CreatePersonalBestText();
			CreateRestartText();
			CreateQuitText();
		}

		private void CreatePlayfieldMask()
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Expected O, but got Unknown
			//IL_007f: 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_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			_playfieldMaskObject = new GameObject("PlayfieldMask", new Type[4]
			{
				typeof(RectTransform),
				typeof(CanvasRenderer),
				typeof(Image),
				typeof(RectMask2D)
			});
			_playfieldMaskRect = _playfieldMaskObject.GetComponent<RectTransform>();
			((Transform)_playfieldMaskRect).SetParent((Transform)(object)_rootRect, false);
			_playfieldMaskRect.anchorMin = new Vector2(0.5f, 0.5f);
			_playfieldMaskRect.anchorMax = new Vector2(0.5f, 0.5f);
			_playfieldMaskRect.pivot = new Vector2(0.5f, 0.5f);
			_playfieldMaskRect.sizeDelta = new Vector2(_boardWidth, _boardHeight);
			_playfieldMaskRect.anchoredPosition = Vector2.zero;
			Image component = _playfieldMaskObject.GetComponent<Image>();
			((Graphic)component).color = new Color(1f, 1f, 1f, 0.001f);
		}

		public void Render(PanelPonGame game)
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			if (_cells == null)
			{
				return;
			}
			float pushVisualOffsetPixels = game.GetPushVisualOffsetPixels();
			for (int i = 0; i < 6; i++)
			{
				for (int j = 0; j < 12; j++)
				{
					Image val = _cells[i, j];
					PanelBlock panelBlock = game.Grid[i, j];
					((Graphic)val).rectTransform.anchoredPosition = GetCellPosition(i, j) + new Vector2(0f, pushVisualOffsetPixels);
					if (panelBlock.Type == BlockType.Empty || panelBlock.AnimState == PanelBlockAnim.ClearDead)
					{
						((Behaviour)val).enabled = false;
						val.sprite = null;
					}
					else
					{
						((Behaviour)val).enabled = true;
						val.sprite = GetBlockSprite(panelBlock);
						((Graphic)val).color = GetBlockColor(panelBlock, incoming: false, game.TotalTicks, i, j, game);
					}
				}
			}
			for (int k = 0; k < 6; k++)
			{
				PanelBlock panelBlock2 = game.NextLine[k];
				Image val2 = _incomingCells[k];
				if (panelBlock2.Type == BlockType.Empty)
				{
					((Behaviour)val2).enabled = false;
					val2.sprite = null;
					continue;
				}
				((Behaviour)val2).enabled = true;
				val2.sprite = GetBlockSprite(panelBlock2, 1);
				((Graphic)val2).color = new Color(0.42f, 0.42f, 0.42f, 0.95f);
				((Graphic)val2).rectTransform.anchoredPosition = GetIncomingCellPosition(k, pushVisualOffsetPixels);
			}
			UpdateCursor(game.CursorX, game.CursorY, pushVisualOffsetPixels);
			bool isGameOver = game.IsGameOver;
			if ((Object)(object)_cursorImage != (Object)null)
			{
				((Behaviour)_cursorImage).enabled = !isGameOver && _cursorFrames.Count > 0;
			}
			if ((Object)(object)_overlayBackground != (Object)null)
			{
				((Behaviour)_overlayBackground).enabled = isGameOver;
			}
			if ((Object)(object)_gameOverText != (Object)null)
			{
				((Behaviour)_gameOverText).enabled = isGameOver;
			}
			if ((Object)(object)_scoreText != (Object)null)
			{
				((Behaviour)_scoreText).enabled = isGameOver;
				((TMP_Text)_scoreText).text = $"Total Score: {game.Score}";
			}
			if ((Object)(object)_personalBestText != (Object)null)
			{
				((Behaviour)_personalBestText).enabled = isGameOver;
				((TMP_Text)_personalBestText).text = $"High-Score: {game.PersonalBest}";
			}
			if ((Object)(object)_restartText != (Object)null)
			{
				((Behaviour)_restartText).enabled = isGameOver;
			}
			if ((Object)(object)_quitText != (Object)null)
			{
				((Behaviour)_quitText).enabled = isGameOver;
			}
		}

		private void LoadSprites()
		{
			_blockTextures.Clear();
			_cursorFrames.Clear();
			string path = Path.Combine(PanelPonPlugin.Instance.Directory, "Sprites");
			_blockTextures[BlockType.Red] = LoadTexture(Path.Combine(path, "block_red.png"));
			_blockTextures[BlockType.Blue] = LoadTexture(Path.Combine(path, "block_blue.png"));
			_blockTextures[BlockType.Green] = LoadTexture(Path.Combine(path, "block_green.png"));
			_blockTextures[BlockType.Yellow] = LoadTexture(Path.Combine(path, "block_yellow.png"));
			_blockTextures[BlockType.Purple] = LoadTexture(Path.Combine(path, "block_purple.png"));
			_blockTextures[BlockType.DarkBlue] = LoadTexture(Path.Combine(path, "block_darkblue.png"));
			string path2 = Path.Combine(path, "cursor.png");
			for (int i = 0; i < 2; i++)
			{
				Sprite val = LoadCursorStripFrame(path2, i);
				if ((Object)(object)val != (Object)null)
				{
					_cursorFrames.Add(val);
				}
			}
		}

		private Texture2D LoadTexture(string path)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			if (!File.Exists(path))
			{
				return null;
			}
			byte[] array = File.ReadAllBytes(path);
			Texture2D val = new Texture2D(2, 2, (TextureFormat)5, false);
			((Texture)val).filterMode = (FilterMode)0;
			((Texture)val).wrapMode = (TextureWrapMode)1;
			ImageConversion.LoadImage(val, array);
			return val;
		}

		private Sprite LoadCursorStripFrame(string path, int frameIndex)
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			if (!File.Exists(path))
			{
				return null;
			}
			Texture2D val = LoadTexture(path);
			int num = Mathf.Max(1, ((Texture)val).width / 38);
			int num2 = Mathf.Clamp(frameIndex, 0, num - 1);
			int num3 = num2 * 38;
			Rect val2 = default(Rect);
			((Rect)(ref val2))..ctor((float)num3, 0f, 38f, 22f);
			return Sprite.Create(val, val2, new Vector2(0.5f, 0.5f), 16f, 0u, (SpriteMeshType)0);
		}

		private Sprite GetBlockSprite(PanelBlock block)
		{
			return GetBlockSprite(block, GetFrameIndex(block));
		}

		private Sprite GetBlockSprite(PanelBlock block, int forceFrame)
		{
			//IL_009b: 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)
			if (!_blockTextures.TryGetValue(block.Type, out var value) || (Object)(object)value == (Object)null)
			{
				return null;
			}
			int num = Mathf.Max(1, ((Texture)value).width / 16);
			int num2 = Mathf.Clamp(forceFrame, 0, num - 1);
			string key = $"{block.Type}_{num2}";
			if (_spriteCache.TryGetValue(key, out var value2))
			{
				return value2;
			}
			Rect val = default(Rect);
			((Rect)(ref val))..ctor((float)(num2 * 16), 0f, 16f, 16f);
			Sprite val2 = Sprite.Create(value, val, new Vector2(0.5f, 0.5f), 16f, 0u, (SpriteMeshType)0);
			_spriteCache[key] = val2;
			return val2;
		}

		private int GetFrameIndex(PanelBlock block)
		{
			if (block.State == PanelBlockState.Clear)
			{
				if (block.ClearComboSize > 3 && block.AnimState == PanelBlockAnim.ClearHighlight)
				{
					return 6;
				}
				return 5;
			}
			switch (block.AnimState)
			{
			case PanelBlockAnim.Land:
			{
				int num = Mathf.Clamp(LandFrames.Length - 1 - block.AnimCounter, 0, LandFrames.Length - 1);
				return LandFrames[num];
			}
			case PanelBlockAnim.Danger:
				return DangerFrames[(int)(Time.unscaledTime * 8f) % DangerFrames.Length];
			default:
				return 0;
			}
		}

		private Color GetBlockColor(PanelBlock block, bool incoming, long totalTicks, int x, int y, PanelPonGame game)
		{
			//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_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_002a: Unknown result type (might be due to invalid IL or missing references)
			if (incoming)
			{
				return new Color(0.42f, 0.42f, 0.42f, 0.95f);
			}
			return Color.white;
		}

		private bool IsDangerBlock(int x, int y, PanelPonGame game)
		{
			int num = 2;
			for (int num2 = 11; num2 > 11 - num; num2--)
			{
				if (game.Grid[x, num2].Type != 0)
				{
					return true;
				}
			}
			return false;
		}

		private void CalculateLayout()
		{
			_cellSize = 16f;
			_cellGap = 0f;
			_boardWidth = 6f * _cellSize + 5f * _cellGap;
			_boardHeight = 12f * _cellSize + 11f * _cellGap;
		}

		private Image CreateBlockImage(string name, Vector2 pos, RectTransform parent)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Expected O, but got Unknown
			//IL_0050: 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_007c: 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_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name, new Type[3]
			{
				typeof(RectTransform),
				typeof(CanvasRenderer),
				typeof(Image)
			});
			RectTransform component = val.GetComponent<RectTransform>();
			((Transform)component).SetParent((Transform)(object)parent, false);
			component.anchorMin = new Vector2(0.5f, 0.5f);
			component.anchorMax = new Vector2(0.5f, 0.5f);
			component.pivot = new Vector2(0.5f, 0.5f);
			component.sizeDelta = new Vector2(_cellSize, _cellSize);
			component.anchoredPosition = pos;
			Image component2 = val.GetComponent<Image>();
			component2.preserveAspect = true;
			((Graphic)component2).color = Color.white;
			((Behaviour)component2).enabled = false;
			return component2;
		}

		private Image CreateCursorImage()
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			//IL_0059: 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_0085: 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_00da: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Cursor", new Type[3]
			{
				typeof(RectTransform),
				typeof(CanvasRenderer),
				typeof(Image)
			});
			RectTransform component = val.GetComponent<RectTransform>();
			((Transform)component).SetParent((Transform)(object)_rootRect, false);
			component.anchorMin = new Vector2(0.5f, 0.5f);
			component.anchorMax = new Vector2(0.5f, 0.5f);
			component.pivot = new Vector2(0.5f, 0.5f);
			component.sizeDelta = new Vector2(38f, 22f);
			Image component2 = val.GetComponent<Image>();
			component2.sprite = ((_cursorFrames.Count > 0) ? _cursorFrames[0] : null);
			component2.preserveAspect = true;
			((Graphic)component2).color = Color.white;
			((Behaviour)component2).enabled = _cursorFrames.Count > 0;
			return component2;
		}

		private void CreateOverlayBackground()
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			//IL_0059: 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_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: 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_00e6: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("OverlayBackground", new Type[3]
			{
				typeof(RectTransform),
				typeof(CanvasRenderer),
				typeof(Image)
			});
			RectTransform component = val.GetComponent<RectTransform>();
			((Transform)component).SetParent((Transform)(object)_rootRect, false);
			component.anchorMin = new Vector2(0.5f, 0.5f);
			component.anchorMax = new Vector2(0.5f, 0.5f);
			component.pivot = new Vector2(0.5f, 0.5f);
			component.sizeDelta = new Vector2(_boardWidth + 4f, _boardHeight + 4f);
			component.anchoredPosition = Vector2.zero;
			_overlayBackground = val.GetComponent<Image>();
			((Graphic)_overlayBackground).color = new Color(0f, 0f, 0f, 0.72f);
			((Behaviour)_overlayBackground).enabled = false;
		}

		private void CreateGameOverText()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: 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_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("GameOverText", new Type[1] { typeof(RectTransform) });
			RectTransform component = val.GetComponent<RectTransform>();
			((Transform)component).SetParent((Transform)(object)_rootRect, false);
			component.anchorMin = new Vector2(0.5f, 0.5f);
			component.anchorMax = new Vector2(0.5f, 0.5f);
			component.pivot = new Vector2(0.5f, 0.5f);
			component.sizeDelta = new Vector2(_boardWidth + 30f, 24f);
			component.anchoredPosition = new Vector2(0f, 24f);
			_gameOverText = val.AddComponent<TextMeshProUGUI>();
			((TMP_Text)_gameOverText).text = "GAME OVER";
			((TMP_Text)_gameOverText).alignment = (TextAlignmentOptions)514;
			((TMP_Text)_gameOverText).fontSize = 10f;
			((Graphic)_gameOverText).color = Color.white;
			((Behaviour)_gameOverText).enabled = false;
		}

		private void CreateScoreText()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: 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_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("ScoreText", new Type[1] { typeof(RectTransform) });
			RectTransform component = val.GetComponent<RectTransform>();
			((Transform)component).SetParent((Transform)(object)_rootRect, false);
			component.anchorMin = new Vector2(0.5f, 0.5f);
			component.anchorMax = new Vector2(0.5f, 0.5f);
			component.pivot = new Vector2(0.5f, 0.5f);
			component.sizeDelta = new Vector2(_boardWidth + 60f, 18f);
			component.anchoredPosition = new Vector2(0f, 6f);
			_scoreText = val.AddComponent<TextMeshProUGUI>();
			((TMP_Text)_scoreText).text = "Total Score: 0";
			((TMP_Text)_scoreText).alignment = (TextAlignmentOptions)514;
			((TMP_Text)_scoreText).fontSize = 7.5f;
			((Graphic)_scoreText).color = Color.white;
			((Behaviour)_scoreText).enabled = false;
		}

		private void CreatePersonalBestText()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: 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_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("PersonalBestText", new Type[1] { typeof(RectTransform) });
			RectTransform component = val.GetComponent<RectTransform>();
			((Transform)component).SetParent((Transform)(object)_rootRect, false);
			component.anchorMin = new Vector2(0.5f, 0.5f);
			component.anchorMax = new Vector2(0.5f, 0.5f);
			component.pivot = new Vector2(0.5f, 0.5f);
			component.sizeDelta = new Vector2(_boardWidth + 90f, 18f);
			component.anchoredPosition = new Vector2(0f, -10f);
			_personalBestText = val.AddComponent<TextMeshProUGUI>();
			((TMP_Text)_personalBestText).text = "High-Score: 0";
			((TMP_Text)_personalBestText).alignment = (TextAlignmentOptions)514;
			((TMP_Text)_personalBestText).fontSize = 7f;
			((Graphic)_personalBestText).color = Color.white;
			((Behaviour)_personalBestText).enabled = false;
		}

		private void CreateRestartText()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: 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_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("RestartText", new Type[1] { typeof(RectTransform) });
			RectTransform component = val.GetComponent<RectTransform>();
			((Transform)component).SetParent((Transform)(object)_rootRect, false);
			component.anchorMin = new Vector2(0.5f, 0.5f);
			component.anchorMax = new Vector2(0.5f, 0.5f);
			component.pivot = new Vector2(0.5f, 0.5f);
			component.sizeDelta = new Vector2(_boardWidth + 90f, 18f);
			component.anchoredPosition = new Vector2(0f, -28f);
			_restartText = val.AddComponent<TextMeshProUGUI>();
			((TMP_Text)_restartText).text = "PRESS RIGHT TO RESTART";
			((TMP_Text)_restartText).alignment = (TextAlignmentOptions)514;
			((TMP_Text)_restartText).fontSize = 6f;
			((Graphic)_restartText).color = Color.white;
			((Behaviour)_restartText).enabled = false;
		}

		private void CreateQuitText()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: 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_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("QuitText", new Type[1] { typeof(RectTransform) });
			RectTransform component = val.GetComponent<RectTransform>();
			((Transform)component).SetParent((Transform)(object)_rootRect, false);
			component.anchorMin = new Vector2(0.5f, 0.5f);
			component.anchorMax = new Vector2(0.5f, 0.5f);
			component.pivot = new Vector2(0.5f, 0.5f);
			component.sizeDelta = new Vector2(_boardWidth + 90f, 18f);
			component.anchoredPosition = new Vector2(0f, -40f);
			_quitText = val.AddComponent<TextMeshProUGUI>();
			((TMP_Text)_quitText).text = "PRESS LEFT TO QUIT";
			((TMP_Text)_quitText).alignment = (TextAlignmentOptions)514;
			((TMP_Text)_quitText).fontSize = 6f;
			((Graphic)_quitText).color = Color.white;
			((Behaviour)_quitText).enabled = false;
		}

		private void UpdateCursor(int x, int y, float pushOffset)
		{
			//IL_007f: 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_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: 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_00cd: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_cursorImage == (Object)null))
			{
				((Behaviour)_cursorImage).enabled = _cursorFrames.Count > 0;
				if (_cursorFrames.Count != 0)
				{
					int index = (int)(Time.unscaledTime * 6f) % _cursorFrames.Count;
					_cursorImage.sprite = _cursorFrames[index];
					Vector2 val = GetCellPosition(x, y) + new Vector2(0f, pushOffset);
					Vector2 val2 = GetCellPosition(x + 1, y) + new Vector2(0f, pushOffset);
					Vector2 anchoredPosition = (val + val2) * 0.5f;
					((Graphic)_cursorImage).rectTransform.anchoredPosition = anchoredPosition;
				}
			}
		}

		private Vector2 GetCellPosition(int x, int y)
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			float num = (0f - _boardWidth) * 0.5f + _cellSize * 0.5f;
			float num2 = (0f - _boardHeight) * 0.5f + _cellSize * 0.5f;
			float num3 = num + (float)x * (_cellSize + _cellGap);
			float num4 = num2 + (float)y * (_cellSize + _cellGap);
			return new Vector2(num3, num4);
		}

		private Vector2 GetIncomingCellPosition(int x, float pushOffset)
		{
			//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_0056: Unknown result type (might be due to invalid IL or missing references)
			float num = (0f - _boardWidth) * 0.5f + _cellSize * 0.5f;
			float num2 = num + (float)x * (_cellSize + _cellGap);
			float num3 = (0f - _boardHeight) * 0.5f - _cellSize * 0.5f + pushOffset;
			return new Vector2(num2, num3);
		}
	}
	public static class PanelPonState
	{
		public static bool AppActive;
	}
	[HarmonyPatch(typeof(Player), "SetInputs")]
	public static class Player_SetInputs_PanelPonPatch
	{
		private static bool Prefix(Player __instance)
		{
			if (!PanelPonState.AppActive)
			{
				return true;
			}
			__instance.FlushInput();
			return false;
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}