Decompiled source of CommonAPI v1.3.1

CommonAPI.dll

Decompiled 3 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Threading;
using BepInEx;
using BepInEx.Logging;
using CommonAPI.Phone;
using CommonAPI.UI;
using DG.Tweening;
using DG.Tweening.Core;
using DG.Tweening.Plugins.Options;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Reptile;
using Reptile.Phone;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.6", FrameworkDisplayName = ".NET Framework 4.6")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: AssemblyCompany("CommonAPI")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("General Purpose API for BRC modding.")]
[assembly: AssemblyFileVersion("1.3.1.0")]
[assembly: AssemblyInformationalVersion("1.3.1+68fa02e47bc4c8190a928f69972f7d49f3c58765")]
[assembly: AssemblyProduct("CommonAPI")]
[assembly: AssemblyTitle("CommonAPI")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.3.1.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 CommonAPI
{
	public static class AssetAPI
	{
		public enum ShaderNames
		{
			AmbientCharacter,
			AmbientEnvironment,
			AmbientEnvironmentCutout,
			AmbientEnvironmentTransparent,
			AmbientEnvironmentGlass
		}

		public enum MaterialNames
		{
			ToonWaterPyramid,
			OasisWater
		}

		private static readonly Dictionary<ShaderNames, Shader> CachedShaders = new Dictionary<ShaderNames, Shader>();

		private static readonly Dictionary<MaterialNames, Material> CachedMaterials = new Dictionary<MaterialNames, Material>();

		public static GraffitiArtInfo GetGraffitiArtInfo()
		{
			return Core.Instance.Assets.LoadAssetFromBundle<GraffitiArtInfo>("graffiti", "GraffitiArtInfo");
		}

		public static Material GetMaterial(MaterialNames materialName)
		{
			if (CachedMaterials.TryGetValue(materialName, out var value) && (Object)(object)value != (Object)null)
			{
				return value;
			}
			Assets assets = Core.Instance.Assets;
			switch (materialName)
			{
			case MaterialNames.ToonWaterPyramid:
			{
				Material val2 = assets.LoadAssetFromBundle<Material>("common_assets", "ToonWater_Pyramid");
				CacheMaterial(materialName, val2);
				return val2;
			}
			case MaterialNames.OasisWater:
			{
				Material val = assets.LoadAssetFromBundle<Material>("common_assets", "OasisWater");
				CacheMaterial(materialName, val);
				return val;
			}
			default:
				throw new ArgumentOutOfRangeException("materialName", "Material name is out of range!");
			}
		}

		public static Shader GetShader(ShaderNames shaderName)
		{
			if (CachedShaders.TryGetValue(shaderName, out var value) && (Object)(object)value != (Object)null)
			{
				return value;
			}
			Assets assets = Core.Instance.Assets;
			switch (shaderName)
			{
			case ShaderNames.AmbientEnvironmentGlass:
			{
				Shader shader5 = assets.LoadAssetFromBundle<Material>("common_assets", "glass").shader;
				CacheShader(shaderName, shader5);
				return shader5;
			}
			case ShaderNames.AmbientCharacter:
			{
				Shader shader4 = assets.LoadAssetFromBundle<Material>("common_assets", "shell").shader;
				CacheShader(shaderName, shader4);
				return shader4;
			}
			case ShaderNames.AmbientEnvironment:
			{
				Shader shader3 = assets.LoadAssetFromBundle<Material>("common_assets", "SkateboardScrewPoleMat").shader;
				CacheShader(shaderName, shader3);
				return shader3;
			}
			case ShaderNames.AmbientEnvironmentCutout:
			{
				Shader shader2 = assets.LoadAssetFromBundle<Material>("common_assets", "Prelude_PropsAtlasMat").shader;
				CacheShader(shaderName, shader2);
				return shader2;
			}
			case ShaderNames.AmbientEnvironmentTransparent:
			{
				Shader shader = assets.LoadAssetFromBundle<Material>("common_assets", "MusicCollectableMiniDiscTransperantMat").shader;
				CacheShader(shaderName, shader);
				return shader;
			}
			default:
				throw new ArgumentOutOfRangeException("shaderName", "Shader name is out of range!");
			}
		}

		private static void CacheShader(ShaderNames shaderName, Shader shader)
		{
			CachedShaders[shaderName] = shader;
		}

		private static void CacheMaterial(MaterialNames materialName, Material material)
		{
			CachedMaterials[materialName] = material;
		}
	}
	[BepInPlugin("CommonAPI", "CommonAPI", "1.3.1")]
	internal class CommonAPIPlugin : BaseUnityPlugin
	{
		public static CommonAPIPlugin Instance;

		public static ManualLogSource Log => ((BaseUnityPlugin)Instance).Logger;

		private void Awake()
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			Instance = this;
			try
			{
				PhoneAPI.Initialize();
				SaveAPI.Initialize();
				CustomSequenceHandler.Initialize();
				new CustomStorage();
				new Harmony("CommonAPI").PatchAll();
				((BaseUnityPlugin)this).Logger.LogInfo((object)"CommonAPI 1.3.1 loaded!");
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)string.Format("Problem loading {0} {1}!{2}{3}", "CommonAPI", "1.3.1", Environment.NewLine, ex));
			}
		}

		private void OnApplicationQuit()
		{
			CustomStorage.Instance.HandleQuit();
		}
	}
	internal class CommonAPISettings
	{
		public static bool Debug;
	}
	public class CustomDialogue
	{
		public string CharacterName = "";

		public string Dialogue = "";

		public Action OnDialogueBegin;

		public Action OnDialogueEnd;

		public bool EndSequenceOnFinish;

		public CustomDialogue NextDialogue;

		public ShowBarsType ShowBars = (ShowBarsType)1;

		public bool AnsweredYes;

		public CustomDialogue(string characterName, string dialogue, CustomDialogue nextDialogue = null)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			CharacterName = characterName;
			Dialogue = dialogue;
			NextDialogue = nextDialogue;
		}
	}
	public class CustomInteractable : MonoBehaviour
	{
		public bool PlacePlayerAtSnapPosition = true;

		public bool LookAt = true;

		public bool ShowRep;

		public InteractableIcon Icon;

		public Sprite CustomIcon;

		internal void OnSequenceBegin(CustomSequence sequence)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			if (!PlacePlayerAtSnapPosition)
			{
				return;
			}
			Transform val = ((Component)this).transform.Find("PlayerSnapPosition");
			if (!((Object)(object)val == (Object)null))
			{
				WorldHandler.instance.PlacePlayerAt(sequence.player, val.position, val.rotation, true);
				PlayerSpawner component = ((Component)val).GetComponent<PlayerSpawner>();
				if ((Object)(object)component != (Object)null)
				{
					component.SetReached();
				}
			}
		}

		public void StartEnteringSequence(CustomSequence sequence, bool setHidePlayer = false, bool setInterruptPlayer = true, bool instantly = false, bool setPausePlayer = true, bool setAllowPhoneOnAfterSequence = true, bool skippable = true, bool lowerVolumeDuringSequence = true, bool disabledExitOnInput = false)
		{
			CustomSequenceHandler.instance.StartEnteringSequence(sequence, this, setHidePlayer, setInterruptPlayer, instantly, setPausePlayer, setAllowPhoneOnAfterSequence, skippable, lowerVolumeDuringSequence, disabledExitOnInput);
		}

		private void OnTriggerStay(Collider other)
		{
			Player val = ((Component)other).GetComponentInChildren<Player>();
			if (!Object.op_Implicit((Object)(object)val))
			{
				val = ((Component)other).GetComponentInParent<Player>();
			}
			if (Object.op_Implicit((Object)(object)val))
			{
				CheckForInteraction(val);
			}
		}

		public bool CheckForInteraction(Player player)
		{
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			if (player.isAI)
			{
				return false;
			}
			if (player.IsDead())
			{
				return false;
			}
			if (!Player.NoMenuOpen())
			{
				return false;
			}
			if (!player.IsNotInCutsceneOrGettingCalled())
			{
				return false;
			}
			if (player.breakChainContextAvailable > 0)
			{
				return false;
			}
			if (player.graffitiContextAvailable > 0)
			{
				return false;
			}
			if (player.talkContextAvailable > 0)
			{
				return false;
			}
			CustomPlayerComponent customPlayerComponent = CustomPlayerComponent.Get(player);
			if (!Object.op_Implicit((Object)(object)customPlayerComponent))
			{
				return false;
			}
			if (!Test(player))
			{
				return false;
			}
			customPlayerComponent.CurrentCustomInteractable = this;
			customPlayerComponent.CustomInteractableContextAvailable = 10;
			if (ShowRep)
			{
				player.showRepLingerTimer = 2f;
			}
			if (LookAt)
			{
				player.characterVisual.LookAtSubject(((Component)this).gameObject, GetLookAtPos());
			}
			if (player.sprayButtonNew)
			{
				Interact(player);
				return true;
			}
			return false;
		}

		public virtual Vector3 GetLookAtPos()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			Transform val = ((Component)this).transform.Find("LookTarget");
			if (Object.op_Implicit((Object)(object)val))
			{
				return val.position;
			}
			return ((Component)this).transform.position;
		}

		public virtual bool Test(Player player)
		{
			return true;
		}

		public virtual void Interact(Player player)
		{
		}
	}
	internal class CustomPlayerComponent : MonoBehaviour
	{
		public Image CustomContextIcon;

		public CustomInteractable CurrentCustomInteractable;

		public int CustomInteractableContextAvailable;

		private Player _player;

		public static CustomPlayerComponent Get(Player player)
		{
			return ((Component)player).GetComponent<CustomPlayerComponent>();
		}

		public static CustomPlayerComponent Attach(Player player)
		{
			CustomPlayerComponent customPlayerComponent = ((Component)player).gameObject.AddComponent<CustomPlayerComponent>();
			customPlayerComponent._player = player;
			customPlayerComponent.Init();
			return customPlayerComponent;
		}

		private void Init()
		{
			if (!((Object)(object)_player.ui == (Object)null))
			{
				CustomContextIcon = Object.Instantiate<Image>(_player.ui.contextTalkIcon, ((Component)_player.ui.contextTalkIcon).gameObject.transform.parent);
			}
		}
	}
	public abstract class CustomSaveData
	{
		public string Filename;

		public bool AutoSave = true;

		public bool FailedToLoad;

		internal bool QueuedSave;

		private const string ApplicationDirectoryName = "Bomb Rush Cyberfunk Modding";

		public CustomSaveData(string pluginName, string filename)
			: this(pluginName, filename, SaveLocations.Documents)
		{
		}

		public CustomSaveData(string pluginName, string filename, SaveLocations saveLocation)
		{
			if (saveLocation == SaveLocations.Absolute)
			{
				Filename = filename;
			}
			else
			{
				Filename = Path.Combine(GetSaveLocation(saveLocation), pluginName, "saves", filename);
			}
			SaveAPI.RegisterCustomSaveData(this);
		}

		private string GetSaveLocation(SaveLocations saveLocation)
		{
			return saveLocation switch
			{
				SaveLocations.BepInEx => Paths.BepInExConfigPath, 
				SaveLocations.Documents => Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal, Environment.SpecialFolderOption.DoNotVerify), "Bomb Rush Cyberfunk Modding"), 
				SaveLocations.LocalAppData => Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData, Environment.SpecialFolderOption.DoNotVerify), "Bomb Rush Cyberfunk Modding"), 
				_ => "", 
			};
		}

		public virtual void Initialize()
		{
		}

		public virtual void Read(BinaryReader reader)
		{
		}

		public virtual void Write(BinaryWriter writer)
		{
		}

		public void Save()
		{
			QueuedSave = true;
		}

		internal string GetFilenameForFileID(int fileID)
		{
			return string.Format(Filename, fileID);
		}

		internal string GetBackupFilenameForFileID(int fileID)
		{
			return GetFilenameForFileID(fileID) + ".bak";
		}
	}
	internal class CustomSaveTransaction : CustomTransaction
	{
		private string _path;

		private byte[] _data;

		public CustomSaveTransaction(byte[] data, string filepath)
		{
			_data = data;
			_path = filepath;
		}

		public override void Process()
		{
			Directory.CreateDirectory(Path.GetDirectoryName(_path));
			File.WriteAllBytes(_path, _data);
		}
	}
	public class CustomSequence
	{
		public GameObject CurrentCamera;

		public Player player;

		public DialogueUI dialogueUI;

		public EffectsUI effectsUI;

		public double time;

		public void Init()
		{
			dialogueUI = Core.Instance.UIManager.dialogueUI;
			player = WorldHandler.instance.GetCurrentPlayer();
			effectsUI = Core.instance.UIManager.effects;
		}

		public virtual void Play()
		{
			effectsUI.ShowBars(0.25f, 150f, (UpdateType)3);
		}

		public virtual void Stop()
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			if (dialogueUI.isYesNoPromptEnabled)
			{
				dialogueUI.DisableYesNoPrompt();
			}
			effectsUI.HideBars(0.25f, (UpdateType)3);
			player.sequenceState = (SequenceState)4;
			if ((Object)(object)CurrentCamera != (Object)null)
			{
				CurrentCamera.SetActive(false);
			}
		}

		public void StartDialogue(CustomDialogue dialogue, float delay = 0.9f)
		{
			CustomSequenceHandler.instance.StartDialogueDelayed(dialogue, delay);
		}

		public void ExitSequence(float delay = 0.9f)
		{
			CustomSequenceHandler.instance.ExitCurrentSequenceDelayed(delay);
		}

		public void SetCamera(GameObject camera)
		{
			if ((Object)(object)CurrentCamera != (Object)null)
			{
				CurrentCamera.SetActive(false);
			}
			CurrentCamera = camera;
			if ((Object)(object)CurrentCamera != (Object)null)
			{
				CurrentCamera.SetActive(true);
			}
		}

		public void RequestYesNoPrompt()
		{
			dialogueUI.RequestYesNoPrompt((DialogueType)1);
		}
	}
	public class CustomSequenceHandler : AMenuController
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static OnStageInitializedDelegate <0>__StageManager_OnStagePostInitialization;
		}

		public const float DefaultExitDelay = 0.9f;

		public const float DefaultDialogueDelay = 0.9f;

		public static CustomSequenceHandler instance;

		public CustomSequence sequence;

		public CustomInteractable interactable;

		public bool disabledExit;

		private GameInput gameInput;

		private BaseModule baseModule;

		private Player player;

		private bool sequenceOverwritten;

		private float skipTimer;

		public SkipState skipTextActiveState = (SkipState)1;

		private float skipTextTimer;

		public bool isBusy;

		private bool hidePlayer;

		private bool pausePlayer;

		private bool interruptPlayer;

		private bool lowerVolume;

		private readonly float fadeDuration = 0.4f;

		internal float shutDuration = 0.2f;

		private readonly float skipFadeDuration = 0.3f;

		private float skipStartTimer;

		private readonly float skipThreshold = 0.4f;

		private readonly List<Coroutine> queuedSequenceActions = new List<Coroutine>();

		internal bool allowPhoneOnAfterSequence;

		internal CustomDialogue CurrentDialogue;

		public static void Initialize()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			object obj = <>O.<0>__StageManager_OnStagePostInitialization;
			if (obj == null)
			{
				OnStageInitializedDelegate val = StageManager_OnStagePostInitialization;
				<>O.<0>__StageManager_OnStagePostInitialization = val;
				obj = (object)val;
			}
			StageManager.OnStagePostInitialization += (OnStageInitializedDelegate)obj;
		}

		private IEnumerator StartDialogueCoroutine(CustomDialogue dialogue, float delay = 0.9f)
		{
			yield return (object)new WaitForSeconds(0.9f);
			StartDialogue(dialogue);
		}

		public void StartDialogueDelayed(CustomDialogue dialogue, float delay = 0.9f)
		{
			queuedSequenceActions.Add(((MonoBehaviour)this).StartCoroutine(StartDialogueCoroutine(dialogue, delay)));
		}

		public void StartDialogue(CustomDialogue dialogue)
		{
			instance.CurrentDialogue = dialogue;
			DialogueUI dialogueUI = Core.Instance.UIManager.dialogueUI;
			dialogueUI.effectsUI.ShowBars(0.25f, 150f, (UpdateType)3);
			dialogueUI.CanBeSkipped = true;
			dialogueUI.ToggleDialogueUI(true);
			dialogueUI.SetLine(dialogue.Dialogue);
			((Behaviour)dialogueUI.characterNameText).enabled = true;
			dialogue.OnDialogueBegin?.Invoke();
		}

		private static void StageManager_OnStagePostInitialization()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			new GameObject("Custom Sequence Handler").AddComponent<CustomSequenceHandler>().Init();
		}

		public void Init()
		{
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Expected O, but got Unknown
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Expected O, but got Unknown
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Expected O, but got Unknown
			instance = this;
			base.allowMouseInput = false;
			gameInput = Core.Instance.GameInput;
			base.uIManager = Core.Instance.UIManager;
			base.audioManager = Core.Instance.AudioManager;
			baseModule = Core.Instance.BaseModule;
			player = WorldHandler.instance.GetCurrentPlayer();
			Core.OnUpdate += new OnUpdateHandler(UpdateSequenceHandler);
			Core.OnCoreUpdatePaused += new OnCoreUpdateHandler(OnCoreUpdatePaused);
			Core.OnCoreUpdateUnPaused += new OnCoreUpdateUnpausedHandler(OnCoreUpdateUnPaused);
		}

		public void ExitCurrentSequenceDelayed(float delay = 0.9f)
		{
			queuedSequenceActions.Add(((MonoBehaviour)this).StartCoroutine(ExitCurrentSequenceDelayedCoroutine(delay)));
		}

		private IEnumerator ExitCurrentSequenceDelayedCoroutine(float delay = 0.9f)
		{
			yield return (object)new WaitForSeconds(delay);
			yield return ExitSequenceRoutine();
		}

		public void ExitCurrentSequence()
		{
			((MonoBehaviour)this).StartCoroutine(ExitSequenceRoutine());
		}

		public override void OnDestroy()
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Expected O, but got Unknown
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Expected O, but got Unknown
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Expected O, but got Unknown
			((AMenuController)this).OnDestroy();
			if ((Object)(object)Core.Instance != (Object)null && (Object)(object)base.uIManager != (Object)null)
			{
				base.uIManager.AbsolutePopIfPresent((IUIMenuController)(object)this);
			}
			base.audioManager = null;
			base.uIManager = null;
			gameInput = null;
			player = null;
			instance = null;
			Core.OnUpdate -= new OnUpdateHandler(UpdateSequenceHandler);
			Core.OnCoreUpdatePaused -= new OnCoreUpdateHandler(OnCoreUpdatePaused);
			Core.OnCoreUpdateUnPaused -= new OnCoreUpdateUnpausedHandler(OnCoreUpdateUnPaused);
		}

		public void UpdateSequenceHandler()
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Invalid comparison between Unknown and I4
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Invalid comparison between Unknown and I4
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Invalid comparison between Unknown and I4
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Expected O, but got Unknown
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Expected O, but got Unknown
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Expected O, but got Unknown
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Expected O, but got Unknown
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			if (!isBusy || (int)player.sequenceState != 1)
			{
				return;
			}
			DialogueUI dialogueUI = base.uIManager.dialogueUI;
			bool flag = ((AMenuController)this).IsEnabled && !disabledExit && gameInput.GetButtonNew(2, 0);
			if (flag && dialogueUI.CanBeSkipped && !dialogueUI.isYesNoPromptEnabled)
			{
				if (dialogueUI.ReadyToResume)
				{
					if (dialogueUI.IsShowingDialogue())
					{
						Core.Instance.AudioManager.PlaySfxUI((SfxCollectionID)23, (AudioClipID)922, 0f);
					}
					dialogueUI.EndDialogue();
				}
				else
				{
					FastForwardTypewriter();
				}
			}
			if ((int)skipTextActiveState != 0 && !dialogueUI.isYesNoPromptEnabled)
			{
				EffectsUI effects = base.uIManager.effects;
				float dt = Core.dt;
				bool num = ((AMenuController)this).IsEnabled && gameInput.GetButtonHeld(64, 0);
				if (skipStartTimer >= 0.5f)
				{
					if ((int)skipTextActiveState == 3)
					{
						skipTextTimer += dt;
						if (skipTextTimer > 1.5f && skipTimer == 0f)
						{
							Tween obj = effects.FadeSkipOut(skipFadeDuration, (UpdateType)3);
							obj.onComplete = (TweenCallback)Delegate.Combine((Delegate?)(object)obj.onComplete, (Delegate?)(TweenCallback)delegate
							{
								//IL_0002: Unknown result type (might be due to invalid IL or missing references)
								skipTextActiveState = (SkipState)1;
							});
							skipTextActiveState = (SkipState)2;
							skipTextTimer = 0f;
						}
					}
					else if ((int)skipTextActiveState == 1 && !flag && (gameInput.GetButtonHeld(64, 0) || gameInput.GetButtonHeld(4, 0)))
					{
						Tween obj2 = effects.FadeSkipIn(skipFadeDuration, (UpdateType)3);
						obj2.onComplete = (TweenCallback)Delegate.Combine((Delegate?)(object)obj2.onComplete, (Delegate?)(TweenCallback)delegate
						{
							//IL_0002: Unknown result type (might be due to invalid IL or missing references)
							skipTextActiveState = (SkipState)3;
						});
						skipTextActiveState = (SkipState)2;
					}
				}
				skipStartTimer += dt;
				if (num && skipStartTimer >= 0.5f)
				{
					skipTimer += dt;
					skipTextTimer = 0f;
				}
				else
				{
					skipTimer = 0f;
				}
			}
			if (!disabledExit && skipTimer >= skipThreshold)
			{
				((MonoBehaviour)this).StartCoroutine(ExitSequenceRoutine());
			}
		}

		private IEnumerator ExitSequenceRoutine()
		{
			if ((int)player.sequenceState != 2)
			{
				player.sequenceState = (SequenceState)2;
				Core coreInstance = Core.Instance;
				EffectsUI effectsUI = base.uIManager.effects;
				skipTextActiveState = (SkipState)4;
				effectsUI.FadeSkipOut(skipFadeDuration, (UpdateType)3);
				_ = Time.deltaTime;
				_ = fadeDuration;
				Tween val = effectsUI.FadeToBlack(fadeDuration);
				yield return TweenExtensions.WaitForCompletion(val);
				yield return (object)new WaitForSeconds(shutDuration);
				SetExitSequence();
				yield return (object)new WaitForSeconds(shutDuration);
				yield return (object)new WaitWhile((Func<bool>)(() => coreInstance.IsCorePaused));
				if (!IsInSequence())
				{
					effectsUI.FadeOpen(fadeDuration);
					isBusy = false;
					effectsUI.HideVerticalBars();
				}
			}
		}

		public override void Activate()
		{
		}

		public override void Deactivate()
		{
		}

		private void StopAllSequenceActions()
		{
			foreach (Coroutine queuedSequenceAction in queuedSequenceActions)
			{
				if (queuedSequenceAction != null)
				{
					((MonoBehaviour)this).StopCoroutine(queuedSequenceAction);
				}
			}
			queuedSequenceActions.Clear();
		}

		private void SetExitSequence()
		{
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			StopAllSequenceActions();
			if (hidePlayer)
			{
				player.HideForSequence(false);
			}
			if (pausePlayer)
			{
				player.PauseForSequence(false);
			}
			if (lowerVolume || (base.audioManager.IsVolumeLowered && !IsInSequence()))
			{
				lowerVolume = false;
				base.audioManager.StopTemporarilyLowerVolume((MonoBehaviour)(object)this);
			}
			player.sequenceState = (SequenceState)4;
			player.RecheckLoopingSounds();
			sequence.time = 0.0;
			sequence.Stop();
			WorldHandler val = WorldHandler.instance;
			if (Object.op_Implicit((Object)(object)val))
			{
				Player currentPlayer = val.GetCurrentPlayer();
				if ((Object)(object)currentPlayer != (Object)null)
				{
					GameplayCamera cam = currentPlayer.cam;
					if ((Object)(object)cam != (Object)null && (Object)(object)val.CurrentCamera != (Object)(object)cam.cam)
					{
						((Behaviour)val.CurrentCamera).enabled = false;
					}
				}
			}
			base.uIManager.AbsolutePopIfPresent((IUIMenuController)(object)this);
			if (base.uIManager.dialogueUI.IsShowingDialogue())
			{
				base.uIManager.dialogueUI.AbortDialogue();
			}
			LetPlayerExitSequence();
		}

		public void LetPlayerExitSequence()
		{
			player.userInputEnabled = true;
			((Component)player.ui).gameObject.SetActive(true);
			player.phone.SetAllCamerasForSequenceExit();
			player.phone.AllowPhone(true, false, allowPhoneOnAfterSequence);
			player.EnablePlayer(false);
			if (!base.uIManager.IsShowingAnyMenu && baseModule.IsPlayingInStage)
			{
				baseModule.StageManager.RestoreCurrentPlayerInput();
			}
		}

		private void FastForwardTypewriter()
		{
			base.uIManager.dialogueUI.FastForwardTypewriter();
		}

		public void StartEnteringSequence(CustomSequence setSequence, CustomInteractable interactable = null, bool setHidePlayer = true, bool setInterruptPlayer = true, bool instantly = false, bool setPausePlayer = false, bool setAllowPhoneOnAfterSequence = true, bool skippable = true, bool lowerVolumeDuringSequence = false, bool disabledExitOnInput = false)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Invalid comparison between Unknown and I4
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			this.interactable = interactable;
			sequenceOverwritten = false;
			if (IsInSequence() && (int)player.sequenceState != 3)
			{
				sequenceOverwritten = true;
			}
			if (player.ability == player.characterSelectAbility)
			{
				instantly = false;
			}
			sequence = setSequence;
			skipTimer = 0f;
			skipTextActiveState = (SkipState)(skippable ? 1 : 0);
			skipTextTimer = 0f;
			isBusy = true;
			hidePlayer = setHidePlayer;
			allowPhoneOnAfterSequence = setAllowPhoneOnAfterSequence;
			interruptPlayer = setInterruptPlayer;
			pausePlayer = setPausePlayer;
			lowerVolume = lowerVolume != lowerVolumeDuringSequence && lowerVolumeDuringSequence;
			disabledExit = disabledExitOnInput;
			base.audioManager.PauseAllGameplayLoopingSfx();
			base.audioManager.ClearAllGameplayLoopingSfx();
			if (base.uIManager.IsShowingAnyMenu)
			{
				base.uIManager.PopAllMenusInstant();
			}
			if (instantly)
			{
				SetInSequenceImmediate();
			}
			else
			{
				((MonoBehaviour)this).StartCoroutine(EnterSequenceRoutine());
			}
		}

		private IEnumerator EnterSequenceRoutine()
		{
			player.sequenceState = (SequenceState)0;
			if (player.inGraffitiGame)
			{
				yield return (object)new WaitUntil((Func<bool>)(() => !player.inGraffitiGame));
			}
			if (player.ability == player.characterSelectAbility)
			{
				yield return (object)new WaitUntil((Func<bool>)(() => player.ability != player.characterSelectAbility));
			}
			else if (player.ability == player.danceAbility)
			{
				player.StopCurrentAbility();
			}
			player.userInputEnabled = false;
			player.phone.AllowPhone(false, false, false);
			SetPartiallyInSequence();
			yield return TweenExtensions.WaitForCompletion(base.uIManager.effects.FadeToBlack(fadeDuration));
			SetFullyInSequence();
			yield return (object)new WaitForSeconds(shutDuration);
			base.uIManager.effects.FadeOpen(fadeDuration);
			base.uIManager.effects.ShowVerticalBars();
		}

		private void SetPartiallyInSequence()
		{
			player.FlushInput();
			if (interruptPlayer)
			{
				player.CompletelyStop();
			}
			if (pausePlayer)
			{
				player.PauseForSequence(true);
			}
			player.StopHoldProps();
			player.DestroyPickupVisuals();
			player.phone.AllowPhone(false, false, false);
			if (!sequenceOverwritten)
			{
				player.DisablePlayer();
			}
			if (lowerVolume)
			{
				base.audioManager.StartTemporarilyLowerVolume((MonoBehaviour)(object)this);
			}
		}

		private void SetFullyInSequence()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			player.sequenceState = (SequenceState)1;
			if (hidePlayer)
			{
				player.HideForSequence(true);
			}
			gameInput.DisableAllControllerMaps(0);
			gameInput.EnableControllerMap(1, 0);
			if (!((AMenuController)this).IsEnabled)
			{
				base.uIManager.PushNewMenuInstant((IUIMenuController)(object)this);
			}
			((Component)player.ui).gameObject.SetActive(false);
			sequence.Init();
			if ((Object)(object)interactable != (Object)null)
			{
				interactable.OnSequenceBegin(sequence);
			}
			sequence.Play();
			skipStartTimer = 0f;
		}

		private void SetInSequenceImmediate()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			EffectsUI effects = base.uIManager.effects;
			if (!effects.IsFadedToColor(EffectsUI.niceClear))
			{
				effects.FadeOpen(0f);
				effects.ShowVerticalBars();
			}
			SetPartiallyInSequence();
			SetFullyInSequence();
		}

		public bool IsInSequence()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Invalid comparison between Unknown and I4
			return (int)player.sequenceState != 4;
		}

		public void SetPreEnteringSequence()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			player.sequenceState = (SequenceState)3;
		}

		private void OnCoreUpdatePaused()
		{
			if (sequence != null && !base.uIManager.dialogueUI.isYesNoPromptEnabled)
			{
				_ = disabledExit;
			}
		}

		private void OnCoreUpdateUnPaused()
		{
			if (sequence != null && !base.uIManager.dialogueUI.isYesNoPromptEnabled)
			{
				_ = disabledExit;
			}
		}
	}
	public class CustomStorage
	{
		public static CustomStorage Instance;

		private Thread _storageThread;

		private bool _running = true;

		private Queue<CustomTransaction> _transactionQueue = new Queue<CustomTransaction>();

		internal CustomStorage()
		{
			Instance = this;
			_storageThread = new Thread(StorageLoop);
			_storageThread.IsBackground = true;
			_storageThread.Name = "CustomStorageThread";
			_storageThread.Start();
		}

		private void StorageLoop()
		{
			while (_running)
			{
				if (_transactionQueue.Count > 0)
				{
					_transactionQueue.Peek().Process();
					_transactionQueue.Dequeue();
				}
				else
				{
					Thread.Sleep(100);
				}
			}
		}

		internal void HandleQuit()
		{
			CommonAPIPlugin.Log.LogInfo((object)"Flushing custom save files...");
			DateTime dateTime = DateTime.Now + TimeSpan.FromSeconds(15.0);
			while (_transactionQueue.Count > 0)
			{
				if (DateTime.Now > dateTime)
				{
					throw new Exception("Could not finish saving to save files, the thread was aborted prematurely!");
				}
			}
			_running = false;
		}

		public void WriteFile(byte[] data, string path)
		{
			CustomSaveTransaction item = new CustomSaveTransaction(data, path);
			_transactionQueue.Enqueue(item);
		}
	}
	internal abstract class CustomTransaction
	{
		public abstract void Process();
	}
	public class EventDrivenInteractable : CustomInteractable
	{
		public Func<Player, bool> OnTest;

		public Func<Vector3> OnGetLookAtPos;

		public Action<Player> OnInteract;

		public override Vector3 GetLookAtPos()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			if (OnGetLookAtPos == null)
			{
				return base.GetLookAtPos();
			}
			return OnGetLookAtPos();
		}

		public override void Interact(Player player)
		{
			if (OnInteract == null)
			{
				base.Interact(player);
			}
			else
			{
				OnInteract(player);
			}
		}

		public override bool Test(Player player)
		{
			if (OnTest == null)
			{
				return base.Test(player);
			}
			return OnTest(player);
		}
	}
	public enum InteractableIcon
	{
		Talk,
		Graffiti,
		Custom
	}
	public static class SaveAPI
	{
		public delegate void SaveGameDelegate(int saveSlot, string saveSlotFilename, int fileId);

		[CompilerGenerated]
		private static class <>O
		{
			public static OnStageInitializedDelegate <0>__StageManager_OnStageInitialized;

			public static OnStageInitializedDelegate <1>__StageManager_OnStagePostInitialization;
		}

		public static SaveGameDelegate OnNewGame;

		public static SaveGameDelegate OnSaveGame;

		public static SaveGameDelegate OnDeleteGame;

		public static SaveGameDelegate OnLoadStageInitialized;

		public static SaveGameDelegate OnLoadStagePostInitialization;

		internal static bool AlreadyRanOnLoadStageInitialized = false;

		internal static bool AlreadyRanOnLoadStagePostInitialization = false;

		private static List<CustomSaveData> _customSaveDatas = new List<CustomSaveData>();

		public static void RegisterCustomSaveData(CustomSaveData customSaveData)
		{
			if (!customSaveData.Filename.Contains("{0}"))
			{
				throw new Exception("Can't register save data for " + customSaveData.GetType()?.ToString() + ", Filename is missing a \"{0}\" token to differentiate save slots. Filename is: " + customSaveData.Filename);
			}
			if (CommonAPISettings.Debug)
			{
				CommonAPIPlugin.Log.LogDebug((object)$"Registering custom save data {customSaveData.GetType()}");
			}
			_customSaveDatas.Add(customSaveData);
		}

		internal static void Initialize()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			object obj = <>O.<0>__StageManager_OnStageInitialized;
			if (obj == null)
			{
				OnStageInitializedDelegate val = StageManager_OnStageInitialized;
				<>O.<0>__StageManager_OnStageInitialized = val;
				obj = (object)val;
			}
			StageManager.OnStageInitialized += (OnStageInitializedDelegate)obj;
			object obj2 = <>O.<1>__StageManager_OnStagePostInitialization;
			if (obj2 == null)
			{
				OnStageInitializedDelegate val2 = StageManager_OnStagePostInitialization;
				<>O.<1>__StageManager_OnStagePostInitialization = val2;
				obj2 = (object)val2;
			}
			StageManager.OnStagePostInitialization += (OnStageInitializedDelegate)obj2;
		}

		internal static void OnSetCurrentSaveSlot()
		{
			if (Core.Instance.SaveManager.HasCurrentSaveSlot)
			{
				int saveSlotId = Core.Instance.SaveManager.CurrentSaveSlot.saveSlotId;
				string saveSlotFileName = Core.Instance.SaveManager.saveSlotHandler.GetSaveSlotFileName(saveSlotId);
				if (CommonAPISettings.Debug)
				{
					CommonAPIPlugin.Log.LogInfo((object)$"Loading into save slot {saveSlotId}, filename: {saveSlotFileName} (Set Current Save Slot)");
				}
				LoadAllCustomData(GetFilenameID(saveSlotFileName));
			}
		}

		private static void StageManager_OnStageInitialized()
		{
			if (!AlreadyRanOnLoadStageInitialized)
			{
				int saveSlotId = Core.Instance.SaveManager.CurrentSaveSlot.saveSlotId;
				string saveSlotFileName = Core.Instance.SaveManager.saveSlotHandler.GetSaveSlotFileName(saveSlotId);
				if (CommonAPISettings.Debug)
				{
					CommonAPIPlugin.Log.LogDebug((object)$"Loading into save slot {saveSlotId}, filename: {saveSlotFileName} (Initialized)");
				}
				int filenameID = GetFilenameID(saveSlotFileName);
				OnLoadStageInitialized?.Invoke(saveSlotId, saveSlotFileName, filenameID);
				AlreadyRanOnLoadStageInitialized = true;
			}
		}

		private static void StageManager_OnStagePostInitialization()
		{
			if (!AlreadyRanOnLoadStagePostInitialization)
			{
				int saveSlotId = Core.Instance.SaveManager.CurrentSaveSlot.saveSlotId;
				string saveSlotFileName = Core.Instance.SaveManager.saveSlotHandler.GetSaveSlotFileName(saveSlotId);
				if (CommonAPISettings.Debug)
				{
					CommonAPIPlugin.Log.LogDebug((object)$"Loading into save slot {saveSlotId}, filename: {saveSlotFileName} (PostInitialiation)");
				}
				OnLoadStagePostInitialization?.Invoke(saveSlotId, saveSlotFileName, GetFilenameID(saveSlotFileName));
				AlreadyRanOnLoadStagePostInitialization = true;
			}
		}

		internal static void DeleteAllCustomData(int fileID)
		{
			foreach (CustomSaveData customSaveData in _customSaveDatas)
			{
				string filenameForFileID = customSaveData.GetFilenameForFileID(fileID);
				string backupFilenameForFileID = customSaveData.GetBackupFilenameForFileID(fileID);
				if (File.Exists(filenameForFileID))
				{
					if (CommonAPISettings.Debug)
					{
						CommonAPIPlugin.Log.LogDebug((object)$"Deleting custom data for {customSaveData.GetType()}, file: {filenameForFileID}");
					}
					File.Delete(filenameForFileID);
				}
				if (File.Exists(backupFilenameForFileID))
				{
					File.Delete(backupFilenameForFileID);
				}
			}
		}

		internal static void SaveAllCustomData(int fileID)
		{
			foreach (CustomSaveData customSaveData in _customSaveDatas)
			{
				if (customSaveData.AutoSave || customSaveData.QueuedSave)
				{
					customSaveData.QueuedSave = false;
					WriteData(customSaveData, customSaveData.GetFilenameForFileID(fileID));
				}
			}
		}

		internal static void SaveBackupsOfCustomData(int fileID)
		{
			foreach (CustomSaveData customSaveData in _customSaveDatas)
			{
				WriteData(customSaveData, customSaveData.GetBackupFilenameForFileID(fileID));
			}
		}

		private static void WriteData(CustomSaveData saveData, string filename)
		{
			if (CommonAPISettings.Debug)
			{
				CommonAPIPlugin.Log.LogDebug((object)$"Writing custom data for {saveData.GetType()}, file: {filename}");
			}
			MemoryStream memoryStream = new MemoryStream();
			BinaryWriter binaryWriter = new BinaryWriter(memoryStream);
			saveData.Write(binaryWriter);
			binaryWriter.Flush();
			byte[] data = memoryStream.ToArray();
			CustomStorage.Instance.WriteFile(data, filename);
			binaryWriter.Dispose();
			memoryStream.Dispose();
		}

		private static bool TryLoadCustomData(CustomSaveData saveData, string filename)
		{
			saveData.FailedToLoad = false;
			try
			{
				FileStream fileStream = new FileStream(filename, FileMode.Open);
				BinaryReader binaryReader = new BinaryReader(fileStream);
				saveData.Read(binaryReader);
				binaryReader.Dispose();
				fileStream.Dispose();
				if (saveData.FailedToLoad)
				{
					CommonAPIPlugin.Log.LogError((object)$"Failed to load custom data for {saveData.GetType()} (Handled), file: {filename}");
					return false;
				}
			}
			catch (Exception ex)
			{
				CommonAPIPlugin.Log.LogError((object)$"Failed to load custom data for {saveData.GetType()} (Unhandled), file: {filename}{Environment.NewLine}{ex}");
				return false;
			}
			return true;
		}

		internal static void LoadAllCustomData(int fileID)
		{
			foreach (CustomSaveData customSaveData in _customSaveDatas)
			{
				customSaveData.QueuedSave = false;
				string text = customSaveData.GetFilenameForFileID(fileID);
				string backupFilenameForFileID = customSaveData.GetBackupFilenameForFileID(fileID);
				if (!File.Exists(text))
				{
					text = backupFilenameForFileID;
				}
				if (File.Exists(text))
				{
					if (CommonAPISettings.Debug)
					{
						CommonAPIPlugin.Log.LogDebug((object)$"Loading custom data for {customSaveData.GetType()}, file: {text}");
					}
					bool flag = TryLoadCustomData(customSaveData, text);
					if (!flag)
					{
						customSaveData.Initialize();
						if (File.Exists(backupFilenameForFileID))
						{
							CommonAPIPlugin.Log.LogInfo((object)$"Will load backup file for {customSaveData.GetType()}.");
							flag = TryLoadCustomData(customSaveData, backupFilenameForFileID);
						}
						if (!flag)
						{
							CommonAPIPlugin.Log.LogInfo((object)$"Starting a clean save for {customSaveData.GetType()}.");
							customSaveData.Initialize();
						}
					}
				}
				else
				{
					if (CommonAPISettings.Debug)
					{
						CommonAPIPlugin.Log.LogDebug((object)$"Making new custom data for {customSaveData.GetType()}.");
					}
					customSaveData.Initialize();
				}
			}
		}

		internal static void MakeNewForAllCustomData(int fileID)
		{
			foreach (CustomSaveData customSaveData in _customSaveDatas)
			{
				customSaveData.QueuedSave = false;
				string filenameForFileID = customSaveData.GetFilenameForFileID(fileID);
				if (CommonAPISettings.Debug)
				{
					CommonAPIPlugin.Log.LogDebug((object)$"Making new custom data for {customSaveData.GetType()}, file: {filenameForFileID}");
				}
				customSaveData.Initialize();
			}
		}

		internal static int GetFilenameID(string filename)
		{
			string text = "";
			for (int i = 0; i < filename.Length; i++)
			{
				if (char.IsDigit(filename[i]))
				{
					text += filename[i];
				}
			}
			if (int.TryParse(text, out var result))
			{
				return result;
			}
			return -1;
		}
	}
	public enum SaveLocations
	{
		BepInEx,
		Documents,
		LocalAppData,
		Absolute
	}
	public static class StageAPI
	{
		public delegate void StageInitializationDelegate(Stage newStage, Stage previousStage);

		public static StageInitializationDelegate OnStagePreInitialization;
	}
	public static class TextureUtility
	{
		public static Sprite CreateSpriteFromTexture(Texture2D texture)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			return Sprite.Create(texture, new Rect(0f, 0f, (float)((Texture)texture).width, (float)((Texture)texture).height), new Vector2(0.5f, 0.5f), 100f);
		}

		public static Sprite LoadSprite(string path)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			//IL_001b: Expected O, but got Unknown
			Texture2D val = new Texture2D(1, 1);
			byte[] array = File.ReadAllBytes(path);
			ImageConversion.LoadImage(val, array);
			return CreateSpriteFromTexture(val);
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "CommonAPI";

		public const string PLUGIN_NAME = "CommonAPI";

		public const string PLUGIN_VERSION = "1.3.1";
	}
}
namespace CommonAPI.UI
{
	public static class RectTransformExtensions
	{
		public static void SetBounds(this RectTransform rect, float left, float top, float right, float bottom)
		{
			//IL_0005: 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)
			rect.offsetMin = new Vector2(0f - left, 0f - top);
			rect.offsetMax = new Vector2(right, bottom);
		}

		public static void SetAnchor(this RectTransform rect, float x, float y)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(x, y);
			rect.anchorMin = val;
			rect.anchorMax = val;
		}

		public static void SetPivot(this RectTransform rect, float x, float y)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			rect.pivot = new Vector2(x, y);
		}

		public static void SetAnchorAndPivot(this RectTransform rect, float x, float y)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(x, y);
			rect.anchorMin = val;
			rect.anchorMax = val;
			rect.pivot = val;
		}

		public static void StretchToFillParent(this RectTransform rect)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			rect.anchorMin = Vector2.zero;
			rect.anchorMax = Vector2.one;
			rect.SetBounds(0f, 0f, 0f, 0f);
		}
	}
}
namespace CommonAPI.Phone
{
	public static class AppUtility
	{
		public static readonly Vector2 AppSize = new Vector2(1070f, 1740f);

		public static TMP_FontAsset GetAppFont()
		{
			return ((TMP_Text)((Component)((Component)((Component)WorldHandler.instance.GetCurrentPlayer().phone.GetAppInstance<AppGraffiti>()).transform.Find("Overlay")).transform.Find("Icons").Find("HeaderLabel")).GetComponent<TextMeshProUGUI>()).font;
		}

		internal static App CreateApp(Type appType, Transform root)
		{
			//IL_0006: 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_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(appType.Name)
			{
				layer = 24
			};
			RectTransform val2 = val.AddComponent<RectTransform>();
			((Transform)val2).SetParent(root, false);
			val2.sizeDelta = AppSize;
			val2.SetAnchorAndPivot(0.5f, 1f);
			GameObject val3 = new GameObject("Content")
			{
				layer = 24
			};
			val3.transform.SetParent((Transform)(object)val2, false);
			val3.AddComponent<RectTransform>().StretchToFillParent();
			Component obj = val.AddComponent(appType);
			return (App)(object)((obj is App) ? obj : null);
		}
	}
	public abstract class CustomApp : App
	{
		public const float TitleBarHeight = 275f;

		public PhoneScrollView ScrollView;

		public virtual int Unread { get; }

		public virtual bool Available { get; } = true;


		public override void OnAppInit()
		{
			base.m_Unlockables = Array.Empty<AUnlockable>();
		}

		public override void OnReleaseRight()
		{
			((App)this).OnReleaseRight();
			ScrollView?.OnReleaseRight();
		}

		public override void OnPressRight()
		{
			((App)this).OnPressRight();
			ScrollView?.OnPressRight();
		}

		public override void OnPressUp()
		{
			((App)this).OnPressUp();
			ScrollView?.OnPressUp();
		}

		public override void OnPressDown()
		{
			((App)this).OnPressDown();
			ScrollView?.OnPressDown();
		}

		public override void OnHoldDown()
		{
			((App)this).OnHoldDown();
			ScrollView?.OnHoldDown();
		}

		public override void OnHoldUp()
		{
			((App)this).OnHoldUp();
			ScrollView?.OnHoldUp();
		}

		public override void OnReleaseDown()
		{
			((App)this).OnReleaseDown();
			ScrollView?.OnReleaseDown();
		}

		public override void OnReleaseUp()
		{
			((App)this).OnReleaseUp();
			ScrollView?.OnReleaseUp();
		}

		public void PlayBackSFX()
		{
			base.m_AudioManager.PlaySfxGameplay((SfxCollectionID)14, (AudioClipID)305, 0f);
		}

		public void PlayConfirmSFX()
		{
			base.m_AudioManager.PlaySfxGameplay((SfxCollectionID)14, (AudioClipID)306, 0f);
		}

		public void PlaySelectSFX()
		{
			base.m_AudioManager.PlaySfxGameplay((SfxCollectionID)14, (AudioClipID)308, 0f);
		}

		protected void CreateIconlessTitleBar(string title, float fontSize = 80f)
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			Transform obj = Object.Instantiate<Transform>(((Component)((App)this).MyPhone.GetAppInstance<AppGraffiti>()).transform.Find("Overlay"));
			Transform obj2 = ((Component)obj).transform.Find("Icons");
			Object.Destroy((Object)(object)((Component)obj2.Find("GraffitiIcon")).gameObject);
			Transform val = obj2.Find("HeaderLabel");
			val.localPosition = new Vector3(140f, val.localPosition.y, val.localPosition.z);
			Object.Destroy((Object)(object)((Component)val).GetComponent<TMProLocalizationAddOn>());
			TextMeshProUGUI component = ((Component)val).GetComponent<TextMeshProUGUI>();
			((TMP_Text)component).text = title;
			((TMP_Text)component).fontSize = fontSize;
			((TMP_Text)component).fontSizeMax = fontSize;
			((TMP_Text)component).fontSizeMin = fontSize;
			obj.SetParent(((Component)this).transform, false);
		}

		protected void CreateTitleBar(string title, Sprite icon = null, float fontSize = 80f)
		{
			Transform obj = Object.Instantiate<Transform>(((Component)((App)this).MyPhone.GetAppInstance<AppGraffiti>()).transform.Find("Overlay"));
			Transform obj2 = ((Component)obj).transform.Find("Icons");
			((Component)obj2.Find("GraffitiIcon")).GetComponent<Image>().sprite = icon;
			Transform obj3 = obj2.Find("HeaderLabel");
			Object.Destroy((Object)(object)((Component)obj3).GetComponent<TMProLocalizationAddOn>());
			TextMeshProUGUI component = ((Component)obj3).GetComponent<TextMeshProUGUI>();
			((TMP_Text)component).text = title;
			((TMP_Text)component).fontSize = fontSize;
			((TMP_Text)component).fontSizeMax = fontSize;
			((TMP_Text)component).fontSizeMin = fontSize;
			obj.SetParent(((Component)this).transform, false);
		}
	}
	public static class PhoneAPI
	{
		internal static List<RegisteredPhoneApp> Apps;

		internal static Dictionary<string, RegisteredPhoneApp> PhoneAppByTypeName;

		private static bool Initialized;

		internal static void Initialize()
		{
			if (!Initialized)
			{
				Initialized = true;
				Apps = new List<RegisteredPhoneApp>();
				PhoneAppByTypeName = new Dictionary<string, RegisteredPhoneApp>();
			}
		}

		internal static void RegisterApp(Type appType, string title, Sprite icon = null)
		{
			if (!Initialized)
			{
				Initialize();
			}
			RegisteredPhoneApp registeredPhoneApp = new RegisteredPhoneApp
			{
				AppType = appType,
				Icon = icon,
				Title = title
			};
			Apps.Add(registeredPhoneApp);
			PhoneAppByTypeName[appType.Name] = registeredPhoneApp;
		}

		public static void RegisterApp<T>(string title, Sprite icon = null) where T : CustomApp
		{
			RegisterApp(typeof(T), title, icon);
		}
	}
	public abstract class PhoneButton : MonoBehaviour
	{
		public bool BeingPressed;

		public Action OnConfirm;

		public abstract float Width { get; }

		public abstract float Height { get; }

		public virtual void PlayHighlightAnimation()
		{
		}

		public virtual void PlayDeselectAnimation(bool skip = false)
		{
		}

		public virtual void PlayHoldAnimation()
		{
		}

		public virtual void Confirm()
		{
			OnConfirm?.Invoke();
		}
	}
	public class PhoneScrollView : MonoBehaviour
	{
		public const float DefaultLength = 1600f;

		public float AnimationSpeed = 0.1f;

		public List<PhoneButton> Buttons = new List<PhoneButton>();

		public float Separation = 50f;

		public float Height = 275f;

		public float Length = 1600f;

		public int SelectedIndex;

		public CustomApp App;

		public float CurrentScroll;

		private float continuousScrollTimer;

		public static PhoneScrollView Create(CustomApp app, float height = 275f, float length = 1600f)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Scroll View");
			val.transform.SetParent((Transform)(object)((App)app).Content, false);
			PhoneScrollView phoneScrollView = val.AddComponent<PhoneScrollView>();
			phoneScrollView.App = app;
			RectTransform obj = val.AddComponent<RectTransform>();
			obj.anchorMin = Vector2.zero;
			obj.anchorMax = Vector2.one;
			phoneScrollView.Height = height;
			phoneScrollView.Length = length;
			obj.anchoredPosition = new Vector2(0f, 0f - height);
			val.layer = 24;
			return phoneScrollView;
		}

		public bool ValidateSelectedIndex()
		{
			if (Buttons.Count <= 0)
			{
				return false;
			}
			if (SelectedIndex < 0)
			{
				SelectedIndex = 0;
			}
			if (SelectedIndex >= Buttons.Count)
			{
				SelectedIndex = Buttons.Count - 1;
			}
			return true;
		}

		public void AddButton(PhoneButton button)
		{
			((Component)button).transform.SetParent(((Component)this).transform, false);
			Buttons.Add(button);
			UpdateButtons();
		}

		public void InsertButton(int index, PhoneButton button)
		{
			((Component)button).transform.SetParent(((Component)this).transform, false);
			Buttons.Insert(index, button);
			UpdateButtons();
		}

		public void RemoveButton(int index)
		{
			PhoneButton phoneButton = Buttons[index];
			Buttons.RemoveAt(index);
			Object.Destroy((Object)(object)((Component)phoneButton).gameObject);
			UpdateButtons();
		}

		public void RemoveButton(PhoneButton button)
		{
			Buttons.Remove(button);
			Object.Destroy((Object)(object)((Component)button).gameObject);
			UpdateButtons();
		}

		public void RemoveAllButtons()
		{
			foreach (PhoneButton button in Buttons)
			{
				Object.Destroy((Object)(object)((Component)button).gameObject);
			}
			Buttons.Clear();
			UpdateButtons();
			ResetScroll();
			CancelAnimation();
		}

		public bool HasButton(PhoneButton button)
		{
			return Buttons.Contains(button);
		}

		public void StartScrollAnimation()
		{
			((MonoBehaviour)this).StartCoroutine(AnimateScrollCoroutine());
		}

		public void CancelAnimation()
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			((MonoBehaviour)this).StopAllCoroutines();
			ComponentExtensions.RectTransform((Component)(object)this).anchoredPosition = new Vector2(0f, 0f - Height + CurrentScroll);
		}

		private IEnumerator AnimateScrollCoroutine()
		{
			RectTransform rect = ComponentExtensions.RectTransform((Component)(object)this);
			float targetY = 0f - Height + CurrentScroll;
			float y = rect.anchoredPosition.y;
			float num = targetY - y;
			float speed = num / AnimationSpeed;
			while (rect.anchoredPosition.y != targetY)
			{
				y = rect.anchoredPosition.y;
				if (targetY > y)
				{
					y += Core.dt * speed;
					if (y > targetY)
					{
						y = targetY;
					}
				}
				else if (targetY < y)
				{
					y += Core.dt * speed;
					if (y < targetY)
					{
						y = targetY;
					}
				}
				rect.anchoredPosition = new Vector2(0f, y);
				yield return null;
			}
		}

		public void OnReleaseRight()
		{
			if (!ValidateSelectedIndex())
			{
				return;
			}
			PhoneButton phoneButton = Buttons[SelectedIndex];
			if (phoneButton.BeingPressed)
			{
				phoneButton.PlayHighlightAnimation();
				App.PlayConfirmSFX();
				phoneButton.Confirm();
			}
			foreach (PhoneButton button in Buttons)
			{
				button.BeingPressed = false;
			}
		}

		public void OnPressRight()
		{
			if (ValidateSelectedIndex())
			{
				PhoneButton phoneButton = Buttons[SelectedIndex];
				phoneButton.BeingPressed = true;
				phoneButton.PlayHoldAnimation();
			}
		}

		public void OnPressUp()
		{
			ScrollUp();
			continuousScrollTimer -= 0.4f;
		}

		public void OnPressDown()
		{
			ScrollDown();
			continuousScrollTimer -= 0.4f;
		}

		public void OnReleaseUp()
		{
			continuousScrollTimer = 0f;
		}

		public void OnReleaseDown()
		{
			continuousScrollTimer = 0f;
		}

		public void OnHoldUp()
		{
			continuousScrollTimer += Core.dt;
			if (continuousScrollTimer >= 0.1f)
			{
				continuousScrollTimer = 0f;
				ScrollUp();
			}
		}

		public void OnHoldDown()
		{
			continuousScrollTimer += Core.dt;
			if (continuousScrollTimer >= 0.1f)
			{
				continuousScrollTimer = 0f;
				ScrollDown();
			}
		}

		public void ScrollUp()
		{
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			App.PlaySelectSFX();
			if (ValidateSelectedIndex())
			{
				PhoneButton phoneButton = Buttons[SelectedIndex];
				SelectedIndex--;
				if (SelectedIndex < 0)
				{
					SelectedIndex = 0;
				}
				PhoneButton phoneButton2 = Buttons[SelectedIndex];
				if ((Object)(object)phoneButton2 != (Object)(object)phoneButton)
				{
					phoneButton.PlayDeselectAnimation();
					phoneButton2.PlayHighlightAnimation();
				}
				float y = ComponentExtensions.RectTransform((Component)(object)phoneButton2).anchoredPosition.y;
				if (0f - y + phoneButton2.Height / 2f + Separation - CurrentScroll < phoneButton2.Height / 2f + Separation)
				{
					CancelAnimation();
					CurrentScroll = 0f - y - phoneButton2.Height / 2f - Separation;
					StartScrollAnimation();
				}
			}
		}

		public void ResetScroll()
		{
			SelectedIndex = 0;
			CurrentScroll = 0f;
			UpdateButtons();
		}

		public void ScrollDown()
		{
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			App.PlaySelectSFX();
			if (ValidateSelectedIndex())
			{
				PhoneButton phoneButton = Buttons[SelectedIndex];
				SelectedIndex++;
				if (SelectedIndex >= Buttons.Count)
				{
					SelectedIndex = Buttons.Count - 1;
				}
				PhoneButton phoneButton2 = Buttons[SelectedIndex];
				if ((Object)(object)phoneButton2 != (Object)(object)phoneButton)
				{
					phoneButton.PlayDeselectAnimation();
					phoneButton2.PlayHighlightAnimation();
				}
				float y = ComponentExtensions.RectTransform((Component)(object)phoneButton2).anchoredPosition.y;
				if (0f - y + phoneButton2.Height / 2f + Separation - CurrentScroll > Length)
				{
					CancelAnimation();
					float num = Mathf.Ceil(Length / (phoneButton2.Height + Separation));
					num -= 2f;
					CurrentScroll = 0f - y - phoneButton2.Height / 2f - Separation;
					CurrentScroll -= num * (phoneButton2.Height + Separation);
					StartScrollAnimation();
				}
			}
		}

		public void UpdateButtons()
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			if (ValidateSelectedIndex())
			{
				float num = Separation;
				for (int i = 0; i < Buttons.Count; i++)
				{
					PhoneButton phoneButton = Buttons[i];
					phoneButton.PlayDeselectAnimation(skip: true);
					ComponentExtensions.RectTransform((Component)(object)phoneButton).anchoredPosition = new Vector2((0f - phoneButton.Width) / 2f, (0f - phoneButton.Height) / 2f - num);
					num += phoneButton.Height + Separation;
				}
				Buttons[SelectedIndex].PlayHighlightAnimation();
			}
		}
	}
	public static class PhoneUIUtility
	{
		public static SimplePhoneButton CreateSimpleButton(string label)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Expected O, but got Unknown
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Expected O, but got Unknown
			//IL_0191: Expected O, but got Unknown
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Expected O, but got Unknown
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_021d: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Simple Button");
			val.layer = 24;
			SimplePhoneButton simplePhoneButton = val.AddComponent<SimplePhoneButton>();
			GameObject val2 = new GameObject("Animation Parent");
			val2.layer = 24;
			GameObject val3 = new GameObject("Button Image")
			{
				layer = 24
			};
			val3.transform.SetParent(val2.transform, false);
			val2.transform.SetParent(val.transform, false);
			Image buttonImage = val3.AddComponent<Image>();
			simplePhoneButton.ButtonImage = buttonImage;
			GameObjectExtensions.RectTransform(val3).sizeDelta = new Vector2(1060f, 150f);
			simplePhoneButton.SetGraphics();
			RectTransform obj = val.AddComponent<RectTransform>();
			obj.anchorMax = new Vector2(1f, 1f);
			obj.anchorMin = new Vector2(1f, 1f);
			obj.pivot = new Vector2(1f, 1f);
			simplePhoneButton.AnimationParent = val2.transform;
			GameObject val4 = new GameObject("Label");
			TextMeshProUGUI val5 = val4.AddComponent<TextMeshProUGUI>();
			((TMP_Text)val5).text = label;
			((TMP_Text)val5).alignment = (TextAlignmentOptions)513;
			((TMP_Text)val5).font = AppUtility.GetAppFont();
			((TMP_Text)val5).fontSize = 60f;
			((TMP_Text)val5).fontSizeMax = 60f;
			((TMP_Text)val5).fontSizeMin = 50f;
			((TMP_Text)val5).enableAutoSizing = true;
			simplePhoneButton.Label = val5;
			val4.transform.SetParent(val2.transform, false);
			val4.transform.localPosition = new Vector3(-475f, 0f, 0f);
			GameObjectExtensions.RectTransform(val4).SetAnchorAndPivot(0f, 0.5f);
			GameObjectExtensions.RectTransform(val4).sizeDelta = new Vector2(850f, 100f);
			simplePhoneButton.ConfirmArrow = new GameObject("Confirm Arrow");
			simplePhoneButton.ConfirmArrow.layer = 24;
			simplePhoneButton.ConfirmArrow.transform.SetParent(val2.transform, false);
			simplePhoneButton.ConfirmArrow.AddComponent<Image>().sprite = SimplePhoneButton.ConfirmArrowSprite;
			RectTransform obj2 = GameObjectExtensions.RectTransform(simplePhoneButton.ConfirmArrow);
			obj2.sizeDelta = new Vector2(50f, 90f);
			((Transform)obj2).localPosition = new Vector3(425f, 0f, 0f);
			return simplePhoneButton;
		}
	}
	internal class RegisteredPhoneApp
	{
		public string Title;

		public Sprite Icon;

		public Type AppType;
	}
	public class SimplePhoneButton : PhoneButton
	{
		public const float ButtonImageWidth = 1060f;

		public const float ButtonImageHeight = 150f;

		public const float ConfirmArrowWidth = 50f;

		public const float ConfirmArrowHeight = 90f;

		private static bool LoadedResources;

		private static Sprite ButtonSprite_Unselected;

		private static Sprite ButtonSprite_Selected;

		public static Sprite ConfirmArrowSprite;

		public Image ButtonImage;

		public Sprite SelectedButtonSprite;

		public Sprite UnselectedButtonSprite;

		public Transform AnimationParent;

		public TextMeshProUGUI Label;

		public GameObject ConfirmArrow;

		public Color LabelSelectedColor = Color32.op_Implicit(new Color32((byte)49, (byte)90, (byte)165, byte.MaxValue));

		public Color LabelUnselectedColor = Color.white;

		public override float Width => ((Graphic)ButtonImage).rectTransform.sizeDelta.x;

		public override float Height => ((Graphic)ButtonImage).rectTransform.sizeDelta.y;

		public override void PlayHoldAnimation()
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			TweenSettingsExtensions.SetEase<TweenerCore<Vector3, Vector3, VectorOptions>>(ShortcutExtensions.DOLocalMoveX(AnimationParent, 50f, 0.05f, false), (Ease)1);
			ButtonImage.sprite = ButtonSprite_Selected;
			((TMP_Text)Label).faceColor = Color32.op_Implicit(LabelSelectedColor);
			GameObject confirmArrow = ConfirmArrow;
			if (confirmArrow != null)
			{
				confirmArrow.SetActive(true);
			}
		}

		public override void PlayHighlightAnimation()
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			TweenSettingsExtensions.SetEase<TweenerCore<Vector3, Vector3, VectorOptions>>(ShortcutExtensions.DOLocalMoveX(AnimationParent, 0f, 0.1f, false), (Ease)1);
			ButtonImage.sprite = ButtonSprite_Selected;
			((TMP_Text)Label).faceColor = Color32.op_Implicit(LabelSelectedColor);
			GameObject confirmArrow = ConfirmArrow;
			if (confirmArrow != null)
			{
				confirmArrow.SetActive(true);
			}
		}

		public override void PlayDeselectAnimation(bool skip = false)
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			TweenSettingsExtensions.SetEase<TweenerCore<Vector3, Vector3, VectorOptions>>(ShortcutExtensions.DOLocalMoveX(AnimationParent, 70f, 0.1f * (float)Convert.ToInt32(!skip), false), (Ease)1);
			ButtonImage.sprite = ButtonSprite_Unselected;
			((TMP_Text)Label).faceColor = Color32.op_Implicit(LabelUnselectedColor);
			GameObject confirmArrow = ConfirmArrow;
			if (confirmArrow != null)
			{
				confirmArrow.SetActive(false);
			}
		}

		public static void CacheResources()
		{
			if (!LoadedResources)
			{
				LoadedResources = true;
				ButtonSprite_Unselected = LoadSprite("Phone-SimpleButton.png");
				ButtonSprite_Selected = LoadSprite("Phone-SimpleButton-Selected.png");
				ConfirmArrowSprite = LoadSprite("Phone-ConfirmArrow.png");
			}
		}

		private static Sprite LoadSprite(string filename)
		{
			string path = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)CommonAPIPlugin.Instance).Info.Location), filename);
			if (!File.Exists(path))
			{
				return null;
			}
			return TextureUtility.LoadSprite(path);
		}

		public void SetGraphics()
		{
			CacheResources();
			SelectedButtonSprite = ButtonSprite_Selected;
			UnselectedButtonSprite = ButtonSprite_Unselected;
		}
	}
}
namespace CommonAPI.Patches
{
	[HarmonyPatch(typeof(AppHomeScreen))]
	internal class AppHomeScreenPatch
	{
		[HarmonyPostfix]
		[HarmonyPatch("Awake")]
		private static void Awake_Postfix(AppHomeScreen __instance)
		{
			List<HomeScreenApp> apps = __instance.availableHomeScreenApps.ToList();
			foreach (RegisteredPhoneApp app in PhoneAPI.Apps)
			{
				AddApp(app, ref apps);
			}
			__instance.availableHomeScreenApps = apps.ToArray();
		}

		[HarmonyPostfix]
		[HarmonyPatch("OnAppEnable")]
		private static void OnAppEnable_Postfix(AppHomeScreen __instance)
		{
			foreach (HomeScreenApp item in __instance.availableHomeScreenApps.Where((HomeScreenApp x) => PhoneAPI.PhoneAppByTypeName.ContainsKey(x.AppName)))
			{
				CustomApp customApp = __instance.AppInstance(item.AppName) as CustomApp;
				if (!((Object)(object)customApp == (Object)null))
				{
					if (customApp.Available)
					{
						__instance.AddApp(item);
					}
					else
					{
						__instance.RemoveApp(item);
					}
				}
			}
		}

		private static void AddApp(RegisteredPhoneApp app, ref List<HomeScreenApp> apps)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			HomeScreenApp val = ScriptableObject.CreateInstance<HomeScreenApp>();
			val.m_AppName = app.AppType.Name;
			val.m_DisplayName = app.Title;
			val.m_AppIcon = app.Icon;
			val.appType = (HomeScreenAppType)(-1);
			apps.Add(val);
		}
	}
	[HarmonyPatch(typeof(DialogueUI))]
	internal static class DialogueUIPatch
	{
		[HarmonyPrefix]
		[HarmonyPatch("EndDialogue")]
		private static void EndDialogue_Prefix(DialogueUI __instance)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Invalid comparison between Unknown and I4
			if (!((Object)(object)CustomSequenceHandler.instance == (Object)null))
			{
				CustomSequenceHandler instance = CustomSequenceHandler.instance;
				if (instance.CurrentDialogue != null && (int)instance.CurrentDialogue.ShowBars == 1 && (Object)(object)__instance.effectsUI != (Object)null)
				{
					__instance.effectsUI.HideBars(0.25f, (UpdateType)3);
				}
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch("OnButtonPressed")]
		private static bool OnButtonPressed_Prefix(DialogueUI __instance, bool yesClicked)
		{
			if ((Object)(object)CustomSequenceHandler.instance == (Object)null)
			{
				return true;
			}
			CustomSequenceHandler instance = CustomSequenceHandler.instance;
			if (instance.CurrentDialogue == null)
			{
				return true;
			}
			instance.CurrentDialogue.AnsweredYes = yesClicked;
			if (__instance.IsShowingDialogue())
			{
				__instance.EndDialogue();
			}
			return false;
		}

		[HarmonyPrefix]
		[HarmonyPatch("AbortDialogue")]
		private static void AbortDialogue_Prefix()
		{
			if (!((Object)(object)CustomSequenceHandler.instance == (Object)null))
			{
				CustomSequenceHandler instance = CustomSequenceHandler.instance;
				if (instance.CurrentDialogue != null)
				{
					instance.CurrentDialogue.NextDialogue = null;
					instance.CurrentDialogue.EndSequenceOnFinish = false;
					instance.CurrentDialogue.OnDialogueEnd = null;
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("EndDialogue")]
		private static void EndDialogue_Postfix(DialogueUI __instance)
		{
			if ((Object)(object)CustomSequenceHandler.instance == (Object)null)
			{
				return;
			}
			CustomSequenceHandler instance = CustomSequenceHandler.instance;
			CustomDialogue currentDialogue = instance.CurrentDialogue;
			if (currentDialogue == null)
			{
				return;
			}
			if (currentDialogue.NextDialogue != null)
			{
				instance.StartDialogue(currentDialogue.NextDialogue);
			}
			else
			{
				if (currentDialogue.EndSequenceOnFinish)
				{
					instance.ExitCurrentSequenceDelayed();
				}
				instance.CurrentDialogue = null;
			}
			if (currentDialogue.OnDialogueEnd != null)
			{
				currentDialogue.OnDialogueEnd();
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch("IsShowingDialogue")]
		private static bool IsShowingDialogue_Prefix(ref bool __result)
		{
			if ((Object)(object)CustomSequenceHandler.instance == (Object)null)
			{
				return true;
			}
			if (CustomSequenceHandler.instance.CurrentDialogue != null)
			{
				__result = true;
				return false;
			}
			return true;
		}

		[HarmonyPrefix]
		[HarmonyPatch("UpdateTextLabel")]
		private static bool UpdateTextLabel_Prefix(DialogueUI __instance, string line)
		{
			if ((Object)(object)CustomSequenceHandler.instance == (Object)null)
			{
				return true;
			}
			if (CustomSequenceHandler.instance.CurrentDialogue == null)
			{
				return true;
			}
			CustomDialogue currentDialogue = CustomSequenceHandler.instance.CurrentDialogue;
			if (!string.IsNullOrEmpty(currentDialogue.CharacterName))
			{
				((TMP_Text)__instance.characterNameText).text = $"{currentDialogue.CharacterName}:";
				__instance.characterNameTextContainer.SetActive(true);
			}
			else
			{
				((TMP_Text)__instance.characterNameText).text = string.Empty;
				__instance.characterNameTextContainer.SetActive(false);
			}
			((TMP_Text)__instance.textLabel).text = line;
			__instance.uiManager.SetLocalizationValueOnDialogueText(__instance.textLabel, __instance.gameTextLocalizer, Array.Empty<string>());
			return false;
		}
	}
	[HarmonyPatch(typeof(HomescreenScrollView))]
	internal class HomescreenScrollViewPatch
	{
		[HarmonyPrefix]
		[HarmonyPatch("SetButtonContent")]
		private static bool SetButtonContent_Prefix(HomescreenScrollView __instance, PhoneScrollButton button, int contentIndex)
		{
			HomeScreenApp val = __instance.m_HomeScreen.Apps[contentIndex];
			CustomApp customApp = __instance.m_HomeScreen.AppInstance(val.AppName) as CustomApp;
			if ((Object)(object)customApp == (Object)null)
			{
				return true;
			}
			((HomescreenButton)((button is HomescreenButton) ? button : null)).SetContent(val, customApp.Unread);
			return false;
		}
	}
	[HarmonyPatch(typeof(Phone))]
	internal class PhonePatch
	{
		[HarmonyPrefix]
		[HarmonyPatch("PhoneInit")]
		private static void PhoneInit_Prefix(Phone __instance, Player setPlayer)
		{
			Transform obj = ((Component)__instance).transform.Find("OpenCanvas/PhoneContainerOpen/MainScreen/Apps");
			RectTransform root = (RectTransform)(object)((obj is RectTransform) ? obj : null);
			foreach (RegisteredPhoneApp app in PhoneAPI.Apps)
			{
				AppUtility.CreateApp(app.AppType, (Transform)(object)root);
			}
		}
	}
	[HarmonyPatch(typeof(Player))]
	internal static class PlayerPatch
	{
		[HarmonyPostfix]
		[HarmonyPatch("Init")]
		private static void Init_Postfix(Player __instance)
		{
			CustomPlayerComponent.Attach(__instance);
		}

		[HarmonyPrefix]
		[HarmonyPatch("UpdateSprayCanShake")]
		private static void UpdateSprayCanShake_Prefix(Player __instance)
		{
			CustomPlayerComponent customPlayerComponent = CustomPlayerComponent.Get(__instance);
			if (Object.op_Implicit((Object)(object)customPlayerComponent))
			{
				__instance.talkContextAvailable += customPlayerComponent.CustomInteractableContextAvailable;
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("UpdateSprayCanShake")]
		private static void UpdateSprayCanShake_Postfix(Player __instance)
		{
			CustomPlayerComponent customPlayerComponent = CustomPlayerComponent.Get(__instance);
			if (Object.op_Implicit((Object)(object)customPlayerComponent))
			{
				__instance.talkContextAvailable -= customPlayerComponent.CustomInteractableContextAvailable;
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("ContextIconsUpdate")]
		private static void ContextIconsUpdate_Postfix(Player __instance)
		{
			if (__instance.graffitiContextAvailable > 0 || __instance.talkContextAvailable > 0 || __instance.breakChainContextAvailable > 0)
			{
				return;
			}
			CustomPlayerComponent customPlayerComponent = CustomPlayerComponent.Get(__instance);
			if (!Object.op_Implicit((Object)(object)customPlayerComponent))
			{
				return;
			}
			customPlayerComponent.CustomInteractableContextAvailable = Mathf.Max(customPlayerComponent.CustomInteractableContextAvailable - 1, 0);
			bool flag = customPlayerComponent.CustomInteractableContextAvailable > 0;
			CustomInteractable currentCustomInteractable = customPlayerComponent.CurrentCustomInteractable;
			if (flag && Object.op_Implicit((Object)(object)currentCustomInteractable))
			{
				((Component)__instance.ui.breakChainsContextIcon).gameObject.SetActive(false);
				((Component)__instance.ui.contextGraffitiIcon).gameObject.SetActive(false);
				((Component)__instance.ui.contextTalkIcon).gameObject.SetActive(false);
				((Component)customPlayerComponent.CustomContextIcon).gameObject.SetActive(false);
				__instance.ui.contextLabelUiButtonGlyphComponent.SetButtonTextGlyph(10);
				__instance.ui.ShowContextLabelUI();
				switch (currentCustomInteractable.Icon)
				{
				default:
					((Component)__instance.ui.contextTalkIcon).gameObject.SetActive(true);
					break;
				case InteractableIcon.Graffiti:
					((Component)__instance.ui.contextGraffitiIcon).gameObject.SetActive(true);
					break;
				case InteractableIcon.Custom:
					((Component)customPlayerComponent.CustomContextIcon).gameObject.SetActive(true);
					customPlayerComponent.CustomContextIcon.sprite = currentCustomInteractable.CustomIcon;
					break;
				}
			}
		}
	}
	[HarmonyPatch(typeof(SaveManager))]
	internal static class SaveManagerPatch
	{
		[HarmonyPrefix]
		[HarmonyPatch("SaveCurrentSaveSlotBackup")]
		private static void SaveCurrentSaveSlotBackup_Prefix(SaveManager __instance)
		{
			int currentSaveSlot = __instance.saveSlotSettings.currentSaveSlot;
			SaveAPI.SaveBackupsOfCustomData(SaveAPI.GetFilenameID(__instance.saveSlotHandler.GetSaveSlotFileName(currentSaveSlot)));
		}
	}
	[HarmonyPatch(typeof(SaveSlotHandler))]
	internal static class SaveSlotHandlerPatch
	{
		[HarmonyPostfix]
		[HarmonyPatch("SetCurrentSaveSlotDataBySlotId")]
		private static void SetCurrentSaveSlotDataBySlotID_Postfix(int saveSlotId)
		{
			SaveAPI.AlreadyRanOnLoadStageInitialized = false;
			SaveAPI.AlreadyRanOnLoadStagePostInitialization = false;
			SaveAPI.OnSetCurrentSaveSlot();
		}

		[HarmonyPrefix]
		[HarmonyPatch("SaveSaveSlot")]
		private static void SaveSaveSlot_Prefix(SaveSlotHandler __instance, int saveSlotId)
		{
			if (saveSlotId <= -1)
			{
				return;
			}
			string saveSlotFileName = __instance.GetSaveSlotFileName(saveSlotId);
			if (!string.IsNullOrEmpty(saveSlotFileName))
			{
				int filenameID = SaveAPI.GetFilenameID(saveSlotFileName);
				SaveAPI.SaveAllCustomData(filenameID);
				if (CommonAPISettings.Debug)
				{
					CommonAPIPlugin.Log.LogDebug((object)$"Saving {saveSlotFileName} in slot {saveSlotId}");
				}
				SaveAPI.OnSaveGame?.Invoke(saveSlotId, saveSlotFileName, filenameID);
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch("DeleteSaveSlotData")]
		private static void DeleteSaveSlotData_Prefix(SaveSlotHandler __instance, int slotId)
		{
			if (slotId <= -1)
			{
				return;
			}
			string saveSlotFileName = __instance.GetSaveSlotFileName(slotId);
			if (!string.IsNullOrEmpty(saveSlotFileName))
			{
				int filenameID = SaveAPI.GetFilenameID(saveSlotFileName);
				SaveAPI.DeleteAllCustomData(filenameID);
				if (CommonAPISettings.Debug)
				{
					CommonAPIPlugin.Log.LogDebug((object)$"Deleting save {saveSlotFileName} in slot {slotId}");
				}
				SaveAPI.OnDeleteGame?.Invoke(slotId, saveSlotFileName, filenameID);
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch("AddNewSaveSlot")]
		private static void AddNewSaveSlot_Prefix(SaveSlotHandler __instance, int saveSlotId)
		{
			string text = __instance.GenerateNewSaveSlotFileName(saveSlotId);
			int filenameID = SaveAPI.GetFilenameID(text);
			SaveAPI.MakeNewForAllCustomData(filenameID);
			if (CommonAPISettings.Debug)
			{
				CommonAPIPlugin.Log.LogDebug((object)$"Creating save {text} in slot {saveSlotId}");
			}
			SaveAPI.OnNewGame?.Invoke(saveSlotId, text, filenameID);
		}
	}
	[HarmonyPatch(typeof(SequenceHandler))]
	internal class SequenceHandlerPatch
	{
		[HarmonyPrefix]
		[HarmonyPatch("UpdateSequenceHandler")]
		private static bool UpdateSequenceHandler_Prefix()
		{
			if ((Object)(object)CustomSequenceHandler.instance == (Object)null)
			{
				return true;
			}
			if (CustomSequenceHandler.instance.isBusy)
			{
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(StageManager))]
	internal static class StageManagerPatch
	{
		[HarmonyPrefix]
		[HarmonyPatch("SetupWorldHandler")]
		private static void SetupWorldHandler_Prefix(Stage newStage, Stage prevStage)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			StageAPI.OnStagePreInitialization?.Invoke(newStage, prevStage);
		}
	}
	[HarmonyPatch(typeof(Type))]
	internal class TypePatch
	{
		private const string ReptilePhoneNamespace = "Reptile.Phone.";

		[HarmonyPostfix]
		[HarmonyPatch("GetType", new Type[] { typeof(string) })]
		private static void GetType_Postfix(string typeName, ref Type __result)
		{
			if (typeName.StartsWith("Reptile.Phone."))
			{
				string key = typeName.Substring("Reptile.Phone.".Length);
				if (PhoneAPI.PhoneAppByTypeName.TryGetValue(key, out var value))
				{
					__result = value.AppType;
				}
			}
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}