Decompiled source of Score Attack Local Training v2.7.1

plugins/Score_Attack_Local_Training/ScoreAttackPlugin.dll

Decompiled 3 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Bootstrap;
using CommonAPI;
using CommonAPI.Phone;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Reptile;
using Reptile.Phone;
using ScoreAttack;
using ScoreAttack.Patches;
using ScoreAttackGhostSystem;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Networking;
using UnityEngine.Playables;
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: IgnoresAccessChecksTo("Unity.TextMeshPro")]
[assembly: AssemblyCompany("ScoreAttackPlugin")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("My first plugin")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("ScoreAttackPlugin")]
[assembly: AssemblyTitle("ScoreAttackPlugin")]
[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 ScoreAttackGhostSystem
{
	public class CrewBoomSupport
	{
		public static Guid GetGUID(int character)
		{
			Type typeByName = GetTypeByName("CrewBoomAPI.CrewBoomAPIDatabase");
			Dictionary<int, Guid> dictionary = typeByName.GetField("_userCharacters", BindingFlags.Static | BindingFlags.NonPublic).GetValue(null) as Dictionary<int, Guid>;
			return dictionary[character];
		}

		public static int GetCharacter(Guid guid)
		{
			Type typeByName = GetTypeByName("CrewBoomAPI.CrewBoomAPIDatabase");
			Dictionary<int, Guid> source = typeByName.GetField("_userCharacters", BindingFlags.Static | BindingFlags.NonPublic).GetValue(null) as Dictionary<int, Guid>;
			Dictionary<Guid, int> dictionary = source.ToDictionary((KeyValuePair<int, Guid> x) => x.Value, (KeyValuePair<int, Guid> x) => x.Key);
			return dictionary[guid];
		}

		public static Type GetTypeByName(string name)
		{
			foreach (Assembly item in AppDomain.CurrentDomain.GetAssemblies().Reverse())
			{
				Type type = item.GetType(name);
				if (type != null)
				{
					return type;
				}
			}
			return null;
		}
	}
	public class Ghost
	{
		private Player _player;

		private float _tickDelta;

		private List<GhostFrame> _frames;

		public int Character;

		public Guid CharacterGUID;

		public int Outfit;

		public bool HasOngoingScoreDataCached;

		public float TickDelta => _tickDelta;

		public Player Player => _player;

		public int FrameCount => _frames.Count;

		public float Length => (float)(FrameCount - 1) * _tickDelta;

		public List<GhostFrame> Frames => _frames;

		public float Score { get; set; }

		public float OngoingScore { get; set; }

		public bool HasOngoingScoreData => Frames.Any((GhostFrame f) => f.OngoingScore > 0f);

		public Ghost(float tickDelta)
		{
			_tickDelta = tickDelta;
			_frames = new List<GhostFrame>();
			Character = -1;
			Outfit = -1;
			Score = 0f;
			OngoingScore = 0f;
			HasOngoingScoreDataCached = false;
			base..ctor();
		}

		public void Init()
		{
			_player = WorldHandler.instance.GetCurrentPlayer();
		}

		public int GetFrameForTime(float time)
		{
			return Mathf.FloorToInt(time / _tickDelta);
		}

		public void CacheOngoingScoreData()
		{
			HasOngoingScoreDataCached = Frames.Any((GhostFrame f) => f.OngoingScore > 0f);
		}
	}
	public class GhostFrame
	{
		public class GhostFrameAnimation
		{
			public int ID;

			public float Time;

			public bool ForceOverwrite = false;

			public bool Instant = false;

			public float AtTime = -1f;
		}

		public class GhostFrameVisual
		{
			public Vector3 Position;

			public Quaternion Rotation;

			public BoostpackEffectMode boostpackEffectMode = (BoostpackEffectMode)0;

			public FrictionEffectMode frictionEffectMode = (FrictionEffectMode)0;

			public int dustEmission = 0;

			public float dustSize = 1f;

			public int spraypaintEmission = 0;

			public int ringEmission = 0;
		}

		public class GhostFrameEffects
		{
			public int ringParticles = -1;

			public int spraypaintParticles = -1;

			public bool DoJumpEffects = false;

			public bool DoHighJumpEffects = false;

			public Vector3 JumpEffects = Vector3.zero;

			public Vector3 HighJumpEffects = Vector3.zero;
		}

		public class GhostFrameSFX
		{
			public AudioClipID AudioClipID = (AudioClipID)(-1);

			public SfxCollectionID CollectionID = (SfxCollectionID)(-1);

			public float RandomPitchVariance = 0f;

			public bool Voice = false;
		}

		public int FrameIndex;

		public bool Valid = false;

		private Ghost _replay;

		public Vector3 PlayerPosition;

		public Quaternion PlayerRotation;

		public Vector3 Velocity;

		public float BaseScore;

		public float ScoreMultiplier;

		public float OngoingScore;

		public PhoneState PhoneState;

		public SpraycanState SpraycanState;

		public MoveStyle moveStyle;

		public MoveStyle equippedMoveStyle;

		public bool UsingEquippedMoveStyle;

		public GhostFrameAnimation Animation;

		public GhostFrameVisual Visual;

		public GhostFrameEffects Effects;

		public List<GhostFrameSFX> SFX;

		public GhostFrame(Ghost replay)
		{
			//IL_0010: 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)
			_replay = replay;
			PhoneState = (PhoneState)0;
			SpraycanState = (SpraycanState)0;
			Animation = new GhostFrameAnimation();
			Visual = new GhostFrameVisual();
			Effects = new GhostFrameEffects();
			SFX = new List<GhostFrameSFX>();
			base..ctor();
		}
	}
	public class GhostManager : MonoBehaviour
	{
		private static GhostManager _instance;

		private GhostState _currentGhostState = null;

		private GhostRecorder _ghostRecorder = new GhostRecorder();

		private GhostPlayer _ghostPlayer = new GhostPlayer();

		public static GhostManager Instance => _instance;

		public GhostState CurrentGhostState => _currentGhostState;

		public GhostRecorder GhostRecorder => _ghostRecorder;

		public GhostPlayer GhostPlayer => _ghostPlayer;

		public static GhostManager Create()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			GameObject val = new GameObject("Ghost Manager");
			return val.AddComponent<GhostManager>();
		}

		private void Awake()
		{
			_instance = this;
		}

		public void OnFixedUpdate()
		{
			if (!Core.instance.IsCorePaused || StartGraffitiModePatch.inGraffitiMode)
			{
				_currentGhostState?.OnFixedUpdate();
			}
		}

		private void OnDestroy()
		{
			_instance = null;
		}

		public GhostRecorder GetGhostRecorder()
		{
			return _ghostRecorder;
		}

		public GhostState GetGhostState()
		{
			return _currentGhostState;
		}

		public void RemoveCurrentGhostState()
		{
			_currentGhostState = null;
		}

		public void AddCurrentGhostState()
		{
			_currentGhostState = GetGhostRecorder();
		}
	}
	public class GhostPlayer : GhostState
	{
		public Ghost Replay;

		public Action OnFrameSkip;

		private bool _paused = false;

		private float _playbackSpeed = 1f;

		private float _currentTime = 0f;

		public static Player ghostPlayerCharacter;

		private bool developmentMode = false;

		private bool _isSpraying = false;

		public float BaseScore;

		public float ScoreMultiplier;

		public float LastAppliedOngoingScore;

		private SpraycanState _lastAppliedSpraycanState = (SpraycanState)0;

		public float CurrentTime => _currentTime;

		public bool ReplayEnded { get; private set; } = false;


		public bool Active { get; private set; } = false;


		public override void Start()
		{
			_currentTime = 0f;
			_paused = false;
			_playbackSpeed = 1f;
			ReplayEnded = false;
			ghostPlayerCharacter = SetupAIPlayer();
			Active = true;
			float tickDelta = Replay.TickDelta;
			float num = _currentTime % tickDelta;
			if (num != 0f)
			{
				float num2 = tickDelta - num;
				_currentTime += num2;
			}
			ScoreAttackPlugin.Instance.ResetCurrentTime();
			LastAppliedOngoingScore = 0f;
		}

		private Player SetupAIPlayer()
		{
			//IL_0029: 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_0131: Expected I4, but got Unknown
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: 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)
			WorldHandler instance = WorldHandler.instance;
			PlayerSpawner defaultPlayerSpawnPoint = instance.GetDefaultPlayerSpawnPoint();
			Player currentPlayer = WorldHandler.instance.GetCurrentPlayer();
			int outfit = Core.Instance.SaveManager.CurrentSaveSlot.GetCharacterProgress(currentPlayer.character).outfit;
			if (GhostSaveData.Instance.GhostModel != 0)
			{
				switch (GhostSaveData.Instance.GhostModel)
				{
				case GhostModel.DJCyber:
					Replay.Character = 9;
					break;
				case GhostModel.Faux:
					Replay.Character = 12;
					break;
				}
				Replay.Outfit = 0;
			}
			else
			{
				if (Replay.Character > 26)
				{
					_ = Replay.CharacterGUID;
					if (Replay.CharacterGUID != Guid.Empty)
					{
						try
						{
							Replay.Character = CrewBoomSupport.GetCharacter(Replay.CharacterGUID);
						}
						catch (Exception)
						{
							Replay.Character = -1;
						}
					}
				}
				if (Replay.Character == -1)
				{
					Replay.Character = (int)currentPlayer.character;
				}
				if (Replay.Outfit == -1)
				{
					Replay.Outfit = outfit;
				}
			}
			MoveStyle moveStyle = Replay.Frames[0].moveStyle;
			Player val = instance.SetupAIPlayerAt(((Component)defaultPlayerSpawnPoint).transform, (Characters)Replay.Character, (PlayerType)3, Replay.Outfit, moveStyle, (Crew)1);
			val.motor.gravity = 0f;
			val.motor.SetKinematic(true);
			((Behaviour)val.motor).enabled = false;
			val.moveStyleEquipped = Replay.Frames[0].equippedMoveStyle;
			val.DropCombo();
			val.StopCurrentAbility();
			if (GhostSaveData.Instance.GhostEffect == GhostEffect.Transparent)
			{
				MakePlayerGhostLOD(val, 0.3f);
			}
			if (AppGhostSettings.SoundMode != GhostSoundMode.Doppler)
			{
				AudioSource[] componentsInChildren = ((Component)val).GetComponentsInChildren<AudioSource>(true);
				AudioSource[] array = componentsInChildren;
				foreach (AudioSource val2 in array)
				{
					val2.dopplerLevel = 0f;
				}
			}
			else
			{
				AudioSource[] componentsInChildren2 = ((Component)val).GetComponentsInChildren<AudioSource>(true);
				AudioSource[] array2 = componentsInChildren2;
				foreach (AudioSource val3 in array2)
				{
					val3.dopplerLevel = 1f;
				}
			}
			if (AppGhostSettings.SoundMode == GhostSoundMode.Off)
			{
				AudioSource[] componentsInChildren3 = ((Component)val).GetComponentsInChildren<AudioSource>(true);
				AudioSource[] array3 = componentsInChildren3;
				foreach (AudioSource val4 in array3)
				{
					val4.mute = true;
				}
			}
			else
			{
				AudioSource[] componentsInChildren4 = ((Component)val).GetComponentsInChildren<AudioSource>(true);
				AudioSource[] array4 = componentsInChildren4;
				foreach (AudioSource val5 in array4)
				{
					val5.mute = false;
				}
			}
			return val;
		}

		public void SkipTo(float time)
		{
			if (time >= Replay.Length)
			{
				time = Replay.Length;
			}
			int num = Replay.GetFrameForTime(time);
			if (num >= Replay.FrameCount)
			{
				num = Replay.FrameCount - 1;
			}
			if (num < 0)
			{
				num = 0;
			}
			ApplyFrameToWorld(Replay.Frames[num], skip: true);
			_currentTime = (float)num * Replay.TickDelta;
		}

		public void EndReplay()
		{
			ReplayEnded = true;
			if ((Object)(object)ghostPlayerCharacter != (Object)null)
			{
				if (GhostSaveData.Instance.GhostEffect == GhostEffect.Transparent)
				{
					MakePlayerGhostLOD(ghostPlayerCharacter, 0.15f);
				}
				ghostPlayerCharacter.anim.speed = 0f;
			}
		}

		public void ApplyFrameToWorld(GhostFrame frame, bool skip)
		{
			//IL_0005: 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)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			ApplyFrameToWorld(frame, skip, frame.PlayerPosition, frame.PlayerRotation, frame.Visual.Position, frame.Visual.Rotation);
		}

		public void ApplyFrameToWorld(GhostFrame frame, bool skip, Vector3 interpPosition, Quaternion interpRotation, Vector3 interpPositionVisual, Quaternion interpRotationVisual)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0040: 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_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_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Invalid comparison between Unknown and I4
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: 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_0225: Unknown result type (might be due to invalid IL or missing references)
			//IL_022b: Invalid comparison between Unknown and I4
			//IL_02d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0335: Unknown result type (might be due to invalid IL or missing references)
			//IL_033b: Invalid comparison between Unknown and I4
			//IL_0387: Unknown result type (might be due to invalid IL or missing references)
			//IL_038d: Invalid comparison between Unknown and I4
			//IL_0365: Unknown result type (might be due to invalid IL or missing references)
			//IL_036c: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0401: Unknown result type (might be due to invalid IL or missing references)
			//IL_039b: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a5: Invalid comparison between Unknown and I4
			//IL_03a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b0: Invalid comparison between Unknown and I4
			//IL_03cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d6: Unknown result type (might be due to invalid IL or missing references)
			if (!frame.Valid)
			{
				return;
			}
			Player val = ghostPlayerCharacter;
			val.moveStyle = frame.moveStyle;
			val.moveStyleEquipped = frame.equippedMoveStyle;
			val.InitMovement(frame.moveStyle);
			val.SetMoveStyle(frame.moveStyle, true, false, (GameObject)null);
			val.SwitchToEquippedMovestyle(frame.UsingEquippedMoveStyle, false, true, false);
			if (frame.OngoingScore != 0f)
			{
				LastAppliedOngoingScore = frame.OngoingScore;
			}
			if (skip)
			{
				val.SwitchToEquippedMovestyle(frame.UsingEquippedMoveStyle, false, true, false);
				OnFrameSkip?.Invoke();
			}
			ApplyInterpolationToWorld(skip, interpPosition, interpRotation, interpPositionVisual, interpRotationVisual);
			val.SetVelocity(frame.Velocity);
			val.SetBoostpackAndFrictionEffects(frame.Visual.boostpackEffectMode, frame.Visual.frictionEffectMode);
			val.SetDustEmission(frame.Visual.dustEmission);
			val.SetDustSize(frame.Visual.dustSize);
			val.SetSpraypaintEmission(frame.Visual.spraypaintEmission);
			val.SetRingEmission(frame.Visual.ringEmission);
			if (frame.SpraycanState != _lastAppliedSpraycanState)
			{
				val.SetSpraycanState(frame.SpraycanState);
				_lastAppliedSpraycanState = frame.SpraycanState;
				if ((int)frame.SpraycanState == 3)
				{
					val.anim.Play(val.canSprayHash, 1, 0f);
				}
			}
			else
			{
				val.spraycanState = frame.SpraycanState;
			}
			if (frame.SpraycanState != _lastAppliedSpraycanState)
			{
				Debug.Log((object)$"[ScoreAttack] Ghost SpraycanState changed to: {frame.SpraycanState}");
				_lastAppliedSpraycanState = frame.SpraycanState;
			}
			else if (_isSpraying)
			{
				Debug.Log((object)"[ScoreAttack] Replaying spray animation");
			}
			bool flag = frame.Animation.AtTime != -1f;
			float num = ((!flag) ? frame.Animation.Time : frame.Animation.AtTime);
			if ((int)frame.SpraycanState == 0 || flag)
			{
				val.PlayAnim(frame.Animation.ID, frame.Animation.ForceOverwrite, frame.Animation.Instant, num);
			}
			if (frame.Effects.ringParticles > 0)
			{
				val.ringParticles.Emit(frame.Effects.ringParticles);
			}
			if (frame.Effects.spraypaintParticles > 0)
			{
				val.spraypaintParticles.Emit(frame.Effects.spraypaintParticles);
			}
			if (frame.Effects.DoJumpEffects)
			{
				val.DoJumpEffects(frame.Effects.JumpEffects);
			}
			if (frame.Effects.DoHighJumpEffects)
			{
				val.DoHighJumpEffects(frame.Effects.HighJumpEffects);
			}
			if (AppGhostSettings.SoundMode != 0)
			{
				foreach (GhostFrame.GhostFrameSFX item in frame.SFX)
				{
					if ((int)item.AudioClipID == -1)
					{
						continue;
					}
					if (item.Voice)
					{
						val.audioManager.PlayVoice(ref val.currentVoicePriority, val.character, item.AudioClipID, val.playerGameplayVoicesAudioSource, (VoicePriority)0);
					}
					else if ((int)item.CollectionID != -1)
					{
						if (((int)item.AudioClipID != 130 && (int)item.AudioClipID != 114) || frame.Effects.DoHighJumpEffects)
						{
							val.audioManager.PlaySfxGameplay(item.CollectionID, item.AudioClipID, val.playerOneShotAudioSource, item.RandomPitchVariance);
						}
					}
					else
					{
						val.audioManager.PlaySfxGameplay(frame.moveStyle, item.AudioClipID, val.playerOneShotAudioSource, item.RandomPitchVariance);
					}
				}
			}
			Collider[] componentsInChildren = ((Component)val).GetComponentsInChildren<Collider>(true);
			foreach (Collider val2 in componentsInChildren)
			{
				if (!((Object)(object)val2 == (Object)null))
				{
					val2.enabled = false;
				}
			}
		}

		public void ApplyInterpolationToWorld(bool skip, Vector3 interpPosition, Quaternion interpRotation, Vector3 interpPositionVisual, Quaternion interpRotationVisual)
		{
			//IL_0026: 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_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			Player val = ghostPlayerCharacter;
			if (skip)
			{
				WorldHandler.instance.PlacePlayerAt(val, interpPosition, interpRotation, true);
			}
			else
			{
				((Component)val).transform.position = interpPosition;
				((Component)val).transform.rotation = interpRotation;
			}
			((Component)val.characterVisual).transform.position = interpPositionVisual;
			((Component)val.characterVisual).transform.rotation = interpRotationVisual;
		}

		public override void End()
		{
			Active = false;
			((Component)Core.instance.UIManager).gameObject.SetActive(true);
			Time.timeScale = 1f;
			if (!((Object)(object)ghostPlayerCharacter != (Object)null))
			{
				return;
			}
			WorldHandler instance = WorldHandler.instance;
			if (instance != null)
			{
				SceneObjectsRegister sceneObjectsRegister = instance.SceneObjectsRegister;
				if (sceneObjectsRegister != null && sceneObjectsRegister.players != null)
				{
					instance.SceneObjectsRegister.players.Remove(ghostPlayerCharacter);
				}
			}
			Object.Destroy((Object)(object)((Component)ghostPlayerCharacter).gameObject);
		}

		private void RefreshTimeScale()
		{
			if (_paused)
			{
				Time.timeScale = 0f;
			}
			else
			{
				Time.timeScale = _playbackSpeed;
			}
		}

		public override void OnUpdate()
		{
			UpdatePlaybackInput();
			RefreshTimeScale();
		}

		private void UpdatePlaybackInput()
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			if (developmentMode)
			{
				if (Input.GetKeyDown((KeyCode)32))
				{
					_paused = !_paused;
				}
				_playbackSpeed += Input.mouseScrollDelta.y * 0.05f;
				if (_playbackSpeed <= 0f)
				{
					_playbackSpeed = 0f;
				}
				if (Input.GetKeyDown((KeyCode)114))
				{
					_playbackSpeed = 1f;
					_paused = false;
				}
				if (Input.GetKeyDown((KeyCode)8))
				{
					_currentTime = 0f;
				}
				if (Input.GetKeyDown((KeyCode)104))
				{
					((Component)Core.instance.UIManager).gameObject.SetActive(!((Component)Core.instance.UIManager).gameObject.activeSelf);
				}
				if (Input.GetKeyDown((KeyCode)48))
				{
					SkipTo(0f);
				}
				if (Input.GetKeyDown((KeyCode)49))
				{
					SkipTo(Replay.Length * 0.25f);
				}
				if (Input.GetKeyDown((KeyCode)50))
				{
					SkipTo(Replay.Length * 0.5f);
				}
				if (Input.GetKeyDown((KeyCode)51))
				{
					SkipTo(Replay.Length * 0.75f);
				}
				if (Input.GetKeyDown((KeyCode)52))
				{
					SkipTo(Replay.Length);
				}
			}
		}

		private static void MakePlayerGhostLOD(Player player, float alpha)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			Material val = new Material(Shader.Find("Sprites/Default"));
			val.color = new Color(1f, 1f, 1f, alpha);
			val.SetInt("_ZTest", 8);
			val.SetInt("_ZWrite", 0);
			val.renderQueue = 4000;
			PlayerVisualEffects vFX = player.characterVisual.VFX;
			PlayerMoveStyleProps moveStyleProps = player.characterVisual.moveStyleProps;
			GameObject[] source = (GameObject[])(object)new GameObject[30]
			{
				vFX.circleBoostEffect, vFX.jumpEffect, vFX.frictionEffect, vFX.frictionBlueEffect, vFX.boostpackEffect, vFX.boostpackBlueEffect, vFX.boostpackTrail, vFX.spraycan, vFX.spraycanCap, vFX.spraypaint,
				vFX.graffitiSlash, vFX.graffitiFinishEffect, vFX.graffitiFinishLargeEffect, vFX.phone, vFX.dust, vFX.ring, vFX.hitEffect, vFX.getHitEffect, vFX.highJumpEffect, moveStyleProps.bmxFrame,
				moveStyleProps.bmxHandlebars, moveStyleProps.bmxWheelF, moveStyleProps.bmxWheelR, moveStyleProps.bmxGear, moveStyleProps.bmxPedalL, moveStyleProps.bmxPedalR, moveStyleProps.skateboard, moveStyleProps.skateR, moveStyleProps.skateL, moveStyleProps.specialSkateBoard
			};
			Renderer[] componentsInChildren = ((Component)player).GetComponentsInChildren<Renderer>(true);
			Renderer[] array = componentsInChildren;
			foreach (Renderer val2 in array)
			{
				if ((Object)(object)val2 != (Object)null)
				{
					if (val2 is TrailRenderer && !source.Contains(((Component)val2).gameObject))
					{
						((Component)val2).gameObject.SetActive(false);
					}
					Material[] array2 = (Material[])(object)new Material[val2.materials.Length];
					for (int j = 0; j < array2.Length; j++)
					{
						array2[j] = val;
					}
					val2.materials = array2;
				}
			}
		}
	}
	public class GhostRecorder : GhostState
	{
		public static GhostRecorder Instance;

		public InputBuffer CurrentInput;

		private Ghost _currentReplay;

		public bool Recording { get; private set; } = false;


		public Ghost Replay => _currentReplay;

		public GhostFrame LastFrame => (_currentReplay.Frames.Count > 1) ? _currentReplay.Frames[_currentReplay.Frames.Count - 1] : null;

		public override void Start()
		{
			_currentReplay = new Ghost(ScoreAttackPlugin.ghostTickInterval);
			_currentReplay.Init();
			Instance = this;
			Recording = true;
		}

		public override void End()
		{
			Instance = null;
			Recording = false;
		}

		public void OnPlayerInput(Player player)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)WorldHandler.instance.GetCurrentPlayer() != (Object)(object)player))
			{
				CurrentInput = player.inputBuffer;
			}
		}

		public override void OnFixedUpdate()
		{
			if (Recording)
			{
				if ((Object)(object)ScoreAttackManager.Encounter == (Object)null || !ScoreAttackEncounter.IsScoreAttackActive())
				{
					Debug.Log((object)"[Score Attack] Stopping recording: Score Attack is no longer active.");
					End();
				}
				else if ((Object)(object)_currentReplay.Player == (Object)null)
				{
					Debug.Log((object)"[GhostRecorder] Stopping recording: Player is no longer valid.");
					End();
				}
				else
				{
					RecordCurrentFrame();
				}
			}
		}

		private void RecordCurrentFrame()
		{
			//IL_029f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Expected I4, but got Unknown
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Invalid comparison between Unknown and I4
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			//IL_023b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0240: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: Unknown result type (might be due to invalid IL or missing references)
			//IL_0249: Unknown result type (might be due to invalid IL or missing references)
			//IL_026e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0273: Unknown result type (might be due to invalid IL or missing references)
			//IL_0277: Unknown result type (might be due to invalid IL or missing references)
			//IL_027c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: 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_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: 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_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: 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_01bc: 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_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Expected I4, but got Unknown
			//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: 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)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			GhostFrame ghostFrame = new GhostFrame(_currentReplay)
			{
				FrameIndex = _currentReplay.Frames.Count
			};
			_currentReplay.Frames.Add(ghostFrame);
			if ((Object)(object)_currentReplay.Player == (Object)null)
			{
				return;
			}
			Player player = _currentReplay.Player;
			ghostFrame.Valid = true;
			if (_currentReplay.Character == -1)
			{
				_currentReplay.Character = (int)player.character;
				if ((int)player.character > 26)
				{
					_currentReplay.CharacterGUID = CrewBoomSupport.GetGUID((int)player.character);
				}
			}
			if (_currentReplay.Outfit == -1)
			{
				_currentReplay.Outfit = Core.Instance.SaveManager.CurrentSaveSlot.GetCharacterProgress(player.character).outfit;
			}
			ghostFrame.PlayerPosition = ((Component)player).transform.position;
			ghostFrame.PlayerRotation = ((Component)player).transform.rotation;
			ghostFrame.Velocity = player.GetVelocity();
			ghostFrame.BaseScore = player.baseScore;
			ghostFrame.ScoreMultiplier = player.scoreMultiplier;
			ghostFrame.SpraycanState = player.spraycanState;
			ghostFrame.moveStyle = player.moveStyle;
			ghostFrame.equippedMoveStyle = player.moveStyleEquipped;
			ghostFrame.UsingEquippedMoveStyle = player.usingEquippedMovestyle;
			ghostFrame.Animation.ID = player.curAnim;
			ghostFrame.Animation.Time = player.anim.playbackTime;
			ghostFrame.Visual.Position = player.characterVisual.tf.position;
			ghostFrame.Visual.Rotation = player.characterVisual.tf.rotation;
			EmissionModule emission;
			MinMaxCurve rateOverTime;
			try
			{
				GhostFrame.GhostFrameVisual visual = ghostFrame.Visual;
				emission = player.characterVisual.dustParticles.emission;
				rateOverTime = ((EmissionModule)(ref emission)).rateOverTime;
				visual.dustEmission = (int)((MinMaxCurve)(ref rateOverTime)).constant;
			}
			catch (Exception)
			{
			}
			try
			{
				ghostFrame.Visual.dustSize = player.characterVisual.VFX.dust.transform.localScale.x;
			}
			catch (Exception)
			{
			}
			try
			{
				GhostFrame.GhostFrameVisual visual2 = ghostFrame.Visual;
				emission = player.spraypaintParticles.emission;
				rateOverTime = ((EmissionModule)(ref emission)).rateOverTime;
				visual2.spraypaintEmission = (int)((MinMaxCurve)(ref rateOverTime)).constant;
			}
			catch (Exception)
			{
			}
			try
			{
				GhostFrame.GhostFrameVisual visual3 = ghostFrame.Visual;
				emission = player.ringParticles.emission;
				rateOverTime = ((EmissionModule)(ref emission)).rateOverTime;
				visual3.ringEmission = (int)((MinMaxCurve)(ref rateOverTime)).constant;
			}
			catch (Exception)
			{
			}
			ghostFrame.Visual.boostpackEffectMode = player.characterVisual.boostpackEffectMode;
			ghostFrame.Visual.frictionEffectMode = player.characterVisual.frictionEffectMode;
		}
	}
	public abstract class GhostState
	{
		public virtual void Start()
		{
		}

		public virtual void OnFixedUpdate()
		{
		}

		public virtual void End()
		{
		}

		public virtual void OnUpdate()
		{
		}
	}
}
namespace ScoreAttackGhostSystem.Patches
{
	[HarmonyPatch]
	internal class GhostPatch
	{
		[HarmonyPatch(typeof(MoveAlongPoints))]
		public static class Hitbox_HitboxHitPlayer_Patch
		{
			[HarmonyPrefix]
			[HarmonyPatch("HitboxHitPlayer")]
			public static bool Prefix_HitboxHitPlayer(Player player)
			{
				return (Object)(object)player != (Object)(object)GhostPlayer.ghostPlayerCharacter;
			}
		}

		[HarmonyPatch(typeof(MoveAlongHandler))]
		public static class MoveAlongHandler_GetCurrentPlayer_Patch
		{
			[HarmonyPrefix]
			[HarmonyPatch("GetCurrentPlayer")]
			public static bool Prefix_GetCurrentPlayer(MoveAlongHandler __instance, ref Player __result)
			{
				if ((Object)(object)GhostPlayer.ghostPlayerCharacter != (Object)null && (Object)(object)WorldHandler.instance.GetCurrentPlayer() == (Object)(object)GhostPlayer.ghostPlayerCharacter)
				{
					__result = null;
					return false;
				}
				return true;
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(BreakableObject), "CheckSetPlayerFromHitbox")]
		private static bool CheckSetPlayerFromHitbox_Prefix(BreakableObject __instance, Collider newCollider)
		{
			if ((Object)(object)__instance.curCollider == (Object)(object)newCollider)
			{
				return false;
			}
			Player componentInParent = ((Component)((Component)newCollider).transform).GetComponentInParent<Player>();
			if ((Object)(object)componentInParent == (Object)(object)GhostPlayer.ghostPlayerCharacter || componentInParent.isAI)
			{
				return false;
			}
			return true;
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(ParticleSystem))]
		[HarmonyPatch("Emit", new Type[] { typeof(int) })]
		private static void SetFrameEmit(int count, ParticleSystem __instance)
		{
			WorldHandler instance = WorldHandler.instance;
			if ((Object)(object)((instance != null) ? instance.GetCurrentPlayer() : null) == (Object)null)
			{
				return;
			}
			WorldHandler instance2 = WorldHandler.instance;
			Player val = ((instance2 != null) ? instance2.GetCurrentPlayer() : null);
			if (GhostRecorder.Instance != null && GhostRecorder.Instance.Recording && GhostRecorder.Instance.LastFrame != null)
			{
				if ((Object)(object)__instance == (Object)(object)val.ringParticles)
				{
					GhostRecorder.Instance.LastFrame.Effects.ringParticles = count;
				}
				if ((Object)(object)__instance == (Object)(object)val.spraypaintParticles)
				{
					GhostRecorder.Instance.LastFrame.Effects.spraypaintParticles = count;
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(AudioManager))]
		[HarmonyPatch("PlaySfxGameplay", new Type[]
		{
			typeof(SfxCollectionID),
			typeof(AudioClipID),
			typeof(AudioSource),
			typeof(float)
		})]
		private static void SetSFXGameplayAlt(SfxCollectionID collectionId, AudioClipID audioClipId, AudioSource audioSource, float randomPitchVariance)
		{
			//IL_0087: 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_008e: 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)
			WorldHandler instance = WorldHandler.instance;
			if (!((Object)(object)((instance != null) ? instance.GetCurrentPlayer() : null) == (Object)null))
			{
				WorldHandler instance2 = WorldHandler.instance;
				if (!((Object)(object)audioSource != (Object)(object)((instance2 != null) ? instance2.GetCurrentPlayer().playerOneShotAudioSource : null)) && GhostRecorder.Instance != null && GhostRecorder.Instance.Recording && GhostRecorder.Instance.LastFrame != null)
				{
					GhostRecorder.Instance.LastFrame.SFX.Add(new GhostFrame.GhostFrameSFX
					{
						CollectionID = collectionId,
						AudioClipID = audioClipId,
						RandomPitchVariance = randomPitchVariance
					});
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(AudioManager))]
		[HarmonyPatch("PlaySfxGameplay", new Type[]
		{
			typeof(MoveStyle),
			typeof(AudioClipID),
			typeof(AudioSource),
			typeof(float)
		})]
		private static void SetSFXGameplay(MoveStyle moveStyle, AudioClipID audioClipId, AudioSource audioSource, float randomPitchVariance)
		{
			//IL_0084: 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)
			WorldHandler instance = WorldHandler.instance;
			if (!((Object)(object)((instance != null) ? instance.GetCurrentPlayer() : null) == (Object)null))
			{
				WorldHandler instance2 = WorldHandler.instance;
				if (!((Object)(object)audioSource != (Object)(object)((instance2 != null) ? instance2.GetCurrentPlayer().playerOneShotAudioSource : null)) && GhostRecorder.Instance != null && GhostRecorder.Instance.Recording && GhostRecorder.Instance.LastFrame != null)
				{
					GhostRecorder.Instance.LastFrame.SFX.Add(new GhostFrame.GhostFrameSFX
					{
						AudioClipID = audioClipId,
						RandomPitchVariance = randomPitchVariance
					});
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(AudioManager))]
		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		private static void SetSFXGameplay(ref VoicePriority currentPriority, Characters character, AudioClipID audioClipID, AudioSource audioSource, VoicePriority playbackPriority)
		{
			//IL_0084: 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)
			WorldHandler instance = WorldHandler.instance;
			if (!((Object)(object)((instance != null) ? instance.GetCurrentPlayer() : null) == (Object)null))
			{
				WorldHandler instance2 = WorldHandler.instance;
				if (!((Object)(object)audioSource != (Object)(object)((instance2 != null) ? instance2.GetCurrentPlayer().playerGameplayVoicesAudioSource : null)) && GhostRecorder.Instance != null && GhostRecorder.Instance.Recording && GhostRecorder.Instance.LastFrame != null)
				{
					GhostRecorder.Instance.LastFrame.SFX.Add(new GhostFrame.GhostFrameSFX
					{
						AudioClipID = audioClipID,
						Voice = true
					});
				}
			}
		}
	}
	[HarmonyPatch(typeof(Player))]
	internal class GhostPlayerPatch
	{
		[HarmonyPatch(typeof(Player), "OnTriggerStay")]
		public class Patch_Player_OnTriggerStay
		{
			[HarmonyPrefix]
			public static bool OnTriggerStay_Prefix(Collider other, Player __instance)
			{
				if ((Object)(object)__instance != (Object)(object)GhostPlayer.ghostPlayerCharacter)
				{
					return true;
				}
				return false;
			}
		}

		[HarmonyPatch(typeof(Player), "StopHoldSpraycan")]
		internal class Player_StopHoldSpraycan_Patch
		{
			[HarmonyPrefix]
			private static bool Prefix(Player __instance)
			{
				if ((Object)(object)__instance == (Object)(object)GhostPlayer.ghostPlayerCharacter)
				{
					return false;
				}
				return true;
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(Player), "PlayVoice")]
		private static bool PlayVoice_Prefix(Player __instance)
		{
			if ((Object)(object)__instance == (Object)(object)GhostPlayer.ghostPlayerCharacter)
			{
				return false;
			}
			return true;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(Player), "InitHitboxes")]
		private static bool InitHitboxes_Prefix(Player __instance)
		{
			if ((Object)(object)__instance == (Object)(object)GhostPlayer.ghostPlayerCharacter)
			{
				return false;
			}
			return true;
		}

		[HarmonyPrefix]
		[HarmonyPatch("FixedUpdatePlayer")]
		[HarmonyPatch("UpdatePlayer")]
		private static bool FixedUpdate_Prefix(Player __instance)
		{
			return (Object)(object)__instance != (Object)(object)GhostPlayer.ghostPlayerCharacter;
		}

		[HarmonyPostfix]
		[HarmonyPatch("PlayAnim")]
		private static void SetFrameAnim(int newAnim, bool forceOverwrite, bool instant, float atTime, Player __instance)
		{
			WorldHandler instance = WorldHandler.instance;
			if (!((Object)(object)__instance != (Object)(object)((instance != null) ? instance.GetCurrentPlayer() : null)) && GhostRecorder.Instance != null && GhostRecorder.Instance.Recording && GhostRecorder.Instance.LastFrame != null)
			{
				GhostRecorder.Instance.LastFrame.Animation.Instant = instant;
				GhostRecorder.Instance.LastFrame.Animation.AtTime = atTime;
				GhostRecorder.Instance.LastFrame.Animation.ForceOverwrite = forceOverwrite;
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("DoJumpEffects")]
		private static void SetFrameJumpEffects(Vector3 dir, Player __instance)
		{
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			WorldHandler instance = WorldHandler.instance;
			if (!((Object)(object)__instance != (Object)(object)((instance != null) ? instance.GetCurrentPlayer() : null)) && GhostRecorder.Instance != null && GhostRecorder.Instance.Recording && GhostRecorder.Instance.LastFrame != null)
			{
				GhostRecorder.Instance.LastFrame.Effects.DoJumpEffects = true;
				GhostRecorder.Instance.LastFrame.Effects.JumpEffects = dir;
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("DoHighJumpEffects")]
		private static void SetFrameHighJumpEffects(Vector3 dir, Player __instance)
		{
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			WorldHandler instance = WorldHandler.instance;
			if (!((Object)(object)__instance != (Object)(object)((instance != null) ? instance.GetCurrentPlayer() : null)) && GhostRecorder.Instance != null && GhostRecorder.Instance.Recording && GhostRecorder.Instance.LastFrame != null)
			{
				GhostRecorder.Instance.LastFrame.Effects.DoHighJumpEffects = true;
				GhostRecorder.Instance.LastFrame.Effects.HighJumpEffects = dir;
			}
		}
	}
}
namespace ScoreAttack
{
	public enum SFXToggle
	{
		Default,
		DefaultPlus,
		LLB,
		FZero,
		POPN,
		SSBM,
		SF3S,
		Skullgirls
	}
	public class AppExtras : CustomApp
	{
		public override bool Available => false;

		public static SFXToggle SFXMode { get; private set; }

		public static void Initialize()
		{
			PhoneAPI.RegisterApp<AppExtras>("extras", (Sprite)null);
		}

		public override void OnAppInit()
		{
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: 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_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			((CustomApp)this).OnAppInit();
			LoadState();
			((CustomApp)this).CreateIconlessTitleBar(GetExtrasTitle(), 80f);
			base.ScrollView = PhoneScrollView.Create((CustomApp)(object)this, 275f, 1600f);
			SimplePhoneButton toggle = PhoneUIUtility.CreateSimpleButton(GetViewerLabel());
			SimplePhoneButton obj = toggle;
			((PhoneButton)obj).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj).OnConfirm, (Action)delegate
			{
				SFXMode = GetNextMode(SFXMode);
				SaveState();
				((TMP_Text)toggle.Label).SetText(GetViewerLabel(), true);
				((CustomApp)this).CreateIconlessTitleBar(GetExtrasTitle(), 80f);
			});
			base.ScrollView.AddButton((PhoneButton)(object)toggle);
			SimplePhoneButton val = PhoneUIUtility.CreateSimpleButton("Open Leaderboard\n<size=50%>Opens in your default browser!</size>");
			((PhoneButton)val).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val).OnConfirm, (Action)delegate
			{
				OpenSpreadsheetInBrowser();
			});
			base.ScrollView.AddButton((PhoneButton)(object)val);
			SimplePhoneButton val2 = PhoneUIUtility.CreateSimpleButton("Export Save Data\n<size=50%>Back up your settings and records</size>");
			((PhoneButton)val2).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val2).OnConfirm, (Action)delegate
			{
				if (ScoreAttackEncounter.IsScoreAttackActive())
				{
					Debug.LogError((object)"Can't export save data during a battle!");
					Core.Instance.UIManager.ShowNotification("You are in a run! Cancel your current run before exporting your save file.", Array.Empty<string>());
				}
				else
				{
					string text2 = SaveManager.ExportSaveData();
					Core.Instance.UIManager.ShowNotification("Save Data Exported!\n<size=50%>" + text2 + "</size>", Array.Empty<string>());
				}
			});
			val2.LabelUnselectedColor = Color.black;
			val2.LabelSelectedColor = Color.red;
			base.ScrollView.AddButton((PhoneButton)(object)val2);
			SimplePhoneButton val3 = PhoneUIUtility.CreateSimpleButton("Import Save Data\n<size=50%>Load settings config and records</size>");
			((PhoneButton)val3).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val3).OnConfirm, (Action)delegate
			{
				if (ScoreAttackEncounter.IsScoreAttackActive())
				{
					Debug.LogError((object)"Can't import save data during a battle!");
					Core.Instance.UIManager.ShowNotification("You are in a run! Cancel your current run before importing a new save file.", Array.Empty<string>());
				}
				else
				{
					string text = SaveManager.ImportSaveData();
					if (string.IsNullOrEmpty(text))
					{
						Core.Instance.UIManager.ShowNotification("No save file found to import.", Array.Empty<string>());
					}
					else
					{
						Core.Instance.UIManager.ShowNotification("Save Data Imported!\n<size=50%>" + text + "</size>", Array.Empty<string>());
					}
				}
			});
			val3.LabelUnselectedColor = Color.black;
			val3.LabelSelectedColor = Color.red;
			base.ScrollView.AddButton((PhoneButton)(object)val3);
		}

		public override void OnAppDisable()
		{
			((MonoBehaviour)Core.Instance).StartCoroutine(ScoreAttackManager.Encounter.LoadAnnouncerClips());
			((App)this).OnAppDisable();
		}

		private static string GetViewerLabel()
		{
			string text = ((SFXMode == SFXToggle.Default) ? "white" : "yellow");
			return "Score Attack SFX \n<size=50%><color=" + text + ">" + GetFormattedEnumName(SFXMode) + "</color></size>";
		}

		private static string GetFormattedEnumName(SFXToggle mode)
		{
			return mode switch
			{
				SFXToggle.Default => "Default SFX", 
				SFXToggle.DefaultPlus => "Default Plus SFX", 
				SFXToggle.LLB => "Lethal League Blaze SFX", 
				SFXToggle.FZero => "F-Zero GX SFX", 
				SFXToggle.POPN => "Pop'n Music SFX", 
				SFXToggle.SSBM => "Smash Bros. Melee SFX", 
				SFXToggle.SF3S => "Street Fighter III 3rd Strike SFX", 
				SFXToggle.Skullgirls => "Skullgirls SFX", 
				_ => mode.ToString(), 
			};
		}

		private static SFXToggle GetNextMode(SFXToggle current)
		{
			return (SFXToggle)((int)(current + 1) % Enum.GetValues(typeof(SFXToggle)).Length);
		}

		private void LoadState()
		{
			try
			{
				SFXMode = ScoreAttackSaveData.Instance.ExtraSFXMode;
			}
			catch
			{
				SFXMode = SFXToggle.Default;
			}
		}

		private void SaveState()
		{
			ScoreAttackSaveData.Instance.ExtraSFXMode = SFXMode;
			Core.Instance.SaveManager.SaveCurrentSaveSlot();
			Debug.Log((object)$"[ScoreAttack] Saved SFXMode: {SFXMode}");
		}

		private static string GetExtrasTitle()
		{
			return "Extras\n<size=50%>Experimental!</size>";
		}

		private void OpenSpreadsheetInBrowser()
		{
			string text = "https://docs.google.com/spreadsheets/d/e/2PACX-1vQPLU_jkIHBLmvsMqjotXKyeUZ2veHfseqzD_aMRI29b6Mb92c0o5l8WUdDPCp1s4xVwyLwgYHBiYa7/pubhtml";
			Application.OpenURL(text);
			Core.Instance.UIManager.ShowNotification("<size=75%><color=yellow>Vanilla Score Attack Leaderboard</color> opened in your default web browser! </size>\n<size=50%>You can also go to <color=yellow>sloppers.club/leaderboard</color> to view/submit vanilla score attack runs!</size>", Array.Empty<string>());
		}
	}
	public class AppFPSLimit : CustomApp
	{
		public class VSyncWatcher : MonoBehaviour
		{
			private float timer = 0f;

			private string lastTitle = "";

			private void Update()
			{
				timer += Time.deltaTime;
				if (!(timer >= 0.5f))
				{
					return;
				}
				timer = 0f;
				string text = StaticGetFpsTitle();
				if (text != lastTitle)
				{
					lastTitle = text;
					if ((Object)(object)Instance != (Object)null)
					{
						Instance.ForceTitleRefresh(text);
					}
				}
			}
		}

		public bool LimitFramerate = false;

		public int FpsLimit = 60;

		public int CurrentFps = 60;

		private float refreshTimer = 0f;

		private string lastTitle = "";

		public static AppFPSLimit Instance;

		public override bool Available => false;

		public static void Initialize()
		{
			PhoneAPI.RegisterApp<AppFPSLimit>("fps select", (Sprite)null);
		}

		public override void OnAppInit()
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected O, but got Unknown
			((CustomApp)this).OnAppInit();
			Instance = this;
			((CustomApp)this).CreateIconlessTitleBar(GetFpsTitle(), 80f);
			if ((Object)(object)GameObject.Find("VSyncWatcher") == (Object)null)
			{
				GameObject val = new GameObject("VSyncWatcher");
				Object.DontDestroyOnLoad((Object)(object)val);
				val.AddComponent<VSyncWatcher>();
			}
			base.ScrollView = PhoneScrollView.Create((CustomApp)(object)this, 275f, 1600f);
			SimplePhoneButton val2 = PhoneUIUtility.CreateSimpleButton("30 fps");
			SimplePhoneButton obj = val2;
			((PhoneButton)obj).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj).OnConfirm, (Action)delegate
			{
				SetTargetFrameRate(30);
				Core.Instance.UIManager.ShowNotification("FPS Limit has been set to 30! \nMake sure " + GetColoredVSyncText() + " is off for it to go into effect.", Array.Empty<string>());
			});
			base.ScrollView.AddButton((PhoneButton)(object)val2);
			val2 = PhoneUIUtility.CreateSimpleButton("40 fps");
			SimplePhoneButton obj2 = val2;
			((PhoneButton)obj2).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj2).OnConfirm, (Action)delegate
			{
				SetTargetFrameRate(40);
				Core.Instance.UIManager.ShowNotification("FPS Limit has been set to 40! \nMake sure " + GetColoredVSyncText() + " is off for it to go into effect.", Array.Empty<string>());
			});
			base.ScrollView.AddButton((PhoneButton)(object)val2);
			val2 = PhoneUIUtility.CreateSimpleButton("60 fps");
			SimplePhoneButton obj3 = val2;
			((PhoneButton)obj3).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj3).OnConfirm, (Action)delegate
			{
				SetTargetFrameRate(60);
				Core.Instance.UIManager.ShowNotification("FPS Limit has been set to 60! \nMake sure " + GetColoredVSyncText() + " is off for it to go into effect.", Array.Empty<string>());
			});
			base.ScrollView.AddButton((PhoneButton)(object)val2);
			val2 = PhoneUIUtility.CreateSimpleButton("90 fps");
			SimplePhoneButton obj4 = val2;
			((PhoneButton)obj4).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj4).OnConfirm, (Action)delegate
			{
				SetTargetFrameRate(90);
				Core.Instance.UIManager.ShowNotification("FPS Limit has been set to 90! \nMake sure " + GetColoredVSyncText() + " is off for it to go into effect.", Array.Empty<string>());
			});
			base.ScrollView.AddButton((PhoneButton)(object)val2);
			val2 = PhoneUIUtility.CreateSimpleButton("120 fps");
			SimplePhoneButton obj5 = val2;
			((PhoneButton)obj5).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj5).OnConfirm, (Action)delegate
			{
				SetTargetFrameRate(120);
				Core.Instance.UIManager.ShowNotification("FPS Limit has been set to 120! \nMake sure " + GetColoredVSyncText() + " is off for it to go into effect.", Array.Empty<string>());
			});
			base.ScrollView.AddButton((PhoneButton)(object)val2);
			val2 = PhoneUIUtility.CreateSimpleButton("144 fps");
			SimplePhoneButton obj6 = val2;
			((PhoneButton)obj6).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj6).OnConfirm, (Action)delegate
			{
				SetTargetFrameRate(144);
				Core.Instance.UIManager.ShowNotification("FPS Limit has been set to 144! \nMake sure " + GetColoredVSyncText() + " is off for it to go into effect.", Array.Empty<string>());
			});
			base.ScrollView.AddButton((PhoneButton)(object)val2);
			val2 = PhoneUIUtility.CreateSimpleButton("240 fps");
			SimplePhoneButton obj7 = val2;
			((PhoneButton)obj7).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj7).OnConfirm, (Action)delegate
			{
				SetTargetFrameRate(240);
				Core.Instance.UIManager.ShowNotification("FPS Limit has been set to 240! \nMake sure " + GetColoredVSyncText() + " is off for it to go into effect.", Array.Empty<string>());
			});
			base.ScrollView.AddButton((PhoneButton)(object)val2);
			val2 = PhoneUIUtility.CreateSimpleButton("Unlimited");
			SimplePhoneButton obj8 = val2;
			((PhoneButton)obj8).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj8).OnConfirm, (Action)delegate
			{
				SetTargetFrameRate(-1);
				Core.Instance.UIManager.ShowNotification("Your FPS has no limits! \nMake sure " + GetColoredVSyncText() + " is off for it to go into effect.", Array.Empty<string>());
			});
			base.ScrollView.AddButton((PhoneButton)(object)val2);
		}

		private void SetTargetFrameRate(int frameRate)
		{
			Application.targetFrameRate = frameRate;
			ScoreAttackSaveData.Instance.TargetFrameRate = frameRate;
			((CustomApp)this).CreateIconlessTitleBar(GetFpsTitle(), 80f);
		}

		private void RefreshVSyncStatus()
		{
			string fpsTitle = GetFpsTitle();
			if (fpsTitle != lastTitle)
			{
				lastTitle = fpsTitle;
				((CustomApp)this).CreateIconlessTitleBar(fpsTitle, 80f);
			}
		}

		private string GetFpsTitle()
		{
			int targetFrameRate = ScoreAttackSaveData.Instance.TargetFrameRate;
			if (targetFrameRate == 0)
			{
				targetFrameRate = Application.targetFrameRate;
				ScoreAttackSaveData.Instance.TargetFrameRate = targetFrameRate;
			}
			string text = targetFrameRate switch
			{
				0 => "No Limit Set", 
				-1 => "None, baby!", 
				_ => targetFrameRate + " fps", 
			};
			string text2 = ((QualitySettings.vSyncCount > 0) ? "V-Sync = On" : "V-Sync = Off");
			return "FPS Limit\n<size=50%>Limit = " + text + "</size>\n<size=50%>" + text2 + "</size>";
		}

		public static string StaticGetFpsTitle()
		{
			int targetFrameRate = ScoreAttackSaveData.Instance.TargetFrameRate;
			if (targetFrameRate == 0)
			{
				targetFrameRate = Application.targetFrameRate;
			}
			string text = targetFrameRate switch
			{
				0 => "No Limit Set", 
				-1 => "None, baby!", 
				_ => targetFrameRate + " fps", 
			};
			string text2 = ((QualitySettings.vSyncCount > 0) ? "V-Sync = On" : "V-Sync = Off");
			return "FPS Limit\n<size=50%>Limit = " + text + "</size>\n<size=50%>" + text2 + "</size>";
		}

		private void OnUpdate()
		{
			refreshTimer += Time.deltaTime;
			if (refreshTimer >= 0.5f)
			{
				refreshTimer = 0f;
				RefreshVSyncStatus();
			}
		}

		public void ForceTitleRefresh(string newTitle)
		{
			((CustomApp)this).CreateIconlessTitleBar(newTitle, 80f);
		}

		private string GetColoredVSyncText()
		{
			string text = ((QualitySettings.vSyncCount > 0) ? "red" : "green");
			return "<color=" + text + ">V-Sync</color>";
		}
	}
	public enum GrindDebtDisplayMode
	{
		Disabled,
		Bar,
		Value,
		Both,
		SoftGoat
	}
	public enum GrindDebtColorMode
	{
		Flashing,
		Red,
		White
	}
	public class AppGrindDebt : CustomApp
	{
		public class GrindDebtMonitor : MonoBehaviour
		{
			private AppGrindDebt app;

			private float refreshCooldown = 0.25f;

			private float refreshTimer = 0f;

			private bool hadDebt = false;

			public void Init(AppGrindDebt appRef)
			{
				app = appRef;
			}

			private void Update()
			{
				if ((Object)(object)app == (Object)null)
				{
					return;
				}
				refreshTimer -= Time.deltaTime;
				if (refreshTimer <= 0f)
				{
					refreshTimer = refreshCooldown;
					float trickTimer = GetTrickTimer();
					bool flag = trickTimer >= 0.2f;
					if (flag != hadDebt)
					{
						hadDebt = flag;
						((CustomApp)app).CreateIconlessTitleBar(GetGrindDebtString(), 80f);
					}
				}
			}
		}

		private float refreshCooldown = 0.25f;

		private float refreshTimer = 0f;

		private bool hadDebt = false;

		public override bool Available => false;

		public static GrindDebtDisplayMode ViewerMode { get; private set; }

		public static GrindDebtColorMode ColorMode { get; private set; }

		public static void Initialize()
		{
			PhoneAPI.RegisterApp<AppGrindDebt>("grind debt", (Sprite)null);
		}

		public override void OnAppInit()
		{
			((CustomApp)this).OnAppInit();
			LoadState();
			((CustomApp)this).CreateIconlessTitleBar(GetGrindDebtString(), 80f);
			((Component)this).gameObject.AddComponent<GrindDebtMonitor>().Init(this);
			base.ScrollView = PhoneScrollView.Create((CustomApp)(object)this, 275f, 1600f);
			SimplePhoneButton val = PhoneUIUtility.CreateSimpleButton("Clear Grind Debt");
			((PhoneButton)val).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val).OnConfirm, (Action)delegate
			{
				Player currentPlayer = WorldHandler.instance.GetCurrentPlayer();
				currentPlayer.grindAbility.trickTimer = 0f;
				currentPlayer.RefreshAllDegrade();
				((CustomApp)this).CreateIconlessTitleBar(GetGrindDebtString(), 80f);
				hadDebt = false;
			});
			base.ScrollView.AddButton((PhoneButton)(object)val);
			SimplePhoneButton toggle = PhoneUIUtility.CreateSimpleButton(GetViewerLabel());
			SimplePhoneButton obj = toggle;
			((PhoneButton)obj).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj).OnConfirm, (Action)delegate
			{
				ViewerMode = GetNextMode(ViewerMode);
				((TMP_Text)toggle.Label).SetText(GetViewerLabel(), true);
				((CustomApp)this).CreateIconlessTitleBar(GetGrindDebtString(), 80f);
				SaveState();
			});
			base.ScrollView.AddButton((PhoneButton)(object)toggle);
			SimplePhoneButton colorToggle = PhoneUIUtility.CreateSimpleButton(GetColorLabel());
			SimplePhoneButton obj2 = colorToggle;
			((PhoneButton)obj2).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj2).OnConfirm, (Action)delegate
			{
				ColorMode = GetNextColorMode(ColorMode);
				((TMP_Text)colorToggle.Label).SetText(GetColorLabel(), true);
				SaveState();
			});
			base.ScrollView.AddButton((PhoneButton)(object)colorToggle);
		}

		private static string GetViewerLabel()
		{
			string text = ((ViewerMode == GrindDebtDisplayMode.Disabled) ? "red" : "green");
			return "Grind Debt Viewer \n<size=50%><color=" + text + ">" + GetFormattedEnumName(ViewerMode) + "</color></size>";
		}

		private static string GetFormattedEnumName(GrindDebtDisplayMode mode)
		{
			return mode switch
			{
				GrindDebtDisplayMode.Disabled => "Disabled", 
				GrindDebtDisplayMode.Bar => "Boost Bar", 
				GrindDebtDisplayMode.Value => "Numerical Value", 
				GrindDebtDisplayMode.Both => "Bar + Value", 
				GrindDebtDisplayMode.SoftGoat => "SoftGoat Speedometer Preset", 
				_ => mode.ToString(), 
			};
		}

		private static string GetColorLabel()
		{
			return "Viewer Behavior \n<size=50%><color=orange>" + GetFormattedEnumName(ColorMode) + "</color></size>";
		}

		private static string GetFormattedEnumName(GrindDebtColorMode mode)
		{
			return mode switch
			{
				GrindDebtColorMode.Flashing => "Flash When You Have Debt", 
				GrindDebtColorMode.Red => "Solid Colors", 
				GrindDebtColorMode.White => "All White", 
				_ => mode.ToString(), 
			};
		}

		private static GrindDebtDisplayMode GetNextMode(GrindDebtDisplayMode current)
		{
			return (GrindDebtDisplayMode)((int)(current + 1) % 5);
		}

		private static GrindDebtColorMode GetNextColorMode(GrindDebtColorMode current)
		{
			return (GrindDebtColorMode)((int)(current + 1) % 3);
		}

		public static float GetTrickTimer()
		{
			Player currentPlayer = WorldHandler.instance.GetCurrentPlayer();
			if ((Object)(object)currentPlayer == (Object)null || currentPlayer.grindAbility == null)
			{
				return 0f;
			}
			return currentPlayer.grindAbility.trickTimer;
		}

		private void LoadState()
		{
			ViewerMode = ScoreAttackSaveData.Instance.GrindDebtViewerMode;
			ColorMode = ScoreAttackSaveData.Instance.GrindDebtColorMode;
		}

		private void SaveState()
		{
			ScoreAttackSaveData.Instance.GrindDebtViewerMode = ViewerMode;
			ScoreAttackSaveData.Instance.GrindDebtColorMode = ColorMode;
		}

		private static string GetGrindDebtString()
		{
			Player currentPlayer = WorldHandler.instance.GetCurrentPlayer();
			if ((Object)(object)currentPlayer == (Object)null || currentPlayer.grindAbility == null)
			{
				return "Grind Debt\n<size=50%>Checking...</size>";
			}
			float trickTimer = currentPlayer.grindAbility.trickTimer;
			float num = Mathf.Floor(trickTimer * 10f) / 10f;
			if (num >= 0.2f)
			{
				return "Grind Debt\n<size=50%><color=red>Pay your debts...</color></size>";
			}
			return "Grind Debt\n<size=50%>No debt here!</size>";
		}
	}
	public class AppMoveStyle : CustomApp
	{
		private Player player;

		private WorldHandler world;

		private bool coreHasBeenSetup;

		private MoveStyle currentStyle;

		private Dictionary<MoveStyle, int> skinIndices = new Dictionary<MoveStyle, int>();

		private int characterSkinIndex = 0;

		public override bool Available => false;

		public static void Initialize()
		{
			PhoneAPI.RegisterApp<AppMoveStyle>("move styles", (Sprite)null);
		}

		public override void OnAppInit()
		{
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			((CustomApp)this).OnAppInit();
			((CustomApp)this).CreateIconlessTitleBar("Change Style", 80f);
			base.ScrollView = PhoneScrollView.Create((CustomApp)(object)this, 275f, 1600f);
			player = WorldHandler.instance.GetCurrentPlayer();
			world = WorldHandler.instance;
			coreHasBeenSetup = (Object)(object)player != (Object)null && (Object)(object)world != (Object)null;
			SimplePhoneButton val = PhoneUIUtility.CreateSimpleButton("Skateboard");
			SimplePhoneButton obj = val;
			((PhoneButton)obj).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj).OnConfirm, (Action)delegate
			{
				if (coreHasBeenSetup)
				{
					SwapStyle((MoveStyle)2);
				}
			});
			base.ScrollView.AddButton((PhoneButton)(object)val);
			val = PhoneUIUtility.CreateSimpleButton("Inline Skates");
			SimplePhoneButton obj2 = val;
			((PhoneButton)obj2).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj2).OnConfirm, (Action)delegate
			{
				if (coreHasBeenSetup)
				{
					SwapStyle((MoveStyle)3);
				}
			});
			base.ScrollView.AddButton((PhoneButton)(object)val);
			val = PhoneUIUtility.CreateSimpleButton("BMX");
			SimplePhoneButton obj3 = val;
			((PhoneButton)obj3).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj3).OnConfirm, (Action)delegate
			{
				if (coreHasBeenSetup)
				{
					SwapStyle((MoveStyle)1);
				}
			});
			base.ScrollView.AddButton((PhoneButton)(object)val);
			val = PhoneUIUtility.CreateSimpleButton("Swap Style Skin\n<size=50%>Change how your gear looks!</size>");
			SimplePhoneButton obj4 = val;
			((PhoneButton)obj4).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj4).OnConfirm, (Action)delegate
			{
				if (coreHasBeenSetup)
				{
					CycleSkinForCurrentStyle();
				}
			});
			base.ScrollView.AddButton((PhoneButton)(object)val);
			val = PhoneUIUtility.CreateSimpleButton("Swap Outfit\n<size=50%>Change your clothes!</size>");
			SimplePhoneButton obj5 = val;
			((PhoneButton)obj5).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj5).OnConfirm, (Action)delegate
			{
				if (coreHasBeenSetup)
				{
					SwapCharacterOutfit();
				}
			});
			base.ScrollView.AddButton((PhoneButton)(object)val);
			if ((Object)(object)player != (Object)null)
			{
				currentStyle = player.moveStyle;
				if (!skinIndices.ContainsKey(currentStyle))
				{
					skinIndices[currentStyle] = 0;
				}
				ApplySkin(currentStyle, skinIndices[currentStyle]);
			}
		}

		private void SwapStyle(MoveStyle newStyle)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Expected O, but got Unknown
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Expected O, but got Unknown
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Expected O, but got Unknown
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: 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_00f2: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)player != (Object)null)
			{
				Ability val = (Ability)Traverse.Create((object)player).Field("ability").GetValue();
				GrindAbility val2 = (GrindAbility)Traverse.Create((object)player).Field("grindAbility").GetValue();
				WallrunLineAbility val3 = (WallrunLineAbility)Traverse.Create((object)player).Field("wallrunAbility").GetValue();
				player.InitMovement(newStyle);
				if (val == val2)
				{
					player.SwitchToEquippedMovestyle(true, false, true, true);
				}
				else if (val == val3)
				{
					player.SwitchToEquippedMovestyle(true, true, true, true);
				}
				else
				{
					player.SwitchToEquippedMovestyle(true, true, true, true);
				}
				currentStyle = newStyle;
				if (!skinIndices.ContainsKey(newStyle))
				{
					skinIndices[newStyle] = 0;
				}
				ApplySkin(newStyle, skinIndices[newStyle]);
			}
		}

		private void CycleSkinForCurrentStyle()
		{
			//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_002b: 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_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)player == (Object)null))
			{
				currentStyle = player.moveStyle;
				if (!skinIndices.ContainsKey(currentStyle))
				{
					skinIndices[currentStyle] = 1;
				}
				int num = skinIndices[currentStyle];
				int num2 = (num + 1) % 10;
				skinIndices[currentStyle] = num2;
				ApplySkin(currentStyle, num2);
			}
		}

		private void ApplySkin(MoveStyle style, int skinIndex)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)player == (Object)null)
			{
				return;
			}
			Texture moveStyleSkinTexture = player.CharacterConstructor.GetMoveStyleSkinTexture(style, skinIndex);
			if ((Object)(object)moveStyleSkinTexture == (Object)null)
			{
				return;
			}
			Material[] moveStyleMaterials = MoveStyleLoader.GetMoveStyleMaterials(player, style);
			if (moveStyleMaterials == null || moveStyleMaterials.Length == 0)
			{
				Debug.LogWarning((object)$"No materials found for MoveStyle {style}");
				return;
			}
			for (int i = 0; i < moveStyleMaterials.Length; i++)
			{
				moveStyleMaterials[i].mainTexture = moveStyleSkinTexture;
			}
			Debug.Log((object)$"Applied skin index {skinIndex} for style {style}");
		}

		private void SwapCharacterOutfit()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)player == (Object)null))
			{
				Characters character = player.character;
				CharacterProgress characterProgress = Core.Instance.SaveManager.CurrentSaveSlot.GetCharacterProgress(character);
				characterSkinIndex = (characterSkinIndex + 1) % 4;
				player.SetOutfit(characterSkinIndex);
				Debug.Log((object)$"Swapped to outfit index {characterSkinIndex} for character {character}");
			}
		}
	}
	public class AppPolice : CustomApp
	{
		private WantedManager wantedManager;

		public override bool Available => false;

		public static void Initialize()
		{
			PhoneAPI.RegisterApp<AppPolice>("remove police", (Sprite)null);
		}

		public override void OnAppInit()
		{
			((CustomApp)this).OnAppInit();
			((CustomApp)this).CreateIconlessTitleBar("Wanted Level", 80f);
			base.ScrollView = PhoneScrollView.Create((CustomApp)(object)this, 275f, 1600f);
			SimplePhoneButton val = PhoneUIUtility.CreateSimpleButton("Remove Police");
			SimplePhoneButton obj = val;
			((PhoneButton)obj).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj).OnConfirm, (Action)delegate
			{
				if (PlayerIsWanted())
				{
					wantedManager.StopPlayerWantedStatus(true);
				}
				Player currentPlayer = WorldHandler.instance.GetCurrentPlayer();
				currentPlayer.ResetHP();
				if (currentPlayer.AmountOfCuffs() > 0)
				{
					currentPlayer.RemoveAllCuffs((CuffMissileLauncher)null);
				}
			});
			base.ScrollView.AddButton((PhoneButton)(object)val);
			val = PhoneUIUtility.CreateSimpleButton("Enable Cops");
			SimplePhoneButton obj2 = val;
			((PhoneButton)obj2).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj2).OnConfirm, (Action)delegate
			{
			});
			base.ScrollView.AddButton((PhoneButton)(object)val);
		}

		public void Update()
		{
			wantedManager = WantedManager.instance;
		}

		public bool PlayerIsWanted()
		{
			if ((Object)(object)wantedManager != (Object)null)
			{
				return wantedManager.Wanted;
			}
			return false;
		}

		public void StopWantedStatus()
		{
			if (PlayerIsWanted())
			{
				Debug.Log((object)"Stopping wanted status...");
				wantedManager.StopPlayerWantedStatus(true);
			}
		}
	}
	public class AppScoreAttack : CustomApp
	{
		public static Encounter globalEncounter;

		private PhoneButton goToRespawnButton = null;

		private WantedManager wantedManager;

		public bool testingPlugin = false;

		public override bool Available => false;

		public static void Initialize()
		{
			PhoneAPI.RegisterApp<AppScoreAttack>("score atk", (Sprite)null);
		}

		public override void OnAppInit()
		{
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: 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)
			((CustomApp)this).OnAppInit();
			((CustomApp)this).CreateIconlessTitleBar("Select Length", 80f);
			base.ScrollView = PhoneScrollView.Create((CustomApp)(object)this, 275f, 1600f);
			SimplePhoneButton val = PhoneUIUtility.CreateSimpleButton("3 Minutes");
			SimplePhoneButton obj = val;
			((PhoneButton)obj).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj).OnConfirm, (Action)delegate
			{
				//IL_0079: 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_0084: Unknown result type (might be due to invalid IL or missing references)
				Debug.Log((object)"Starting 3 Minute Score Battle...");
				if (BannedMods.IsAdvantageousModLoaded())
				{
					Core.Instance.UIManager.ShowNotification("The score attack app is not compatible with TrickGod!", Array.Empty<string>());
				}
				else
				{
					if (ScoreAttackEncounter.IsScoreAttackActive())
					{
						ScoreAttackEncounter scoreAttackEncounter6 = Object.FindObjectOfType<ScoreAttackEncounter>();
						scoreAttackEncounter6.EndScoreAttack();
						Core.Instance.SaveManager.SaveCurrentSaveSlot();
					}
					BattleRefresh();
					ScoreAttackManager.ExternalGhostLoadedFromGhostList = false;
					Stage currentStage4 = Core.Instance.BaseModule.CurrentStage;
					RespawnPoint respawnPoint4 = ScoreAttackSaveData.Instance.GetRespawnPoint(currentStage4);
					if (respawnPoint4 == null)
					{
						Core.Instance.UIManager.ShowNotification("Please set a respawn point first!\n<size=50%>It's at the bottom of the app menu!</size>", Array.Empty<string>());
					}
					else
					{
						respawnPoint4.ApplyToPlayer(((App)this).MyPhone.player);
						ScoreAttackManager.StartScoreAttack(180f);
						((App)this).MyPhone.CloseCurrentApp();
						((App)this).MyPhone.TurnOff(false);
						ScoreAttackManager.StartScoreAttack(180f);
						((App)this).MyPhone.CloseCurrentApp();
						((App)this).MyPhone.TurnOff(false);
					}
				}
			});
			base.ScrollView.AddButton((PhoneButton)(object)val);
			val = PhoneUIUtility.CreateSimpleButton("5 Minutes");
			SimplePhoneButton obj2 = val;
			((PhoneButton)obj2).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj2).OnConfirm, (Action)delegate
			{
				//IL_0079: 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_0084: Unknown result type (might be due to invalid IL or missing references)
				Debug.Log((object)"Starting 5 Minute Score Battle...");
				if (ScoreAttackEncounter.IsScoreAttackActive())
				{
					ScoreAttackEncounter scoreAttackEncounter5 = Object.FindObjectOfType<ScoreAttackEncounter>();
					scoreAttackEncounter5.EndScoreAttack();
					Core.Instance.SaveManager.SaveCurrentSaveSlot();
				}
				BattleRefresh();
				ScoreAttackManager.ExternalGhostLoadedFromGhostList = false;
				if (BannedMods.IsAdvantageousModLoaded())
				{
					Core.Instance.UIManager.ShowNotification("The score attack app is not compatible with TrickGod!", Array.Empty<string>());
				}
				else
				{
					Stage currentStage3 = Core.Instance.BaseModule.CurrentStage;
					RespawnPoint respawnPoint3 = ScoreAttackSaveData.Instance.GetRespawnPoint(currentStage3);
					if (respawnPoint3 == null)
					{
						Core.Instance.UIManager.ShowNotification("Please set a respawn point first!\n<size=50%>It's at the bottom of the app menu!</size>", Array.Empty<string>());
					}
					else
					{
						respawnPoint3.ApplyToPlayer(((App)this).MyPhone.player);
						ScoreAttackManager.StartScoreAttack(300f);
						((App)this).MyPhone.CloseCurrentApp();
						((App)this).MyPhone.TurnOff(false);
						ScoreAttackManager.StartScoreAttack(300f);
						((App)this).MyPhone.CloseCurrentApp();
						((App)this).MyPhone.TurnOff(false);
					}
				}
			});
			base.ScrollView.AddButton((PhoneButton)(object)val);
			val = PhoneUIUtility.CreateSimpleButton("10 Minutes");
			SimplePhoneButton obj3 = val;
			((PhoneButton)obj3).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj3).OnConfirm, (Action)delegate
			{
				//IL_0079: 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_0084: Unknown result type (might be due to invalid IL or missing references)
				Debug.Log((object)"Starting 10 Minute Score Battle...");
				if (ScoreAttackEncounter.IsScoreAttackActive())
				{
					ScoreAttackEncounter scoreAttackEncounter4 = Object.FindObjectOfType<ScoreAttackEncounter>();
					scoreAttackEncounter4.EndScoreAttack();
					Core.Instance.SaveManager.SaveCurrentSaveSlot();
				}
				BattleRefresh();
				ScoreAttackManager.ExternalGhostLoadedFromGhostList = false;
				if (BannedMods.IsAdvantageousModLoaded())
				{
					Core.Instance.UIManager.ShowNotification("The score attack app is not compatible with TrickGod!", Array.Empty<string>());
				}
				else
				{
					Stage currentStage2 = Core.Instance.BaseModule.CurrentStage;
					RespawnPoint respawnPoint2 = ScoreAttackSaveData.Instance.GetRespawnPoint(currentStage2);
					if (respawnPoint2 == null)
					{
						Core.Instance.UIManager.ShowNotification("Please set a respawn point first!\n<size=50%>It's at the bottom of the app menu!</size>", Array.Empty<string>());
					}
					else
					{
						respawnPoint2.ApplyToPlayer(((App)this).MyPhone.player);
						ScoreAttackManager.StartScoreAttack(600f);
						((App)this).MyPhone.CloseCurrentApp();
						((App)this).MyPhone.TurnOff(false);
						ScoreAttackManager.StartScoreAttack(600f);
						((App)this).MyPhone.CloseCurrentApp();
						((App)this).MyPhone.TurnOff(false);
					}
				}
			});
			base.ScrollView.AddButton((PhoneButton)(object)val);
			if (testingPlugin)
			{
				val = PhoneUIUtility.CreateSimpleButton("1 Minute");
				SimplePhoneButton obj4 = val;
				((PhoneButton)obj4).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj4).OnConfirm, (Action)delegate
				{
					//IL_0079: 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_0084: Unknown result type (might be due to invalid IL or missing references)
					Debug.Log((object)"Starting 1 Minute Score Battle...");
					if (ScoreAttackEncounter.IsScoreAttackActive())
					{
						ScoreAttackEncounter scoreAttackEncounter3 = Object.FindObjectOfType<ScoreAttackEncounter>();
						scoreAttackEncounter3.EndScoreAttack();
						Core.Instance.SaveManager.SaveCurrentSaveSlot();
					}
					BattleRefresh();
					ScoreAttackManager.ExternalGhostLoadedFromGhostList = false;
					if (BannedMods.IsAdvantageousModLoaded())
					{
						Core.Instance.UIManager.ShowNotification("The score attack app is not compatible with TrickGod!", Array.Empty<string>());
					}
					else
					{
						Stage currentStage = Core.Instance.BaseModule.CurrentStage;
						RespawnPoint respawnPoint = ScoreAttackSaveData.Instance.GetRespawnPoint(currentStage);
						if (respawnPoint == null)
						{
							Core.Instance.UIManager.ShowNotification("Please set a respawn point first!\n<size=50%>It's at the bottom of the app menu!</size>", Array.Empty<string>());
						}
						else
						{
							respawnPoint.ApplyToPlayer(((App)this).MyPhone.player);
							ScoreAttackManager.StartScoreAttack(60f);
							((App)this).MyPhone.CloseCurrentApp();
							((App)this).MyPhone.TurnOff(false);
							ScoreAttackManager.StartScoreAttack(60f);
							((App)this).MyPhone.CloseCurrentApp();
							((App)this).MyPhone.TurnOff(false);
						}
					}
				});
				base.ScrollView.AddButton((PhoneButton)(object)val);
			}
			val = PhoneUIUtility.CreateSimpleButton("Cancel Run");
			SimplePhoneButton obj5 = val;
			((PhoneButton)obj5).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj5).OnConfirm, (Action)delegate
			{
				Debug.Log((object)"Cancelling Active Battle...");
				ScoreAttackManager.LoadedExternalGhost = null;
				ScoreAttackManager.ExternalGhostLoadedFromGhostList = false;
				if (ScoreAttackEncounter.IsScoreAttackActive())
				{
					ScoreAttackEncounter scoreAttackEncounter2 = Object.FindObjectOfType<ScoreAttackEncounter>();
					scoreAttackEncounter2.EndScoreAttack();
					Core.Instance.SaveManager.SaveCurrentSaveSlot();
				}
				else
				{
					Core.Instance.UIManager.ShowNotification("There is no ongoing Score Battle run!", Array.Empty<string>());
				}
			});
			val.LabelUnselectedColor = Color.black;
			val.LabelSelectedColor = Color.red;
			base.ScrollView.AddButton((PhoneButton)(object)val);
			val = PhoneUIUtility.CreateSimpleButton("Erase All Your Personal Bests");
			SimplePhoneButton obj6 = val;
			((PhoneButton)obj6).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj6).OnConfirm, (Action)delegate
			{
				Debug.Log((object)"Clearing Personal Bests...");
				ScoreAttackEncounter scoreAttackEncounter = Object.FindObjectOfType<ScoreAttackEncounter>();
				if ((Object)(object)scoreAttackEncounter != (Object)null)
				{
					if (ScoreAttackEncounter.IsScoreAttackActive())
					{
						Debug.LogError((object)"Can't clear PB during a run!");
						Core.Instance.UIManager.ShowNotification("You are in a run! Cancel the run to clear your personal bests.", Array.Empty<string>());
					}
					else
					{
						scoreAttackEncounter.ClearPersonalBest();
						Core.Instance.UIManager.ShowNotification("Personal bests have been erased.", Array.Empty<string>());
					}
				}
				else
				{
					Debug.LogError((object)"ScoreAttackEncounter instance not found!");
				}
			});
			val.LabelUnselectedColor = Color.black;
			val.LabelSelectedColor = Color.red;
			base.ScrollView.AddButton((PhoneButton)(object)val);
		}

		public static void InitializeEncounter()
		{
			globalEncounter = Object.FindObjectOfType<Encounter>();
			if ((Object)(object)globalEncounter == (Object)null)
			{
				Debug.LogError((object)"Error: Encounter object not found!");
			}
		}

		public static void BattleRefresh()
		{
			Player currentPlayer = WorldHandler.instance.GetCurrentPlayer();
			currentPlayer.boostCharge = currentPlayer.maxBoostCharge;
			Debug.Log((object)"Respawning Pickups...");
			Object.FindObjectsOfType<Pickup>().Where(delegate(Pickup pickup)
			{
				//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_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_0009: Invalid comparison between Unknown and I4
				PickUpType pickupType = pickup.pickupType;
				bool flag = (int)pickupType <= 1;
				return flag && (Object)(object)pickup.pickupObject != (Object)null;
			}).ToList()
				.ForEach(delegate(Pickup boost)
				{
					boost.SetPickupActive(true);
				});
			Debug.Log((object)"Restoring Vending Machines...");
			List<VendingMachine> list = (from vending in Object.FindObjectsOfType<VendingMachine>()
				where vending.rewardCount > 0
				select vending).ToList();
			foreach (VendingMachine item in list)
			{
				if (item.dropCount > 0)
				{
					item.dropCount = 0;
				}
			}
			foreach (VendingMachine item2 in list)
			{
				if (item2.rewardCount > 0)
				{
					item2.rewardCount = 0;
				}
			}
			foreach (VendingMachine item3 in list)
			{
				if (item3.firstHit)
				{
					item3.firstHit = false;
				}
			}
		}
	}
	public class AppScoreAttackOffline : CustomApp
	{
		private static Sprite IconSprite;

		private PhoneButton goToRespawnButton = null;

		private WantedManager wantedManager;

		public static void Initialize()
		{
			IconSprite = TextureUtility.LoadSprite(Path.Combine(ScoreAttackPlugin.Instance.Directory, "scoreIcon.png"));
			PhoneAPI.RegisterApp<AppScoreAttackOffline>("score atk", IconSprite);
		}

		public void UpdateGoToRespawnButton()
		{
			//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_0016: Unknown result type (might be due to invalid IL or missing references)
			Stage currentStage = Core.Instance.BaseModule.CurrentStage;
			RespawnPoint respawnPoint = ScoreAttackSaveData.Instance.GetRespawnPoint(currentStage);
			if (respawnPoint == null)
			{
				if (base.ScrollView.HasButton(goToRespawnButton))
				{
					base.ScrollView.RemoveButton(goToRespawnButton);
				}
			}
			else if (!base.ScrollView.HasButton(goToRespawnButton))
			{
				base.ScrollView.AddButton(goToRespawnButton);
			}
		}

		public override void OnAppEnable()
		{
			((App)this).OnAppEnable();
			UpdateGoToRespawnButton();
		}

		public override void OnAppInit()
		{
			((CustomApp)this).OnAppInit();
			((CustomApp)this).CreateTitleBar("Score Attack", IconSprite, 80f);
			base.ScrollView = PhoneScrollView.Create((CustomApp)(object)this, 275f, 1600f);
			SimplePhoneButton val = PhoneUIUtility.CreateSimpleButton("Start a Run...");
			SimplePhoneButton obj = val;
			((PhoneButton)obj).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj).OnConfirm, (Action)delegate
			{
				((App)this).MyPhone.OpenApp(typeof(AppScoreAttack));
			});
			base.ScrollView.AddButton((PhoneButton)(object)val);
			val = PhoneUIUtility.CreateSimpleButton("Ghost Replays...");
			SimplePhoneButton obj2 = val;
			((PhoneButton)obj2).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj2).OnConfirm, (Action)delegate
			{
				((App)this).MyPhone.OpenApp(typeof(AppGhost));
			});
			base.ScrollView.AddButton((PhoneButton)(object)val);
			val = PhoneUIUtility.CreateSimpleButton("Go to Stage...");
			SimplePhoneButton obj3 = val;
			((PhoneButton)obj3).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj3).OnConfirm, (Action)delegate
			{
				((App)this).MyPhone.OpenApp(typeof(AppScoreAttackStageSelect));
			});
			base.ScrollView.AddButton((PhoneButton)(object)val);
			val = PhoneUIUtility.CreateSimpleButton("Change Style...");
			SimplePhoneButton obj4 = val;
			((PhoneButton)obj4).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj4).OnConfirm, (Action)delegate
			{
				((App)this).MyPhone.OpenApp(typeof(AppMoveStyle));
			});
			base.ScrollView.AddButton((PhoneButton)(object)val);
			val = PhoneUIUtility.CreateSimpleButton("Refill Boost");
			SimplePhoneButton obj5 = val;
			((PhoneButton)obj5).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj5).OnConfirm, (Action)delegate
			{
				Player currentPlayer2 = WorldHandler.instance.GetCurrentPlayer();
				currentPlayer2.boostCharge = currentPlayer2.maxBoostCharge;
			});
			base.ScrollView.AddButton((PhoneButton)(object)val);
			val = PhoneUIUtility.CreateSimpleButton("Reset Capsules");
			SimplePhoneButton obj6 = val;
			((PhoneButton)obj6).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj6).OnConfirm, (Action)delegate
			{
				Debug.Log((object)"Respawning Pickups...");
				Object.FindObjectsOfType<Pickup>().Where(delegate(Pickup pickup)
				{
					//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_0007: Unknown result type (might be due to invalid IL or missing references)
					//IL_0009: Invalid comparison between Unknown and I4
					PickUpType pickupType = pickup.pickupType;
					bool flag = (int)pickupType <= 1;
					return flag && (Object)(object)pickup.pickupObject != (Object)null;
				}).ToList()
					.ForEach(delegate(Pickup boost)
					{
						boost.SetPickupActive(true);
					});
				Debug.Log((object)"Restoring Vending Machines...");
				List<VendingMachine> list = (from vending in Object.FindObjectsOfType<VendingMachine>()
					where vending.rewardCount > 0
					select vending).ToList();
				foreach (VendingMachine item in list)
				{
					if (item.dropCount > 0)
					{
						item.dropCount = 0;
					}
				}
				foreach (VendingMachine item2 in list)
				{
					if (item2.rewardCount > 0)
					{
						item2.rewardCount = 0;
					}
				}
				foreach (VendingMachine item3 in list)
				{
					if (item3.firstHit)
					{
						item3.firstHit = false;
					}
				}
			});
			base.ScrollView.AddButton((PhoneButton)(object)val);
			val = PhoneUIUtility.CreateSimpleButton("Reset Cops");
			SimplePhoneButton obj7 = val;
			((PhoneButton)obj7).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj7).OnConfirm, (Action)delegate
			{
				if (PlayerIsWanted())
				{
					wantedManager.StopPlayerWantedStatus(true);
				}
				Player currentPlayer = WorldHandler.instance.GetCurrentPlayer();
				currentPlayer.ResetHP();
				if (currentPlayer.AmountOfCuffs() > 0)
				{
					currentPlayer.RemoveAllCuffs((CuffMissileLauncher)null);
				}
			});
			base.ScrollView.AddButton((PhoneButton)(object)val);
			val = PhoneUIUtility.CreateSimpleButton("Grind Debt...");
			SimplePhoneButton obj8 = val;
			((PhoneButton)obj8).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj8).OnConfirm, (Action)delegate
			{
				((App)this).MyPhone.OpenApp(typeof(AppGrindDebt));
			});
			base.ScrollView.AddButton((PhoneButton)(object)val);
			val = PhoneUIUtility.CreateSimpleButton("Set FPS Limit...");
			SimplePhoneButton obj9 = val;
			((PhoneButton)obj9).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj9).OnConfirm, (Action)delegate
			{
				((App)this).MyPhone.OpenApp(typeof(AppFPSLimit));
			});
			base.ScrollView.AddButton((PhoneButton)(object)val);
			val = PhoneUIUtility.CreateSimpleButton("Extras...");
			SimplePhoneButton obj10 = val;
			((PhoneButton)obj10).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj10).OnConfirm, (Action)delegate
			{
				((App)this).MyPhone.OpenApp(typeof(AppExtras));
			});
			base.ScrollView.AddButton((PhoneButton)(object)val);
			val = PhoneUIUtility.CreateSimpleButton("Set Respawn");
			SimplePhoneButton obj11 = val;
			((PhoneButton)obj11).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj11).OnConfirm, (Action)delegate
			{
				//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_0021: Unknown result type (might be due to invalid IL or missing references)
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				//IL_0037: Unknown result type (might be due to invalid IL or missing references)
				//IL_003c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0053: Unknown result type (might be due to invalid IL or missing references)
				//IL_0054: Unknown result type (might be due to invalid IL or missing references)
				//IL_0055: Unknown result type (might be due to invalid IL or missing references)
				Stage currentStage2 = Core.Instance.BaseModule.CurrentStage;
				Vector3 position = ((Component)((App)this).MyPhone.player).transform.position;
				Quaternion rotation = ((Component)((App)this).MyPhone.player).transform.rotation;
				bool usingEquippedMovestyle = ((App)this).MyPhone.player.usingEquippedMovestyle;
				ScoreAttackSaveData.Instance.SetRespawnPoint(currentStage2, position, rotation, usingEquippedMovestyle);
				UpdateGoToRespawnButton();
			});
			base.ScrollView.AddButton((PhoneButton)(object)val);
			goToRespawnButton = (PhoneButton)(object)PhoneUIUtility.CreateSimpleButton("Go to Respawn");
			PhoneButton obj12 = goToRespawnButton;
			obj12.OnConfirm = (Action)Delegate.Combine(obj12.OnConfirm, (Action)delegate
			{
				//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_0016: Unknown result type (might be due to invalid IL or missing references)
				Stage currentStage = Core.Instance.BaseModule.CurrentStage;
				ScoreAttackSaveData.Instance.GetRespawnPoint(currentStage)?.ApplyToPlayer(((App)this).MyPhone.player);
			});
		}

		public void Update()
		{
			wantedManager = WantedManager.instance;
		}

		public bool PlayerIsWanted()
		{
			if ((Object)(object)wantedManager != (Object)null)
			{
				return wantedManager.Wanted;
			}
			return false;
		}

		public void StopWantedStatus()
		{
			if (PlayerIsWanted())
			{
				wantedManager.StopPlayerWantedStatus(true);
			}
		}
	}
	public class AppScoreAttackStageSelect : CustomApp
	{
		public override bool Available => false;

		public static void Initialize()
		{
			PhoneAPI.RegisterApp<AppScoreAttackStageSelect>("stage select", (Sprite)null);
		}

		public override void OnAppInit()
		{
			((CustomApp)this).OnAppInit();
			((CustomApp)this).CreateIconlessTitleBar("Stage Select", 80f);
			base.ScrollView = PhoneScrollView.Create((CustomApp)(object)this, 275f, 1600f);
			SimplePhoneButton val = CreateStageButton("Hideout", (Stage)5);
			base.ScrollView.AddButton((PhoneButton)(object)val);
			val = CreateStageButton("Versum Hill", (Stage)4);
			base.ScrollView.AddButton((PhoneButton)(object)val);
			val = CreateStageButton("Millennium Square", (Stage)11);
			base.ScrollView.AddButton((PhoneButton)(object)val);
			val = CreateStageButton("Brink Terminal", (Stage)12);
			base.ScrollView.AddButton((PhoneButton)(object)val);
			val = CreateStageButton("Millennium Mall", (Stage)6);
			base.ScrollView.AddButton((PhoneButton)(object)val);
			val = CreateStageButton("Mataan", (Stage)7);
			base.ScrollView.AddButton((PhoneButton)(object)val);
			val = CreateStageButton("Pyramid Island", (Stage)9);
			base.ScrollView.AddButton((PhoneButton)(object)val);
			val = CreateStageButton("Police Station", (Stage)8);
			base.ScrollView.AddButton((PhoneButton)(object)val);
		}

		private SimplePhoneButton CreateStageButton(string label, Stage stage)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			SimplePhoneButton val = PhoneUIUtility.CreateSimpleButton(label);
			((PhoneButton)val).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val).OnConfirm, (Action)delegate
			{
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				Core.Instance.BaseModule.StageManager.ExitCurrentStage(stage, (Stage)(-1));
			});
			return val;
		}
	}
	public class BannedMods : BaseUnityPlugin
	{
		private void Awake()
		{
			if (IsAdvantageousModLoaded())
			{
				Core.Instance.UIManager.ShowNotification("The score attack app is not compatible with TrickGod!", Array.Empty<string>());
			}
		}

		public static bool IsAdvantageousModLoaded()
		{
			return Chainloader.PluginInfos.ContainsKey("TrickGod");
		}
	}
	public enum GhostDisplayMode
	{
		Hide,
		Show
	}
	public enum GhostWarpMode
	{
		Respawn,
		ToGhost
	}
	public class AppGhost : CustomApp
	{
		public override bool Available => false;

		public static void Initialize()
		{
			PhoneAPI.RegisterApp<AppGhost>("ghost", (Sprite)null);
		}

		public override void OnAppInit()
		{
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			((CustomApp)this).OnAppInit();
			((CustomApp)this).CreateIconlessTitleBar("Ghosts\n<size=50%>Challenge Ghosts!</size>", 80f);
			base.ScrollView = PhoneScrollView.Create((CustomApp)(object)this, 275f, 1600f);
			SimplePhoneButton val = PhoneUIUtility.CreateSimpleButton("Load Ghost...");
			SimplePhoneButton obj = val;
			((PhoneButton)obj).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj).OnConfirm, (Action)delegate
			{
				if (GhostSaveData.Instance.GhostDisplayMode == GhostDisplayMode.Hide)
				{
					Debug.Log((object)"[ScoreAttack] Ghost display mode set to Hide. Not letting the player enter this menu.");
					Core.Instance.UIManager.ShowNotification("Ghost display mode is set to <color=red>hide</color>.\nPlease enable it to use ghost playback during runs.", Array.Empty<string>());
				}
				else
				{
					((App)this).MyPhone.OpenApp(typeof(AppGhostList));
				}
			});
			base.ScrollView.AddButton((PhoneButton)(object)val);
			val = PhoneUIUtility.CreateSimpleButton("Delete Ghost...");
			SimplePhoneButton obj2 = val;
			((PhoneButton)obj2).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj2).OnConfirm, (Action)delegate
			{
				((App)this).MyPhone.OpenApp(typeof(AppGhostDelete));
			});
			base.ScrollView.AddButton((PhoneButton)(object)val);
			val = PhoneUIUtility.CreateSimpleButton("Ghost Settings...");
			SimplePhoneButton obj3 = val;
			((PhoneButton)obj3).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj3).OnConfirm, (Action)delegate
			{
				((App)this).MyPhone.OpenApp(typeof(AppGhostSettings));
			});
			base.ScrollView.AddButton((PhoneButton)(object)val);
			AddEnumButton("Display Ghosts", () => GhostSaveData.Instance.GhostDisplayMode, GetNextDisplayMode, delegate(GhostDisplayMode m)
			{
				GhostSaveData.Instance.GhostDisplayMode = m;
			});
			AddEnumButton("Start Position", () => GhostSaveData.Instance.GhostWarpMode, GetNextWarpMode, delegate(GhostWarpMode m)
			{
				GhostSaveData.Instance.GhostWarpMode = m;
			});
			val = PhoneUIUtility.CreateSimpleButton("Cancel Run");
			SimplePhoneButton obj4 = val;
			((PhoneButton)obj4).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj4).OnConfirm, (Action)delegate
			{
				Debug.Log((object)"Cancelling Active Battle...");
				ScoreAttackManager.LoadedExternalGhost = null;
				ScoreAttackManager.ExternalGhostLoadedFromGhostList = false;
				if (ScoreAttackEncounter.IsScoreAttackActive())
				{
					ScoreAttackEncounter scoreAttackEncounter = Object.FindObjectOfType<ScoreAttackEncounter>();
					scoreAttackEncounter.EndScoreAttack();
					Core.Instance.SaveManager.SaveCurrentSaveSlot();
				}
				else
				{
					Core.Instance.UIManager.ShowNotification("There is no ongoing Score Battle run!", Array.Empty<string>());
				}
			});
			val.LabelUnselectedColor = Color.black;
			val.LabelSelectedColor = Color.red;
			base.ScrollView.AddButton((PhoneButton)(object)val);
		}

		private void AddEnumButton<T>(string label, Func<T> getCurrent, Func<T, T> getNext, Action<T> setValue)
		{
			T val = getCurrent();
			SimplePhoneButton button = PhoneUIUtility.CreateSimpleButton(label + "\n<size=50%><color=" + GetColorForValue(val) + ">" + FormatEnum(val) + "</color></size>");
			SimplePhoneButton obj = button;
			((PhoneButton)obj).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj).OnConfirm, (Action)delegate
			{
				T arg = getCurrent();
				T val2 = getNext(arg);
				setValue(val2);
				((TMP_Text)button.Label).SetText(label + "\n<size=50%><color=" + GetColorForValue(val2) + ">" + FormatEnum(val2) + "</color></size>", true);
			});
			base.ScrollView.AddButton((PhoneButton)(object)button);
		}

		private static string FormatEnum<T>(T val)
		{
			T val2 = val;
			T val3 = val2;
			if (val3 is GhostDisplayMode)
			{
				object obj = val3;
				switch ((GhostDisplayMode)((obj is GhostDisplayMode) ? obj : null))
				{
				case GhostDisplayMode.Hide:
					return "Hide Ghost Playback During Runs";
				case GhostDisplayMode.Show:
					return "Show Ghost Playback During Runs";
				}
			}
			else if (val3 is GhostWarpMode)
			{
				object obj2 = val3;
				switch ((GhostWarpMode)((obj2 is GhostWarpMode) ? obj2 : null))
				{
				case GhostWarpMode.Respawn:
					return "Your Respawn Point";
				case GhostWarpMode.ToGhost:
					return "Ghost Start Point";
				}
			}
			return val.ToString();
		}

		private static string GetColorForValue<T>(T val)
		{
			if (val is GhostDisplayMode)
			{
				object obj = val;
				switch ((GhostDisplayMode)((obj is GhostDisplayMode) ? obj : null))
				{
				case GhostDisplayMode.Hide:
					return "red";
				case GhostDisplayMode.Show:
					return "green";
				}
			}
			else if (val is GhostWarpMode)
			{
				object obj2 = val;
				GhostWarpMode ghostWarpMode = (GhostWarpMode)((obj2 is GhostWarpMode) ? obj2 : null);
				if ((uint)ghostWarpMode <= 1u)
				{
					return "orange";
				}
			}
			return "white";
		}

		private static GhostDisplayMode GetNextDisplayMode(GhostDisplayMode mode)
		{
			return (GhostDisplayMode)((int)(mode + 1) % Enum.GetValues(typeof(GhostDisplayMode)).Length);
		}

		private static GhostWarpMode GetNextWarpMo