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 = "")] [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+a478a909a0a530f241fc8fb7e32d8d7030b52b18")] [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 CachedShaders = new Dictionary(); private static readonly Dictionary CachedMaterials = new Dictionary(); public static GraffitiArtInfo GetGraffitiArtInfo() { return Core.Instance.Assets.LoadAssetFromBundle("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("common_assets", "ToonWater_Pyramid"); CacheMaterial(materialName, val2); return val2; } case MaterialNames.OasisWater: { Material val = assets.LoadAssetFromBundle("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("common_assets", "glass").shader; CacheShader(shaderName, shader5); return shader5; } case ShaderNames.AmbientCharacter: { Shader shader4 = assets.LoadAssetFromBundle("common_assets", "shell").shader; CacheShader(shaderName, shader4); return shader4; } case ShaderNames.AmbientEnvironment: { Shader shader3 = assets.LoadAssetFromBundle("common_assets", "SkateboardScrewPoleMat").shader; CacheShader(shaderName, shader3); return shader3; } case ShaderNames.AmbientEnvironmentCutout: { Shader shader2 = assets.LoadAssetFromBundle("common_assets", "Prelude_PropsAtlasMat").shader; CacheShader(shaderName, shader2); return shader2; } case ShaderNames.AmbientEnvironmentTransparent: { Shader shader = assets.LoadAssetFromBundle("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(); 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(); if (!Object.op_Implicit((Object)(object)val)) { val = ((Component)other).GetComponentInParent(); } 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(); } public static CustomPlayerComponent Attach(Player player) { CustomPlayerComponent customPlayerComponent = ((Component)player).gameObject.AddComponent(); customPlayerComponent._player = player; customPlayerComponent.Init(); return customPlayerComponent; } private void Init() { if (!((Object)(object)_player.ui == (Object)null)) { CustomContextIcon = Object.Instantiate(_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)); string text = _path + ".tmp"; using (FileStream fileStream = new FileStream(text, FileMode.Create, FileAccess.Write, FileShare.None)) { fileStream.Write(_data, 0, _data.Length); fileStream.Flush(flushToDisk: true); } if (File.Exists(_path)) { File.Replace(text, _path, null); } else { File.Move(text, _path); } } } 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; } [CompilerGenerated] private sealed class <>c__DisplayClass37_0 { public Core coreInstance; internal bool b__0() { return coreInstance.IsCorePaused; } } [CompilerGenerated] private sealed class d__45 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public CustomSequenceHandler <>4__this; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__45(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Expected O, but got Unknown //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Expected O, but got Unknown //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Expected O, but got Unknown int num = <>1__state; CustomSequenceHandler CS$<>8__locals0 = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; CS$<>8__locals0.player.sequenceState = (SequenceState)0; if (CS$<>8__locals0.player.inGraffitiGame) { <>2__current = (object)new WaitUntil((Func)(() => !CS$<>8__locals0.player.inGraffitiGame)); <>1__state = 1; return true; } goto IL_0071; case 1: <>1__state = -1; goto IL_0071; case 2: <>1__state = -1; goto IL_00d5; case 3: <>1__state = -1; CS$<>8__locals0.SetFullyInSequence(); <>2__current = (object)new WaitForSeconds(CS$<>8__locals0.shutDuration); <>1__state = 4; return true; case 4: { <>1__state = -1; ((AMenuController)CS$<>8__locals0).uIManager.effects.FadeOpen(CS$<>8__locals0.fadeDuration); ((AMenuController)CS$<>8__locals0).uIManager.effects.ShowVerticalBars(); return false; } IL_00d5: CS$<>8__locals0.player.userInputEnabled = false; CS$<>8__locals0.player.phone.AllowPhone(false, false, false); CS$<>8__locals0.SetPartiallyInSequence(); <>2__current = TweenExtensions.WaitForCompletion(((AMenuController)CS$<>8__locals0).uIManager.effects.FadeToBlack(CS$<>8__locals0.fadeDuration)); <>1__state = 3; return true; IL_0071: if (CS$<>8__locals0.player.ability == CS$<>8__locals0.player.characterSelectAbility) { <>2__current = (object)new WaitUntil((Func)(() => CS$<>8__locals0.player.ability != CS$<>8__locals0.player.characterSelectAbility)); <>1__state = 2; return true; } if (CS$<>8__locals0.player.ability == CS$<>8__locals0.player.danceAbility) { CS$<>8__locals0.player.StopCurrentAbility(); } goto IL_00d5; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class d__33 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public float delay; public CustomSequenceHandler <>4__this; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__33(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected O, but got Unknown int num = <>1__state; CustomSequenceHandler customSequenceHandler = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(delay); <>1__state = 1; return true; case 1: <>1__state = -1; <>2__current = customSequenceHandler.ExitSequenceRoutine(); <>1__state = 2; return true; case 2: <>1__state = -1; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class d__37 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public CustomSequenceHandler <>4__this; private <>c__DisplayClass37_0 <>8__1; private EffectsUI 5__2; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__37(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>8__1 = null; 5__2 = null; <>1__state = -2; } private bool MoveNext() { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Invalid comparison between Unknown and I4 //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Expected O, but got Unknown //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Expected O, but got Unknown //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Expected O, but got Unknown //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) int num = <>1__state; CustomSequenceHandler customSequenceHandler = <>4__this; switch (num) { default: return false; case 0: { <>1__state = -1; <>8__1 = new <>c__DisplayClass37_0(); if ((int)customSequenceHandler.player.sequenceState == 2) { return false; } customSequenceHandler.player.sequenceState = (SequenceState)2; <>8__1.coreInstance = Core.Instance; 5__2 = ((AMenuController)customSequenceHandler).uIManager.effects; customSequenceHandler.skipTextActiveState = (SkipState)4; 5__2.FadeSkipOut(customSequenceHandler.skipFadeDuration, (UpdateType)3); _ = Time.deltaTime; _ = customSequenceHandler.fadeDuration; Tween val = 5__2.FadeToBlack(customSequenceHandler.fadeDuration); <>2__current = TweenExtensions.WaitForCompletion(val); <>1__state = 1; return true; } case 1: <>1__state = -1; <>2__current = (object)new WaitForSeconds(customSequenceHandler.shutDuration); <>1__state = 2; return true; case 2: <>1__state = -1; customSequenceHandler.SetExitSequence(); <>2__current = (object)new WaitForSeconds(customSequenceHandler.shutDuration); <>1__state = 3; return true; case 3: <>1__state = -1; <>2__current = (object)new WaitWhile((Func)(() => <>8__1.coreInstance.IsCorePaused)); <>1__state = 4; return true; case 4: <>1__state = -1; if (!customSequenceHandler.IsInSequence()) { 5__2.FadeOpen(customSequenceHandler.fadeDuration); customSequenceHandler.isBusy = false; 5__2.HideVerticalBars(); } return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class d__27 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public float delay; public CustomSequenceHandler <>4__this; public CustomDialogue dialogue; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__27(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown int num = <>1__state; CustomSequenceHandler customSequenceHandler = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(delay); <>1__state = 1; return true; case 1: <>1__state = -1; customSequenceHandler.StartDialogue(dialogue); return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } 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 queuedSequenceActions = new List(); 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; } [IteratorStateMachine(typeof(d__27))] private IEnumerator StartDialogueCoroutine(CustomDialogue dialogue, float delay = 0.9f) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__27(0) { <>4__this = this, dialogue = dialogue, delay = delay }; } 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().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))); } [IteratorStateMachine(typeof(d__33))] private IEnumerator ExitCurrentSequenceDelayedCoroutine(float delay = 0.9f) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__33(0) { <>4__this = this, delay = delay }; } 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()); } } [IteratorStateMachine(typeof(d__37))] private IEnumerator ExitSequenceRoutine() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__37(0) { <>4__this = this }; } 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()); } } [IteratorStateMachine(typeof(d__45))] private IEnumerator EnterSequenceRoutine() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__45(0) { <>4__this = this }; } 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 _transactionQueue = new Queue(); 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 OnTest; public Func OnGetLookAtPos; public Action 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 _customSaveDatas = new List(); 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()).transform.Find("Overlay")).transform.Find("Icons").Find("HeaderLabel")).GetComponent()).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(); ((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().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(); } 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(((Component)((App)this).MyPhone.GetAppInstance()).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()); TextMeshProUGUI component = ((Component)val).GetComponent(); ((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(((Component)((App)this).MyPhone.GetAppInstance()).transform.Find("Overlay")); Transform obj2 = ((Component)obj).transform.Find("Icons"); ((Component)obj2.Find("GraffitiIcon")).GetComponent().sprite = icon; Transform obj3 = obj2.Find("HeaderLabel"); Object.Destroy((Object)(object)((Component)obj3).GetComponent()); TextMeshProUGUI component = ((Component)obj3).GetComponent(); ((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 Apps; internal static Dictionary PhoneAppByTypeName; private static bool Initialized; internal static void Initialize() { if (!Initialized) { Initialized = true; Apps = new List(); PhoneAppByTypeName = new Dictionary(); } } 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(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 { [CompilerGenerated] private sealed class d__20 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public PhoneScrollView <>4__this; private RectTransform 5__2; private float 5__3; private float 5__4; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__20(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { 5__2 = null; <>1__state = -2; } private bool MoveNext() { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0074: 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) int num = <>1__state; PhoneScrollView phoneScrollView = <>4__this; switch (num) { default: return false; case 0: { <>1__state = -1; 5__2 = ComponentExtensions.RectTransform((Component)(object)phoneScrollView); 5__3 = 0f - phoneScrollView.Height + phoneScrollView.CurrentScroll; float y = 5__2.anchoredPosition.y; float num2 = 5__3 - y; 5__4 = num2 / phoneScrollView.AnimationSpeed; break; } case 1: <>1__state = -1; break; } if (5__2.anchoredPosition.y != 5__3) { float y = 5__2.anchoredPosition.y; if (5__3 > y) { y += Core.dt * 5__4; if (y > 5__3) { y = 5__3; } } else if (5__3 < y) { y += Core.dt * 5__4; if (y < 5__3) { y = 5__3; } } 5__2.anchoredPosition = new Vector2(0f, y); <>2__current = null; <>1__state = 1; return true; } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public const float DefaultLength = 1600f; public float AnimationSpeed = 0.1f; public List Buttons = new List(); 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.App = app; RectTransform obj = val.AddComponent(); 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); } [IteratorStateMachine(typeof(d__20))] private IEnumerator AnimateScrollCoroutine() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__20(0) { <>4__this = this }; } 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(); 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(); simplePhoneButton.ButtonImage = buttonImage; GameObjectExtensions.RectTransform(val3).sizeDelta = new Vector2(1060f, 150f); simplePhoneButton.SetGraphics(); RectTransform obj = val.AddComponent(); 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(); ((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().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>(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>(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>(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 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 apps) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) HomeScreenApp val = ScriptableObject.CreateInstance(); 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()); 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) { } } }