Decompiled source of Score Attack Local Training v2.7.1
plugins/Score_Attack_Local_Training/ScoreAttackPlugin.dll
Decompiled 3 weeks ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.IO.Compression; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Threading.Tasks; using BepInEx; using BepInEx.Bootstrap; using CommonAPI; using CommonAPI.Phone; using HarmonyLib; using Microsoft.CodeAnalysis; using Reptile; using Reptile.Phone; using ScoreAttack; using ScoreAttack.Patches; using ScoreAttackGhostSystem; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.Networking; using UnityEngine.Playables; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETFramework,Version=v4.6", FrameworkDisplayName = ".NET Framework 4.6")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")] [assembly: AssemblyCompany("ScoreAttackPlugin")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyDescription("My first plugin")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("ScoreAttackPlugin")] [assembly: AssemblyTitle("ScoreAttackPlugin")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace ScoreAttackGhostSystem { public class CrewBoomSupport { public static Guid GetGUID(int character) { Type typeByName = GetTypeByName("CrewBoomAPI.CrewBoomAPIDatabase"); Dictionary<int, Guid> dictionary = typeByName.GetField("_userCharacters", BindingFlags.Static | BindingFlags.NonPublic).GetValue(null) as Dictionary<int, Guid>; return dictionary[character]; } public static int GetCharacter(Guid guid) { Type typeByName = GetTypeByName("CrewBoomAPI.CrewBoomAPIDatabase"); Dictionary<int, Guid> source = typeByName.GetField("_userCharacters", BindingFlags.Static | BindingFlags.NonPublic).GetValue(null) as Dictionary<int, Guid>; Dictionary<Guid, int> dictionary = source.ToDictionary((KeyValuePair<int, Guid> x) => x.Value, (KeyValuePair<int, Guid> x) => x.Key); return dictionary[guid]; } public static Type GetTypeByName(string name) { foreach (Assembly item in AppDomain.CurrentDomain.GetAssemblies().Reverse()) { Type type = item.GetType(name); if (type != null) { return type; } } return null; } } public class Ghost { private Player _player; private float _tickDelta; private List<GhostFrame> _frames; public int Character; public Guid CharacterGUID; public int Outfit; public bool HasOngoingScoreDataCached; public float TickDelta => _tickDelta; public Player Player => _player; public int FrameCount => _frames.Count; public float Length => (float)(FrameCount - 1) * _tickDelta; public List<GhostFrame> Frames => _frames; public float Score { get; set; } public float OngoingScore { get; set; } public bool HasOngoingScoreData => Frames.Any((GhostFrame f) => f.OngoingScore > 0f); public Ghost(float tickDelta) { _tickDelta = tickDelta; _frames = new List<GhostFrame>(); Character = -1; Outfit = -1; Score = 0f; OngoingScore = 0f; HasOngoingScoreDataCached = false; base..ctor(); } public void Init() { _player = WorldHandler.instance.GetCurrentPlayer(); } public int GetFrameForTime(float time) { return Mathf.FloorToInt(time / _tickDelta); } public void CacheOngoingScoreData() { HasOngoingScoreDataCached = Frames.Any((GhostFrame f) => f.OngoingScore > 0f); } } public class GhostFrame { public class GhostFrameAnimation { public int ID; public float Time; public bool ForceOverwrite = false; public bool Instant = false; public float AtTime = -1f; } public class GhostFrameVisual { public Vector3 Position; public Quaternion Rotation; public BoostpackEffectMode boostpackEffectMode = (BoostpackEffectMode)0; public FrictionEffectMode frictionEffectMode = (FrictionEffectMode)0; public int dustEmission = 0; public float dustSize = 1f; public int spraypaintEmission = 0; public int ringEmission = 0; } public class GhostFrameEffects { public int ringParticles = -1; public int spraypaintParticles = -1; public bool DoJumpEffects = false; public bool DoHighJumpEffects = false; public Vector3 JumpEffects = Vector3.zero; public Vector3 HighJumpEffects = Vector3.zero; } public class GhostFrameSFX { public AudioClipID AudioClipID = (AudioClipID)(-1); public SfxCollectionID CollectionID = (SfxCollectionID)(-1); public float RandomPitchVariance = 0f; public bool Voice = false; } public int FrameIndex; public bool Valid = false; private Ghost _replay; public Vector3 PlayerPosition; public Quaternion PlayerRotation; public Vector3 Velocity; public float BaseScore; public float ScoreMultiplier; public float OngoingScore; public PhoneState PhoneState; public SpraycanState SpraycanState; public MoveStyle moveStyle; public MoveStyle equippedMoveStyle; public bool UsingEquippedMoveStyle; public GhostFrameAnimation Animation; public GhostFrameVisual Visual; public GhostFrameEffects Effects; public List<GhostFrameSFX> SFX; public GhostFrame(Ghost replay) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) _replay = replay; PhoneState = (PhoneState)0; SpraycanState = (SpraycanState)0; Animation = new GhostFrameAnimation(); Visual = new GhostFrameVisual(); Effects = new GhostFrameEffects(); SFX = new List<GhostFrameSFX>(); base..ctor(); } } public class GhostManager : MonoBehaviour { private static GhostManager _instance; private GhostState _currentGhostState = null; private GhostRecorder _ghostRecorder = new GhostRecorder(); private GhostPlayer _ghostPlayer = new GhostPlayer(); public static GhostManager Instance => _instance; public GhostState CurrentGhostState => _currentGhostState; public GhostRecorder GhostRecorder => _ghostRecorder; public GhostPlayer GhostPlayer => _ghostPlayer; public static GhostManager Create() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown GameObject val = new GameObject("Ghost Manager"); return val.AddComponent<GhostManager>(); } private void Awake() { _instance = this; } public void OnFixedUpdate() { if (!Core.instance.IsCorePaused || StartGraffitiModePatch.inGraffitiMode) { _currentGhostState?.OnFixedUpdate(); } } private void OnDestroy() { _instance = null; } public GhostRecorder GetGhostRecorder() { return _ghostRecorder; } public GhostState GetGhostState() { return _currentGhostState; } public void RemoveCurrentGhostState() { _currentGhostState = null; } public void AddCurrentGhostState() { _currentGhostState = GetGhostRecorder(); } } public class GhostPlayer : GhostState { public Ghost Replay; public Action OnFrameSkip; private bool _paused = false; private float _playbackSpeed = 1f; private float _currentTime = 0f; public static Player ghostPlayerCharacter; private bool developmentMode = false; private bool _isSpraying = false; public float BaseScore; public float ScoreMultiplier; public float LastAppliedOngoingScore; private SpraycanState _lastAppliedSpraycanState = (SpraycanState)0; public float CurrentTime => _currentTime; public bool ReplayEnded { get; private set; } = false; public bool Active { get; private set; } = false; public override void Start() { _currentTime = 0f; _paused = false; _playbackSpeed = 1f; ReplayEnded = false; ghostPlayerCharacter = SetupAIPlayer(); Active = true; float tickDelta = Replay.TickDelta; float num = _currentTime % tickDelta; if (num != 0f) { float num2 = tickDelta - num; _currentTime += num2; } ScoreAttackPlugin.Instance.ResetCurrentTime(); LastAppliedOngoingScore = 0f; } private Player SetupAIPlayer() { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Expected I4, but got Unknown //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) WorldHandler instance = WorldHandler.instance; PlayerSpawner defaultPlayerSpawnPoint = instance.GetDefaultPlayerSpawnPoint(); Player currentPlayer = WorldHandler.instance.GetCurrentPlayer(); int outfit = Core.Instance.SaveManager.CurrentSaveSlot.GetCharacterProgress(currentPlayer.character).outfit; if (GhostSaveData.Instance.GhostModel != 0) { switch (GhostSaveData.Instance.GhostModel) { case GhostModel.DJCyber: Replay.Character = 9; break; case GhostModel.Faux: Replay.Character = 12; break; } Replay.Outfit = 0; } else { if (Replay.Character > 26) { _ = Replay.CharacterGUID; if (Replay.CharacterGUID != Guid.Empty) { try { Replay.Character = CrewBoomSupport.GetCharacter(Replay.CharacterGUID); } catch (Exception) { Replay.Character = -1; } } } if (Replay.Character == -1) { Replay.Character = (int)currentPlayer.character; } if (Replay.Outfit == -1) { Replay.Outfit = outfit; } } MoveStyle moveStyle = Replay.Frames[0].moveStyle; Player val = instance.SetupAIPlayerAt(((Component)defaultPlayerSpawnPoint).transform, (Characters)Replay.Character, (PlayerType)3, Replay.Outfit, moveStyle, (Crew)1); val.motor.gravity = 0f; val.motor.SetKinematic(true); ((Behaviour)val.motor).enabled = false; val.moveStyleEquipped = Replay.Frames[0].equippedMoveStyle; val.DropCombo(); val.StopCurrentAbility(); if (GhostSaveData.Instance.GhostEffect == GhostEffect.Transparent) { MakePlayerGhostLOD(val, 0.3f); } if (AppGhostSettings.SoundMode != GhostSoundMode.Doppler) { AudioSource[] componentsInChildren = ((Component)val).GetComponentsInChildren<AudioSource>(true); AudioSource[] array = componentsInChildren; foreach (AudioSource val2 in array) { val2.dopplerLevel = 0f; } } else { AudioSource[] componentsInChildren2 = ((Component)val).GetComponentsInChildren<AudioSource>(true); AudioSource[] array2 = componentsInChildren2; foreach (AudioSource val3 in array2) { val3.dopplerLevel = 1f; } } if (AppGhostSettings.SoundMode == GhostSoundMode.Off) { AudioSource[] componentsInChildren3 = ((Component)val).GetComponentsInChildren<AudioSource>(true); AudioSource[] array3 = componentsInChildren3; foreach (AudioSource val4 in array3) { val4.mute = true; } } else { AudioSource[] componentsInChildren4 = ((Component)val).GetComponentsInChildren<AudioSource>(true); AudioSource[] array4 = componentsInChildren4; foreach (AudioSource val5 in array4) { val5.mute = false; } } return val; } public void SkipTo(float time) { if (time >= Replay.Length) { time = Replay.Length; } int num = Replay.GetFrameForTime(time); if (num >= Replay.FrameCount) { num = Replay.FrameCount - 1; } if (num < 0) { num = 0; } ApplyFrameToWorld(Replay.Frames[num], skip: true); _currentTime = (float)num * Replay.TickDelta; } public void EndReplay() { ReplayEnded = true; if ((Object)(object)ghostPlayerCharacter != (Object)null) { if (GhostSaveData.Instance.GhostEffect == GhostEffect.Transparent) { MakePlayerGhostLOD(ghostPlayerCharacter, 0.15f); } ghostPlayerCharacter.anim.speed = 0f; } } public void ApplyFrameToWorld(GhostFrame frame, bool skip) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) ApplyFrameToWorld(frame, skip, frame.PlayerPosition, frame.PlayerRotation, frame.Visual.Position, frame.Visual.Rotation); } public void ApplyFrameToWorld(GhostFrame frame, bool skip, Vector3 interpPosition, Quaternion interpRotation, Vector3 interpPositionVisual, Quaternion interpRotationVisual) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Invalid comparison between Unknown and I4 //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_0225: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Invalid comparison between Unknown and I4 //IL_02d3: Unknown result type (might be due to invalid IL or missing references) //IL_02f8: Unknown result type (might be due to invalid IL or missing references) //IL_0335: Unknown result type (might be due to invalid IL or missing references) //IL_033b: Invalid comparison between Unknown and I4 //IL_0387: Unknown result type (might be due to invalid IL or missing references) //IL_038d: Invalid comparison between Unknown and I4 //IL_0365: Unknown result type (might be due to invalid IL or missing references) //IL_036c: Unknown result type (might be due to invalid IL or missing references) //IL_03fa: Unknown result type (might be due to invalid IL or missing references) //IL_0401: Unknown result type (might be due to invalid IL or missing references) //IL_039b: Unknown result type (might be due to invalid IL or missing references) //IL_03a5: Invalid comparison between Unknown and I4 //IL_03a9: Unknown result type (might be due to invalid IL or missing references) //IL_03b0: Invalid comparison between Unknown and I4 //IL_03cf: Unknown result type (might be due to invalid IL or missing references) //IL_03d6: Unknown result type (might be due to invalid IL or missing references) if (!frame.Valid) { return; } Player val = ghostPlayerCharacter; val.moveStyle = frame.moveStyle; val.moveStyleEquipped = frame.equippedMoveStyle; val.InitMovement(frame.moveStyle); val.SetMoveStyle(frame.moveStyle, true, false, (GameObject)null); val.SwitchToEquippedMovestyle(frame.UsingEquippedMoveStyle, false, true, false); if (frame.OngoingScore != 0f) { LastAppliedOngoingScore = frame.OngoingScore; } if (skip) { val.SwitchToEquippedMovestyle(frame.UsingEquippedMoveStyle, false, true, false); OnFrameSkip?.Invoke(); } ApplyInterpolationToWorld(skip, interpPosition, interpRotation, interpPositionVisual, interpRotationVisual); val.SetVelocity(frame.Velocity); val.SetBoostpackAndFrictionEffects(frame.Visual.boostpackEffectMode, frame.Visual.frictionEffectMode); val.SetDustEmission(frame.Visual.dustEmission); val.SetDustSize(frame.Visual.dustSize); val.SetSpraypaintEmission(frame.Visual.spraypaintEmission); val.SetRingEmission(frame.Visual.ringEmission); if (frame.SpraycanState != _lastAppliedSpraycanState) { val.SetSpraycanState(frame.SpraycanState); _lastAppliedSpraycanState = frame.SpraycanState; if ((int)frame.SpraycanState == 3) { val.anim.Play(val.canSprayHash, 1, 0f); } } else { val.spraycanState = frame.SpraycanState; } if (frame.SpraycanState != _lastAppliedSpraycanState) { Debug.Log((object)$"[ScoreAttack] Ghost SpraycanState changed to: {frame.SpraycanState}"); _lastAppliedSpraycanState = frame.SpraycanState; } else if (_isSpraying) { Debug.Log((object)"[ScoreAttack] Replaying spray animation"); } bool flag = frame.Animation.AtTime != -1f; float num = ((!flag) ? frame.Animation.Time : frame.Animation.AtTime); if ((int)frame.SpraycanState == 0 || flag) { val.PlayAnim(frame.Animation.ID, frame.Animation.ForceOverwrite, frame.Animation.Instant, num); } if (frame.Effects.ringParticles > 0) { val.ringParticles.Emit(frame.Effects.ringParticles); } if (frame.Effects.spraypaintParticles > 0) { val.spraypaintParticles.Emit(frame.Effects.spraypaintParticles); } if (frame.Effects.DoJumpEffects) { val.DoJumpEffects(frame.Effects.JumpEffects); } if (frame.Effects.DoHighJumpEffects) { val.DoHighJumpEffects(frame.Effects.HighJumpEffects); } if (AppGhostSettings.SoundMode != 0) { foreach (GhostFrame.GhostFrameSFX item in frame.SFX) { if ((int)item.AudioClipID == -1) { continue; } if (item.Voice) { val.audioManager.PlayVoice(ref val.currentVoicePriority, val.character, item.AudioClipID, val.playerGameplayVoicesAudioSource, (VoicePriority)0); } else if ((int)item.CollectionID != -1) { if (((int)item.AudioClipID != 130 && (int)item.AudioClipID != 114) || frame.Effects.DoHighJumpEffects) { val.audioManager.PlaySfxGameplay(item.CollectionID, item.AudioClipID, val.playerOneShotAudioSource, item.RandomPitchVariance); } } else { val.audioManager.PlaySfxGameplay(frame.moveStyle, item.AudioClipID, val.playerOneShotAudioSource, item.RandomPitchVariance); } } } Collider[] componentsInChildren = ((Component)val).GetComponentsInChildren<Collider>(true); foreach (Collider val2 in componentsInChildren) { if (!((Object)(object)val2 == (Object)null)) { val2.enabled = false; } } } public void ApplyInterpolationToWorld(bool skip, Vector3 interpPosition, Quaternion interpRotation, Vector3 interpPositionVisual, Quaternion interpRotationVisual) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) Player val = ghostPlayerCharacter; if (skip) { WorldHandler.instance.PlacePlayerAt(val, interpPosition, interpRotation, true); } else { ((Component)val).transform.position = interpPosition; ((Component)val).transform.rotation = interpRotation; } ((Component)val.characterVisual).transform.position = interpPositionVisual; ((Component)val.characterVisual).transform.rotation = interpRotationVisual; } public override void End() { Active = false; ((Component)Core.instance.UIManager).gameObject.SetActive(true); Time.timeScale = 1f; if (!((Object)(object)ghostPlayerCharacter != (Object)null)) { return; } WorldHandler instance = WorldHandler.instance; if (instance != null) { SceneObjectsRegister sceneObjectsRegister = instance.SceneObjectsRegister; if (sceneObjectsRegister != null && sceneObjectsRegister.players != null) { instance.SceneObjectsRegister.players.Remove(ghostPlayerCharacter); } } Object.Destroy((Object)(object)((Component)ghostPlayerCharacter).gameObject); } private void RefreshTimeScale() { if (_paused) { Time.timeScale = 0f; } else { Time.timeScale = _playbackSpeed; } } public override void OnUpdate() { UpdatePlaybackInput(); RefreshTimeScale(); } private void UpdatePlaybackInput() { //IL_0032: Unknown result type (might be due to invalid IL or missing references) if (developmentMode) { if (Input.GetKeyDown((KeyCode)32)) { _paused = !_paused; } _playbackSpeed += Input.mouseScrollDelta.y * 0.05f; if (_playbackSpeed <= 0f) { _playbackSpeed = 0f; } if (Input.GetKeyDown((KeyCode)114)) { _playbackSpeed = 1f; _paused = false; } if (Input.GetKeyDown((KeyCode)8)) { _currentTime = 0f; } if (Input.GetKeyDown((KeyCode)104)) { ((Component)Core.instance.UIManager).gameObject.SetActive(!((Component)Core.instance.UIManager).gameObject.activeSelf); } if (Input.GetKeyDown((KeyCode)48)) { SkipTo(0f); } if (Input.GetKeyDown((KeyCode)49)) { SkipTo(Replay.Length * 0.25f); } if (Input.GetKeyDown((KeyCode)50)) { SkipTo(Replay.Length * 0.5f); } if (Input.GetKeyDown((KeyCode)51)) { SkipTo(Replay.Length * 0.75f); } if (Input.GetKeyDown((KeyCode)52)) { SkipTo(Replay.Length); } } } private static void MakePlayerGhostLOD(Player player, float alpha) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_0022: Unknown result type (might be due to invalid IL or missing references) Material val = new Material(Shader.Find("Sprites/Default")); val.color = new Color(1f, 1f, 1f, alpha); val.SetInt("_ZTest", 8); val.SetInt("_ZWrite", 0); val.renderQueue = 4000; PlayerVisualEffects vFX = player.characterVisual.VFX; PlayerMoveStyleProps moveStyleProps = player.characterVisual.moveStyleProps; GameObject[] source = (GameObject[])(object)new GameObject[30] { vFX.circleBoostEffect, vFX.jumpEffect, vFX.frictionEffect, vFX.frictionBlueEffect, vFX.boostpackEffect, vFX.boostpackBlueEffect, vFX.boostpackTrail, vFX.spraycan, vFX.spraycanCap, vFX.spraypaint, vFX.graffitiSlash, vFX.graffitiFinishEffect, vFX.graffitiFinishLargeEffect, vFX.phone, vFX.dust, vFX.ring, vFX.hitEffect, vFX.getHitEffect, vFX.highJumpEffect, moveStyleProps.bmxFrame, moveStyleProps.bmxHandlebars, moveStyleProps.bmxWheelF, moveStyleProps.bmxWheelR, moveStyleProps.bmxGear, moveStyleProps.bmxPedalL, moveStyleProps.bmxPedalR, moveStyleProps.skateboard, moveStyleProps.skateR, moveStyleProps.skateL, moveStyleProps.specialSkateBoard }; Renderer[] componentsInChildren = ((Component)player).GetComponentsInChildren<Renderer>(true); Renderer[] array = componentsInChildren; foreach (Renderer val2 in array) { if ((Object)(object)val2 != (Object)null) { if (val2 is TrailRenderer && !source.Contains(((Component)val2).gameObject)) { ((Component)val2).gameObject.SetActive(false); } Material[] array2 = (Material[])(object)new Material[val2.materials.Length]; for (int j = 0; j < array2.Length; j++) { array2[j] = val; } val2.materials = array2; } } } } public class GhostRecorder : GhostState { public static GhostRecorder Instance; public InputBuffer CurrentInput; private Ghost _currentReplay; public bool Recording { get; private set; } = false; public Ghost Replay => _currentReplay; public GhostFrame LastFrame => (_currentReplay.Frames.Count > 1) ? _currentReplay.Frames[_currentReplay.Frames.Count - 1] : null; public override void Start() { _currentReplay = new Ghost(ScoreAttackPlugin.ghostTickInterval); _currentReplay.Init(); Instance = this; Recording = true; } public override void End() { Instance = null; Recording = false; } public void OnPlayerInput(Player player) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)WorldHandler.instance.GetCurrentPlayer() != (Object)(object)player)) { CurrentInput = player.inputBuffer; } } public override void OnFixedUpdate() { if (Recording) { if ((Object)(object)ScoreAttackManager.Encounter == (Object)null || !ScoreAttackEncounter.IsScoreAttackActive()) { Debug.Log((object)"[Score Attack] Stopping recording: Score Attack is no longer active."); End(); } else if ((Object)(object)_currentReplay.Player == (Object)null) { Debug.Log((object)"[GhostRecorder] Stopping recording: Player is no longer valid."); End(); } else { RecordCurrentFrame(); } } } private void RecordCurrentFrame() { //IL_029f: Unknown result type (might be due to invalid IL or missing references) //IL_02a4: Unknown result type (might be due to invalid IL or missing references) //IL_02b5: Unknown result type (might be due to invalid IL or missing references) //IL_02ba: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Expected I4, but got Unknown //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Invalid comparison between Unknown and I4 //IL_0215: Unknown result type (might be due to invalid IL or missing references) //IL_023b: Unknown result type (might be due to invalid IL or missing references) //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_0244: Unknown result type (might be due to invalid IL or missing references) //IL_0249: Unknown result type (might be due to invalid IL or missing references) //IL_026e: Unknown result type (might be due to invalid IL or missing references) //IL_0273: Unknown result type (might be due to invalid IL or missing references) //IL_0277: Unknown result type (might be due to invalid IL or missing references) //IL_027c: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Expected I4, but got Unknown //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) GhostFrame ghostFrame = new GhostFrame(_currentReplay) { FrameIndex = _currentReplay.Frames.Count }; _currentReplay.Frames.Add(ghostFrame); if ((Object)(object)_currentReplay.Player == (Object)null) { return; } Player player = _currentReplay.Player; ghostFrame.Valid = true; if (_currentReplay.Character == -1) { _currentReplay.Character = (int)player.character; if ((int)player.character > 26) { _currentReplay.CharacterGUID = CrewBoomSupport.GetGUID((int)player.character); } } if (_currentReplay.Outfit == -1) { _currentReplay.Outfit = Core.Instance.SaveManager.CurrentSaveSlot.GetCharacterProgress(player.character).outfit; } ghostFrame.PlayerPosition = ((Component)player).transform.position; ghostFrame.PlayerRotation = ((Component)player).transform.rotation; ghostFrame.Velocity = player.GetVelocity(); ghostFrame.BaseScore = player.baseScore; ghostFrame.ScoreMultiplier = player.scoreMultiplier; ghostFrame.SpraycanState = player.spraycanState; ghostFrame.moveStyle = player.moveStyle; ghostFrame.equippedMoveStyle = player.moveStyleEquipped; ghostFrame.UsingEquippedMoveStyle = player.usingEquippedMovestyle; ghostFrame.Animation.ID = player.curAnim; ghostFrame.Animation.Time = player.anim.playbackTime; ghostFrame.Visual.Position = player.characterVisual.tf.position; ghostFrame.Visual.Rotation = player.characterVisual.tf.rotation; EmissionModule emission; MinMaxCurve rateOverTime; try { GhostFrame.GhostFrameVisual visual = ghostFrame.Visual; emission = player.characterVisual.dustParticles.emission; rateOverTime = ((EmissionModule)(ref emission)).rateOverTime; visual.dustEmission = (int)((MinMaxCurve)(ref rateOverTime)).constant; } catch (Exception) { } try { ghostFrame.Visual.dustSize = player.characterVisual.VFX.dust.transform.localScale.x; } catch (Exception) { } try { GhostFrame.GhostFrameVisual visual2 = ghostFrame.Visual; emission = player.spraypaintParticles.emission; rateOverTime = ((EmissionModule)(ref emission)).rateOverTime; visual2.spraypaintEmission = (int)((MinMaxCurve)(ref rateOverTime)).constant; } catch (Exception) { } try { GhostFrame.GhostFrameVisual visual3 = ghostFrame.Visual; emission = player.ringParticles.emission; rateOverTime = ((EmissionModule)(ref emission)).rateOverTime; visual3.ringEmission = (int)((MinMaxCurve)(ref rateOverTime)).constant; } catch (Exception) { } ghostFrame.Visual.boostpackEffectMode = player.characterVisual.boostpackEffectMode; ghostFrame.Visual.frictionEffectMode = player.characterVisual.frictionEffectMode; } } public abstract class GhostState { public virtual void Start() { } public virtual void OnFixedUpdate() { } public virtual void End() { } public virtual void OnUpdate() { } } } namespace ScoreAttackGhostSystem.Patches { [HarmonyPatch] internal class GhostPatch { [HarmonyPatch(typeof(MoveAlongPoints))] public static class Hitbox_HitboxHitPlayer_Patch { [HarmonyPrefix] [HarmonyPatch("HitboxHitPlayer")] public static bool Prefix_HitboxHitPlayer(Player player) { return (Object)(object)player != (Object)(object)GhostPlayer.ghostPlayerCharacter; } } [HarmonyPatch(typeof(MoveAlongHandler))] public static class MoveAlongHandler_GetCurrentPlayer_Patch { [HarmonyPrefix] [HarmonyPatch("GetCurrentPlayer")] public static bool Prefix_GetCurrentPlayer(MoveAlongHandler __instance, ref Player __result) { if ((Object)(object)GhostPlayer.ghostPlayerCharacter != (Object)null && (Object)(object)WorldHandler.instance.GetCurrentPlayer() == (Object)(object)GhostPlayer.ghostPlayerCharacter) { __result = null; return false; } return true; } } [HarmonyPrefix] [HarmonyPatch(typeof(BreakableObject), "CheckSetPlayerFromHitbox")] private static bool CheckSetPlayerFromHitbox_Prefix(BreakableObject __instance, Collider newCollider) { if ((Object)(object)__instance.curCollider == (Object)(object)newCollider) { return false; } Player componentInParent = ((Component)((Component)newCollider).transform).GetComponentInParent<Player>(); if ((Object)(object)componentInParent == (Object)(object)GhostPlayer.ghostPlayerCharacter || componentInParent.isAI) { return false; } return true; } [HarmonyPostfix] [HarmonyPatch(typeof(ParticleSystem))] [HarmonyPatch("Emit", new Type[] { typeof(int) })] private static void SetFrameEmit(int count, ParticleSystem __instance) { WorldHandler instance = WorldHandler.instance; if ((Object)(object)((instance != null) ? instance.GetCurrentPlayer() : null) == (Object)null) { return; } WorldHandler instance2 = WorldHandler.instance; Player val = ((instance2 != null) ? instance2.GetCurrentPlayer() : null); if (GhostRecorder.Instance != null && GhostRecorder.Instance.Recording && GhostRecorder.Instance.LastFrame != null) { if ((Object)(object)__instance == (Object)(object)val.ringParticles) { GhostRecorder.Instance.LastFrame.Effects.ringParticles = count; } if ((Object)(object)__instance == (Object)(object)val.spraypaintParticles) { GhostRecorder.Instance.LastFrame.Effects.spraypaintParticles = count; } } } [HarmonyPostfix] [HarmonyPatch(typeof(AudioManager))] [HarmonyPatch("PlaySfxGameplay", new Type[] { typeof(SfxCollectionID), typeof(AudioClipID), typeof(AudioSource), typeof(float) })] private static void SetSFXGameplayAlt(SfxCollectionID collectionId, AudioClipID audioClipId, AudioSource audioSource, float randomPitchVariance) { //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) WorldHandler instance = WorldHandler.instance; if (!((Object)(object)((instance != null) ? instance.GetCurrentPlayer() : null) == (Object)null)) { WorldHandler instance2 = WorldHandler.instance; if (!((Object)(object)audioSource != (Object)(object)((instance2 != null) ? instance2.GetCurrentPlayer().playerOneShotAudioSource : null)) && GhostRecorder.Instance != null && GhostRecorder.Instance.Recording && GhostRecorder.Instance.LastFrame != null) { GhostRecorder.Instance.LastFrame.SFX.Add(new GhostFrame.GhostFrameSFX { CollectionID = collectionId, AudioClipID = audioClipId, RandomPitchVariance = randomPitchVariance }); } } } [HarmonyPostfix] [HarmonyPatch(typeof(AudioManager))] [HarmonyPatch("PlaySfxGameplay", new Type[] { typeof(MoveStyle), typeof(AudioClipID), typeof(AudioSource), typeof(float) })] private static void SetSFXGameplay(MoveStyle moveStyle, AudioClipID audioClipId, AudioSource audioSource, float randomPitchVariance) { //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) WorldHandler instance = WorldHandler.instance; if (!((Object)(object)((instance != null) ? instance.GetCurrentPlayer() : null) == (Object)null)) { WorldHandler instance2 = WorldHandler.instance; if (!((Object)(object)audioSource != (Object)(object)((instance2 != null) ? instance2.GetCurrentPlayer().playerOneShotAudioSource : null)) && GhostRecorder.Instance != null && GhostRecorder.Instance.Recording && GhostRecorder.Instance.LastFrame != null) { GhostRecorder.Instance.LastFrame.SFX.Add(new GhostFrame.GhostFrameSFX { AudioClipID = audioClipId, RandomPitchVariance = randomPitchVariance }); } } } [HarmonyPostfix] [HarmonyPatch(typeof(AudioManager))] [HarmonyPatch(/*Could not decode attribute arguments.*/)] private static void SetSFXGameplay(ref VoicePriority currentPriority, Characters character, AudioClipID audioClipID, AudioSource audioSource, VoicePriority playbackPriority) { //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) WorldHandler instance = WorldHandler.instance; if (!((Object)(object)((instance != null) ? instance.GetCurrentPlayer() : null) == (Object)null)) { WorldHandler instance2 = WorldHandler.instance; if (!((Object)(object)audioSource != (Object)(object)((instance2 != null) ? instance2.GetCurrentPlayer().playerGameplayVoicesAudioSource : null)) && GhostRecorder.Instance != null && GhostRecorder.Instance.Recording && GhostRecorder.Instance.LastFrame != null) { GhostRecorder.Instance.LastFrame.SFX.Add(new GhostFrame.GhostFrameSFX { AudioClipID = audioClipID, Voice = true }); } } } } [HarmonyPatch(typeof(Player))] internal class GhostPlayerPatch { [HarmonyPatch(typeof(Player), "OnTriggerStay")] public class Patch_Player_OnTriggerStay { [HarmonyPrefix] public static bool OnTriggerStay_Prefix(Collider other, Player __instance) { if ((Object)(object)__instance != (Object)(object)GhostPlayer.ghostPlayerCharacter) { return true; } return false; } } [HarmonyPatch(typeof(Player), "StopHoldSpraycan")] internal class Player_StopHoldSpraycan_Patch { [HarmonyPrefix] private static bool Prefix(Player __instance) { if ((Object)(object)__instance == (Object)(object)GhostPlayer.ghostPlayerCharacter) { return false; } return true; } } [HarmonyPrefix] [HarmonyPatch(typeof(Player), "PlayVoice")] private static bool PlayVoice_Prefix(Player __instance) { if ((Object)(object)__instance == (Object)(object)GhostPlayer.ghostPlayerCharacter) { return false; } return true; } [HarmonyPrefix] [HarmonyPatch(typeof(Player), "InitHitboxes")] private static bool InitHitboxes_Prefix(Player __instance) { if ((Object)(object)__instance == (Object)(object)GhostPlayer.ghostPlayerCharacter) { return false; } return true; } [HarmonyPrefix] [HarmonyPatch("FixedUpdatePlayer")] [HarmonyPatch("UpdatePlayer")] private static bool FixedUpdate_Prefix(Player __instance) { return (Object)(object)__instance != (Object)(object)GhostPlayer.ghostPlayerCharacter; } [HarmonyPostfix] [HarmonyPatch("PlayAnim")] private static void SetFrameAnim(int newAnim, bool forceOverwrite, bool instant, float atTime, Player __instance) { WorldHandler instance = WorldHandler.instance; if (!((Object)(object)__instance != (Object)(object)((instance != null) ? instance.GetCurrentPlayer() : null)) && GhostRecorder.Instance != null && GhostRecorder.Instance.Recording && GhostRecorder.Instance.LastFrame != null) { GhostRecorder.Instance.LastFrame.Animation.Instant = instant; GhostRecorder.Instance.LastFrame.Animation.AtTime = atTime; GhostRecorder.Instance.LastFrame.Animation.ForceOverwrite = forceOverwrite; } } [HarmonyPostfix] [HarmonyPatch("DoJumpEffects")] private static void SetFrameJumpEffects(Vector3 dir, Player __instance) { //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) WorldHandler instance = WorldHandler.instance; if (!((Object)(object)__instance != (Object)(object)((instance != null) ? instance.GetCurrentPlayer() : null)) && GhostRecorder.Instance != null && GhostRecorder.Instance.Recording && GhostRecorder.Instance.LastFrame != null) { GhostRecorder.Instance.LastFrame.Effects.DoJumpEffects = true; GhostRecorder.Instance.LastFrame.Effects.JumpEffects = dir; } } [HarmonyPostfix] [HarmonyPatch("DoHighJumpEffects")] private static void SetFrameHighJumpEffects(Vector3 dir, Player __instance) { //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) WorldHandler instance = WorldHandler.instance; if (!((Object)(object)__instance != (Object)(object)((instance != null) ? instance.GetCurrentPlayer() : null)) && GhostRecorder.Instance != null && GhostRecorder.Instance.Recording && GhostRecorder.Instance.LastFrame != null) { GhostRecorder.Instance.LastFrame.Effects.DoHighJumpEffects = true; GhostRecorder.Instance.LastFrame.Effects.HighJumpEffects = dir; } } } } namespace ScoreAttack { public enum SFXToggle { Default, DefaultPlus, LLB, FZero, POPN, SSBM, SF3S, Skullgirls } public class AppExtras : CustomApp { public override bool Available => false; public static SFXToggle SFXMode { get; private set; } public static void Initialize() { PhoneAPI.RegisterApp<AppExtras>("extras", (Sprite)null); } public override void OnAppInit() { //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) ((CustomApp)this).OnAppInit(); LoadState(); ((CustomApp)this).CreateIconlessTitleBar(GetExtrasTitle(), 80f); base.ScrollView = PhoneScrollView.Create((CustomApp)(object)this, 275f, 1600f); SimplePhoneButton toggle = PhoneUIUtility.CreateSimpleButton(GetViewerLabel()); SimplePhoneButton obj = toggle; ((PhoneButton)obj).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj).OnConfirm, (Action)delegate { SFXMode = GetNextMode(SFXMode); SaveState(); ((TMP_Text)toggle.Label).SetText(GetViewerLabel(), true); ((CustomApp)this).CreateIconlessTitleBar(GetExtrasTitle(), 80f); }); base.ScrollView.AddButton((PhoneButton)(object)toggle); SimplePhoneButton val = PhoneUIUtility.CreateSimpleButton("Open Leaderboard\n<size=50%>Opens in your default browser!</size>"); ((PhoneButton)val).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val).OnConfirm, (Action)delegate { OpenSpreadsheetInBrowser(); }); base.ScrollView.AddButton((PhoneButton)(object)val); SimplePhoneButton val2 = PhoneUIUtility.CreateSimpleButton("Export Save Data\n<size=50%>Back up your settings and records</size>"); ((PhoneButton)val2).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val2).OnConfirm, (Action)delegate { if (ScoreAttackEncounter.IsScoreAttackActive()) { Debug.LogError((object)"Can't export save data during a battle!"); Core.Instance.UIManager.ShowNotification("You are in a run! Cancel your current run before exporting your save file.", Array.Empty<string>()); } else { string text2 = SaveManager.ExportSaveData(); Core.Instance.UIManager.ShowNotification("Save Data Exported!\n<size=50%>" + text2 + "</size>", Array.Empty<string>()); } }); val2.LabelUnselectedColor = Color.black; val2.LabelSelectedColor = Color.red; base.ScrollView.AddButton((PhoneButton)(object)val2); SimplePhoneButton val3 = PhoneUIUtility.CreateSimpleButton("Import Save Data\n<size=50%>Load settings config and records</size>"); ((PhoneButton)val3).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val3).OnConfirm, (Action)delegate { if (ScoreAttackEncounter.IsScoreAttackActive()) { Debug.LogError((object)"Can't import save data during a battle!"); Core.Instance.UIManager.ShowNotification("You are in a run! Cancel your current run before importing a new save file.", Array.Empty<string>()); } else { string text = SaveManager.ImportSaveData(); if (string.IsNullOrEmpty(text)) { Core.Instance.UIManager.ShowNotification("No save file found to import.", Array.Empty<string>()); } else { Core.Instance.UIManager.ShowNotification("Save Data Imported!\n<size=50%>" + text + "</size>", Array.Empty<string>()); } } }); val3.LabelUnselectedColor = Color.black; val3.LabelSelectedColor = Color.red; base.ScrollView.AddButton((PhoneButton)(object)val3); } public override void OnAppDisable() { ((MonoBehaviour)Core.Instance).StartCoroutine(ScoreAttackManager.Encounter.LoadAnnouncerClips()); ((App)this).OnAppDisable(); } private static string GetViewerLabel() { string text = ((SFXMode == SFXToggle.Default) ? "white" : "yellow"); return "Score Attack SFX \n<size=50%><color=" + text + ">" + GetFormattedEnumName(SFXMode) + "</color></size>"; } private static string GetFormattedEnumName(SFXToggle mode) { return mode switch { SFXToggle.Default => "Default SFX", SFXToggle.DefaultPlus => "Default Plus SFX", SFXToggle.LLB => "Lethal League Blaze SFX", SFXToggle.FZero => "F-Zero GX SFX", SFXToggle.POPN => "Pop'n Music SFX", SFXToggle.SSBM => "Smash Bros. Melee SFX", SFXToggle.SF3S => "Street Fighter III 3rd Strike SFX", SFXToggle.Skullgirls => "Skullgirls SFX", _ => mode.ToString(), }; } private static SFXToggle GetNextMode(SFXToggle current) { return (SFXToggle)((int)(current + 1) % Enum.GetValues(typeof(SFXToggle)).Length); } private void LoadState() { try { SFXMode = ScoreAttackSaveData.Instance.ExtraSFXMode; } catch { SFXMode = SFXToggle.Default; } } private void SaveState() { ScoreAttackSaveData.Instance.ExtraSFXMode = SFXMode; Core.Instance.SaveManager.SaveCurrentSaveSlot(); Debug.Log((object)$"[ScoreAttack] Saved SFXMode: {SFXMode}"); } private static string GetExtrasTitle() { return "Extras\n<size=50%>Experimental!</size>"; } private void OpenSpreadsheetInBrowser() { string text = "https://docs.google.com/spreadsheets/d/e/2PACX-1vQPLU_jkIHBLmvsMqjotXKyeUZ2veHfseqzD_aMRI29b6Mb92c0o5l8WUdDPCp1s4xVwyLwgYHBiYa7/pubhtml"; Application.OpenURL(text); Core.Instance.UIManager.ShowNotification("<size=75%><color=yellow>Vanilla Score Attack Leaderboard</color> opened in your default web browser! </size>\n<size=50%>You can also go to <color=yellow>sloppers.club/leaderboard</color> to view/submit vanilla score attack runs!</size>", Array.Empty<string>()); } } public class AppFPSLimit : CustomApp { public class VSyncWatcher : MonoBehaviour { private float timer = 0f; private string lastTitle = ""; private void Update() { timer += Time.deltaTime; if (!(timer >= 0.5f)) { return; } timer = 0f; string text = StaticGetFpsTitle(); if (text != lastTitle) { lastTitle = text; if ((Object)(object)Instance != (Object)null) { Instance.ForceTitleRefresh(text); } } } } public bool LimitFramerate = false; public int FpsLimit = 60; public int CurrentFps = 60; private float refreshTimer = 0f; private string lastTitle = ""; public static AppFPSLimit Instance; public override bool Available => false; public static void Initialize() { PhoneAPI.RegisterApp<AppFPSLimit>("fps select", (Sprite)null); } public override void OnAppInit() { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown ((CustomApp)this).OnAppInit(); Instance = this; ((CustomApp)this).CreateIconlessTitleBar(GetFpsTitle(), 80f); if ((Object)(object)GameObject.Find("VSyncWatcher") == (Object)null) { GameObject val = new GameObject("VSyncWatcher"); Object.DontDestroyOnLoad((Object)(object)val); val.AddComponent<VSyncWatcher>(); } base.ScrollView = PhoneScrollView.Create((CustomApp)(object)this, 275f, 1600f); SimplePhoneButton val2 = PhoneUIUtility.CreateSimpleButton("30 fps"); SimplePhoneButton obj = val2; ((PhoneButton)obj).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj).OnConfirm, (Action)delegate { SetTargetFrameRate(30); Core.Instance.UIManager.ShowNotification("FPS Limit has been set to 30! \nMake sure " + GetColoredVSyncText() + " is off for it to go into effect.", Array.Empty<string>()); }); base.ScrollView.AddButton((PhoneButton)(object)val2); val2 = PhoneUIUtility.CreateSimpleButton("40 fps"); SimplePhoneButton obj2 = val2; ((PhoneButton)obj2).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj2).OnConfirm, (Action)delegate { SetTargetFrameRate(40); Core.Instance.UIManager.ShowNotification("FPS Limit has been set to 40! \nMake sure " + GetColoredVSyncText() + " is off for it to go into effect.", Array.Empty<string>()); }); base.ScrollView.AddButton((PhoneButton)(object)val2); val2 = PhoneUIUtility.CreateSimpleButton("60 fps"); SimplePhoneButton obj3 = val2; ((PhoneButton)obj3).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj3).OnConfirm, (Action)delegate { SetTargetFrameRate(60); Core.Instance.UIManager.ShowNotification("FPS Limit has been set to 60! \nMake sure " + GetColoredVSyncText() + " is off for it to go into effect.", Array.Empty<string>()); }); base.ScrollView.AddButton((PhoneButton)(object)val2); val2 = PhoneUIUtility.CreateSimpleButton("90 fps"); SimplePhoneButton obj4 = val2; ((PhoneButton)obj4).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj4).OnConfirm, (Action)delegate { SetTargetFrameRate(90); Core.Instance.UIManager.ShowNotification("FPS Limit has been set to 90! \nMake sure " + GetColoredVSyncText() + " is off for it to go into effect.", Array.Empty<string>()); }); base.ScrollView.AddButton((PhoneButton)(object)val2); val2 = PhoneUIUtility.CreateSimpleButton("120 fps"); SimplePhoneButton obj5 = val2; ((PhoneButton)obj5).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj5).OnConfirm, (Action)delegate { SetTargetFrameRate(120); Core.Instance.UIManager.ShowNotification("FPS Limit has been set to 120! \nMake sure " + GetColoredVSyncText() + " is off for it to go into effect.", Array.Empty<string>()); }); base.ScrollView.AddButton((PhoneButton)(object)val2); val2 = PhoneUIUtility.CreateSimpleButton("144 fps"); SimplePhoneButton obj6 = val2; ((PhoneButton)obj6).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj6).OnConfirm, (Action)delegate { SetTargetFrameRate(144); Core.Instance.UIManager.ShowNotification("FPS Limit has been set to 144! \nMake sure " + GetColoredVSyncText() + " is off for it to go into effect.", Array.Empty<string>()); }); base.ScrollView.AddButton((PhoneButton)(object)val2); val2 = PhoneUIUtility.CreateSimpleButton("240 fps"); SimplePhoneButton obj7 = val2; ((PhoneButton)obj7).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj7).OnConfirm, (Action)delegate { SetTargetFrameRate(240); Core.Instance.UIManager.ShowNotification("FPS Limit has been set to 240! \nMake sure " + GetColoredVSyncText() + " is off for it to go into effect.", Array.Empty<string>()); }); base.ScrollView.AddButton((PhoneButton)(object)val2); val2 = PhoneUIUtility.CreateSimpleButton("Unlimited"); SimplePhoneButton obj8 = val2; ((PhoneButton)obj8).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj8).OnConfirm, (Action)delegate { SetTargetFrameRate(-1); Core.Instance.UIManager.ShowNotification("Your FPS has no limits! \nMake sure " + GetColoredVSyncText() + " is off for it to go into effect.", Array.Empty<string>()); }); base.ScrollView.AddButton((PhoneButton)(object)val2); } private void SetTargetFrameRate(int frameRate) { Application.targetFrameRate = frameRate; ScoreAttackSaveData.Instance.TargetFrameRate = frameRate; ((CustomApp)this).CreateIconlessTitleBar(GetFpsTitle(), 80f); } private void RefreshVSyncStatus() { string fpsTitle = GetFpsTitle(); if (fpsTitle != lastTitle) { lastTitle = fpsTitle; ((CustomApp)this).CreateIconlessTitleBar(fpsTitle, 80f); } } private string GetFpsTitle() { int targetFrameRate = ScoreAttackSaveData.Instance.TargetFrameRate; if (targetFrameRate == 0) { targetFrameRate = Application.targetFrameRate; ScoreAttackSaveData.Instance.TargetFrameRate = targetFrameRate; } string text = targetFrameRate switch { 0 => "No Limit Set", -1 => "None, baby!", _ => targetFrameRate + " fps", }; string text2 = ((QualitySettings.vSyncCount > 0) ? "V-Sync = On" : "V-Sync = Off"); return "FPS Limit\n<size=50%>Limit = " + text + "</size>\n<size=50%>" + text2 + "</size>"; } public static string StaticGetFpsTitle() { int targetFrameRate = ScoreAttackSaveData.Instance.TargetFrameRate; if (targetFrameRate == 0) { targetFrameRate = Application.targetFrameRate; } string text = targetFrameRate switch { 0 => "No Limit Set", -1 => "None, baby!", _ => targetFrameRate + " fps", }; string text2 = ((QualitySettings.vSyncCount > 0) ? "V-Sync = On" : "V-Sync = Off"); return "FPS Limit\n<size=50%>Limit = " + text + "</size>\n<size=50%>" + text2 + "</size>"; } private void OnUpdate() { refreshTimer += Time.deltaTime; if (refreshTimer >= 0.5f) { refreshTimer = 0f; RefreshVSyncStatus(); } } public void ForceTitleRefresh(string newTitle) { ((CustomApp)this).CreateIconlessTitleBar(newTitle, 80f); } private string GetColoredVSyncText() { string text = ((QualitySettings.vSyncCount > 0) ? "red" : "green"); return "<color=" + text + ">V-Sync</color>"; } } public enum GrindDebtDisplayMode { Disabled, Bar, Value, Both, SoftGoat } public enum GrindDebtColorMode { Flashing, Red, White } public class AppGrindDebt : CustomApp { public class GrindDebtMonitor : MonoBehaviour { private AppGrindDebt app; private float refreshCooldown = 0.25f; private float refreshTimer = 0f; private bool hadDebt = false; public void Init(AppGrindDebt appRef) { app = appRef; } private void Update() { if ((Object)(object)app == (Object)null) { return; } refreshTimer -= Time.deltaTime; if (refreshTimer <= 0f) { refreshTimer = refreshCooldown; float trickTimer = GetTrickTimer(); bool flag = trickTimer >= 0.2f; if (flag != hadDebt) { hadDebt = flag; ((CustomApp)app).CreateIconlessTitleBar(GetGrindDebtString(), 80f); } } } } private float refreshCooldown = 0.25f; private float refreshTimer = 0f; private bool hadDebt = false; public override bool Available => false; public static GrindDebtDisplayMode ViewerMode { get; private set; } public static GrindDebtColorMode ColorMode { get; private set; } public static void Initialize() { PhoneAPI.RegisterApp<AppGrindDebt>("grind debt", (Sprite)null); } public override void OnAppInit() { ((CustomApp)this).OnAppInit(); LoadState(); ((CustomApp)this).CreateIconlessTitleBar(GetGrindDebtString(), 80f); ((Component)this).gameObject.AddComponent<GrindDebtMonitor>().Init(this); base.ScrollView = PhoneScrollView.Create((CustomApp)(object)this, 275f, 1600f); SimplePhoneButton val = PhoneUIUtility.CreateSimpleButton("Clear Grind Debt"); ((PhoneButton)val).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val).OnConfirm, (Action)delegate { Player currentPlayer = WorldHandler.instance.GetCurrentPlayer(); currentPlayer.grindAbility.trickTimer = 0f; currentPlayer.RefreshAllDegrade(); ((CustomApp)this).CreateIconlessTitleBar(GetGrindDebtString(), 80f); hadDebt = false; }); base.ScrollView.AddButton((PhoneButton)(object)val); SimplePhoneButton toggle = PhoneUIUtility.CreateSimpleButton(GetViewerLabel()); SimplePhoneButton obj = toggle; ((PhoneButton)obj).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj).OnConfirm, (Action)delegate { ViewerMode = GetNextMode(ViewerMode); ((TMP_Text)toggle.Label).SetText(GetViewerLabel(), true); ((CustomApp)this).CreateIconlessTitleBar(GetGrindDebtString(), 80f); SaveState(); }); base.ScrollView.AddButton((PhoneButton)(object)toggle); SimplePhoneButton colorToggle = PhoneUIUtility.CreateSimpleButton(GetColorLabel()); SimplePhoneButton obj2 = colorToggle; ((PhoneButton)obj2).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj2).OnConfirm, (Action)delegate { ColorMode = GetNextColorMode(ColorMode); ((TMP_Text)colorToggle.Label).SetText(GetColorLabel(), true); SaveState(); }); base.ScrollView.AddButton((PhoneButton)(object)colorToggle); } private static string GetViewerLabel() { string text = ((ViewerMode == GrindDebtDisplayMode.Disabled) ? "red" : "green"); return "Grind Debt Viewer \n<size=50%><color=" + text + ">" + GetFormattedEnumName(ViewerMode) + "</color></size>"; } private static string GetFormattedEnumName(GrindDebtDisplayMode mode) { return mode switch { GrindDebtDisplayMode.Disabled => "Disabled", GrindDebtDisplayMode.Bar => "Boost Bar", GrindDebtDisplayMode.Value => "Numerical Value", GrindDebtDisplayMode.Both => "Bar + Value", GrindDebtDisplayMode.SoftGoat => "SoftGoat Speedometer Preset", _ => mode.ToString(), }; } private static string GetColorLabel() { return "Viewer Behavior \n<size=50%><color=orange>" + GetFormattedEnumName(ColorMode) + "</color></size>"; } private static string GetFormattedEnumName(GrindDebtColorMode mode) { return mode switch { GrindDebtColorMode.Flashing => "Flash When You Have Debt", GrindDebtColorMode.Red => "Solid Colors", GrindDebtColorMode.White => "All White", _ => mode.ToString(), }; } private static GrindDebtDisplayMode GetNextMode(GrindDebtDisplayMode current) { return (GrindDebtDisplayMode)((int)(current + 1) % 5); } private static GrindDebtColorMode GetNextColorMode(GrindDebtColorMode current) { return (GrindDebtColorMode)((int)(current + 1) % 3); } public static float GetTrickTimer() { Player currentPlayer = WorldHandler.instance.GetCurrentPlayer(); if ((Object)(object)currentPlayer == (Object)null || currentPlayer.grindAbility == null) { return 0f; } return currentPlayer.grindAbility.trickTimer; } private void LoadState() { ViewerMode = ScoreAttackSaveData.Instance.GrindDebtViewerMode; ColorMode = ScoreAttackSaveData.Instance.GrindDebtColorMode; } private void SaveState() { ScoreAttackSaveData.Instance.GrindDebtViewerMode = ViewerMode; ScoreAttackSaveData.Instance.GrindDebtColorMode = ColorMode; } private static string GetGrindDebtString() { Player currentPlayer = WorldHandler.instance.GetCurrentPlayer(); if ((Object)(object)currentPlayer == (Object)null || currentPlayer.grindAbility == null) { return "Grind Debt\n<size=50%>Checking...</size>"; } float trickTimer = currentPlayer.grindAbility.trickTimer; float num = Mathf.Floor(trickTimer * 10f) / 10f; if (num >= 0.2f) { return "Grind Debt\n<size=50%><color=red>Pay your debts...</color></size>"; } return "Grind Debt\n<size=50%>No debt here!</size>"; } } public class AppMoveStyle : CustomApp { private Player player; private WorldHandler world; private bool coreHasBeenSetup; private MoveStyle currentStyle; private Dictionary<MoveStyle, int> skinIndices = new Dictionary<MoveStyle, int>(); private int characterSkinIndex = 0; public override bool Available => false; public static void Initialize() { PhoneAPI.RegisterApp<AppMoveStyle>("move styles", (Sprite)null); } public override void OnAppInit() { //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) ((CustomApp)this).OnAppInit(); ((CustomApp)this).CreateIconlessTitleBar("Change Style", 80f); base.ScrollView = PhoneScrollView.Create((CustomApp)(object)this, 275f, 1600f); player = WorldHandler.instance.GetCurrentPlayer(); world = WorldHandler.instance; coreHasBeenSetup = (Object)(object)player != (Object)null && (Object)(object)world != (Object)null; SimplePhoneButton val = PhoneUIUtility.CreateSimpleButton("Skateboard"); SimplePhoneButton obj = val; ((PhoneButton)obj).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj).OnConfirm, (Action)delegate { if (coreHasBeenSetup) { SwapStyle((MoveStyle)2); } }); base.ScrollView.AddButton((PhoneButton)(object)val); val = PhoneUIUtility.CreateSimpleButton("Inline Skates"); SimplePhoneButton obj2 = val; ((PhoneButton)obj2).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj2).OnConfirm, (Action)delegate { if (coreHasBeenSetup) { SwapStyle((MoveStyle)3); } }); base.ScrollView.AddButton((PhoneButton)(object)val); val = PhoneUIUtility.CreateSimpleButton("BMX"); SimplePhoneButton obj3 = val; ((PhoneButton)obj3).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj3).OnConfirm, (Action)delegate { if (coreHasBeenSetup) { SwapStyle((MoveStyle)1); } }); base.ScrollView.AddButton((PhoneButton)(object)val); val = PhoneUIUtility.CreateSimpleButton("Swap Style Skin\n<size=50%>Change how your gear looks!</size>"); SimplePhoneButton obj4 = val; ((PhoneButton)obj4).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj4).OnConfirm, (Action)delegate { if (coreHasBeenSetup) { CycleSkinForCurrentStyle(); } }); base.ScrollView.AddButton((PhoneButton)(object)val); val = PhoneUIUtility.CreateSimpleButton("Swap Outfit\n<size=50%>Change your clothes!</size>"); SimplePhoneButton obj5 = val; ((PhoneButton)obj5).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj5).OnConfirm, (Action)delegate { if (coreHasBeenSetup) { SwapCharacterOutfit(); } }); base.ScrollView.AddButton((PhoneButton)(object)val); if ((Object)(object)player != (Object)null) { currentStyle = player.moveStyle; if (!skinIndices.ContainsKey(currentStyle)) { skinIndices[currentStyle] = 0; } ApplySkin(currentStyle, skinIndices[currentStyle]); } } private void SwapStyle(MoveStyle newStyle) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Expected O, but got Unknown //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Expected O, but got Unknown //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player != (Object)null) { Ability val = (Ability)Traverse.Create((object)player).Field("ability").GetValue(); GrindAbility val2 = (GrindAbility)Traverse.Create((object)player).Field("grindAbility").GetValue(); WallrunLineAbility val3 = (WallrunLineAbility)Traverse.Create((object)player).Field("wallrunAbility").GetValue(); player.InitMovement(newStyle); if (val == val2) { player.SwitchToEquippedMovestyle(true, false, true, true); } else if (val == val3) { player.SwitchToEquippedMovestyle(true, true, true, true); } else { player.SwitchToEquippedMovestyle(true, true, true, true); } currentStyle = newStyle; if (!skinIndices.ContainsKey(newStyle)) { skinIndices[newStyle] = 0; } ApplySkin(newStyle, skinIndices[newStyle]); } } private void CycleSkinForCurrentStyle() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)player == (Object)null)) { currentStyle = player.moveStyle; if (!skinIndices.ContainsKey(currentStyle)) { skinIndices[currentStyle] = 1; } int num = skinIndices[currentStyle]; int num2 = (num + 1) % 10; skinIndices[currentStyle] = num2; ApplySkin(currentStyle, num2); } } private void ApplySkin(MoveStyle style, int skinIndex) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null) { return; } Texture moveStyleSkinTexture = player.CharacterConstructor.GetMoveStyleSkinTexture(style, skinIndex); if ((Object)(object)moveStyleSkinTexture == (Object)null) { return; } Material[] moveStyleMaterials = MoveStyleLoader.GetMoveStyleMaterials(player, style); if (moveStyleMaterials == null || moveStyleMaterials.Length == 0) { Debug.LogWarning((object)$"No materials found for MoveStyle {style}"); return; } for (int i = 0; i < moveStyleMaterials.Length; i++) { moveStyleMaterials[i].mainTexture = moveStyleSkinTexture; } Debug.Log((object)$"Applied skin index {skinIndex} for style {style}"); } private void SwapCharacterOutfit() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)player == (Object)null)) { Characters character = player.character; CharacterProgress characterProgress = Core.Instance.SaveManager.CurrentSaveSlot.GetCharacterProgress(character); characterSkinIndex = (characterSkinIndex + 1) % 4; player.SetOutfit(characterSkinIndex); Debug.Log((object)$"Swapped to outfit index {characterSkinIndex} for character {character}"); } } } public class AppPolice : CustomApp { private WantedManager wantedManager; public override bool Available => false; public static void Initialize() { PhoneAPI.RegisterApp<AppPolice>("remove police", (Sprite)null); } public override void OnAppInit() { ((CustomApp)this).OnAppInit(); ((CustomApp)this).CreateIconlessTitleBar("Wanted Level", 80f); base.ScrollView = PhoneScrollView.Create((CustomApp)(object)this, 275f, 1600f); SimplePhoneButton val = PhoneUIUtility.CreateSimpleButton("Remove Police"); SimplePhoneButton obj = val; ((PhoneButton)obj).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj).OnConfirm, (Action)delegate { if (PlayerIsWanted()) { wantedManager.StopPlayerWantedStatus(true); } Player currentPlayer = WorldHandler.instance.GetCurrentPlayer(); currentPlayer.ResetHP(); if (currentPlayer.AmountOfCuffs() > 0) { currentPlayer.RemoveAllCuffs((CuffMissileLauncher)null); } }); base.ScrollView.AddButton((PhoneButton)(object)val); val = PhoneUIUtility.CreateSimpleButton("Enable Cops"); SimplePhoneButton obj2 = val; ((PhoneButton)obj2).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj2).OnConfirm, (Action)delegate { }); base.ScrollView.AddButton((PhoneButton)(object)val); } public void Update() { wantedManager = WantedManager.instance; } public bool PlayerIsWanted() { if ((Object)(object)wantedManager != (Object)null) { return wantedManager.Wanted; } return false; } public void StopWantedStatus() { if (PlayerIsWanted()) { Debug.Log((object)"Stopping wanted status..."); wantedManager.StopPlayerWantedStatus(true); } } } public class AppScoreAttack : CustomApp { public static Encounter globalEncounter; private PhoneButton goToRespawnButton = null; private WantedManager wantedManager; public bool testingPlugin = false; public override bool Available => false; public static void Initialize() { PhoneAPI.RegisterApp<AppScoreAttack>("score atk", (Sprite)null); } public override void OnAppInit() { //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Unknown result type (might be due to invalid IL or missing references) ((CustomApp)this).OnAppInit(); ((CustomApp)this).CreateIconlessTitleBar("Select Length", 80f); base.ScrollView = PhoneScrollView.Create((CustomApp)(object)this, 275f, 1600f); SimplePhoneButton val = PhoneUIUtility.CreateSimpleButton("3 Minutes"); SimplePhoneButton obj = val; ((PhoneButton)obj).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj).OnConfirm, (Action)delegate { //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) Debug.Log((object)"Starting 3 Minute Score Battle..."); if (BannedMods.IsAdvantageousModLoaded()) { Core.Instance.UIManager.ShowNotification("The score attack app is not compatible with TrickGod!", Array.Empty<string>()); } else { if (ScoreAttackEncounter.IsScoreAttackActive()) { ScoreAttackEncounter scoreAttackEncounter6 = Object.FindObjectOfType<ScoreAttackEncounter>(); scoreAttackEncounter6.EndScoreAttack(); Core.Instance.SaveManager.SaveCurrentSaveSlot(); } BattleRefresh(); ScoreAttackManager.ExternalGhostLoadedFromGhostList = false; Stage currentStage4 = Core.Instance.BaseModule.CurrentStage; RespawnPoint respawnPoint4 = ScoreAttackSaveData.Instance.GetRespawnPoint(currentStage4); if (respawnPoint4 == null) { Core.Instance.UIManager.ShowNotification("Please set a respawn point first!\n<size=50%>It's at the bottom of the app menu!</size>", Array.Empty<string>()); } else { respawnPoint4.ApplyToPlayer(((App)this).MyPhone.player); ScoreAttackManager.StartScoreAttack(180f); ((App)this).MyPhone.CloseCurrentApp(); ((App)this).MyPhone.TurnOff(false); ScoreAttackManager.StartScoreAttack(180f); ((App)this).MyPhone.CloseCurrentApp(); ((App)this).MyPhone.TurnOff(false); } } }); base.ScrollView.AddButton((PhoneButton)(object)val); val = PhoneUIUtility.CreateSimpleButton("5 Minutes"); SimplePhoneButton obj2 = val; ((PhoneButton)obj2).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj2).OnConfirm, (Action)delegate { //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) Debug.Log((object)"Starting 5 Minute Score Battle..."); if (ScoreAttackEncounter.IsScoreAttackActive()) { ScoreAttackEncounter scoreAttackEncounter5 = Object.FindObjectOfType<ScoreAttackEncounter>(); scoreAttackEncounter5.EndScoreAttack(); Core.Instance.SaveManager.SaveCurrentSaveSlot(); } BattleRefresh(); ScoreAttackManager.ExternalGhostLoadedFromGhostList = false; if (BannedMods.IsAdvantageousModLoaded()) { Core.Instance.UIManager.ShowNotification("The score attack app is not compatible with TrickGod!", Array.Empty<string>()); } else { Stage currentStage3 = Core.Instance.BaseModule.CurrentStage; RespawnPoint respawnPoint3 = ScoreAttackSaveData.Instance.GetRespawnPoint(currentStage3); if (respawnPoint3 == null) { Core.Instance.UIManager.ShowNotification("Please set a respawn point first!\n<size=50%>It's at the bottom of the app menu!</size>", Array.Empty<string>()); } else { respawnPoint3.ApplyToPlayer(((App)this).MyPhone.player); ScoreAttackManager.StartScoreAttack(300f); ((App)this).MyPhone.CloseCurrentApp(); ((App)this).MyPhone.TurnOff(false); ScoreAttackManager.StartScoreAttack(300f); ((App)this).MyPhone.CloseCurrentApp(); ((App)this).MyPhone.TurnOff(false); } } }); base.ScrollView.AddButton((PhoneButton)(object)val); val = PhoneUIUtility.CreateSimpleButton("10 Minutes"); SimplePhoneButton obj3 = val; ((PhoneButton)obj3).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj3).OnConfirm, (Action)delegate { //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) Debug.Log((object)"Starting 10 Minute Score Battle..."); if (ScoreAttackEncounter.IsScoreAttackActive()) { ScoreAttackEncounter scoreAttackEncounter4 = Object.FindObjectOfType<ScoreAttackEncounter>(); scoreAttackEncounter4.EndScoreAttack(); Core.Instance.SaveManager.SaveCurrentSaveSlot(); } BattleRefresh(); ScoreAttackManager.ExternalGhostLoadedFromGhostList = false; if (BannedMods.IsAdvantageousModLoaded()) { Core.Instance.UIManager.ShowNotification("The score attack app is not compatible with TrickGod!", Array.Empty<string>()); } else { Stage currentStage2 = Core.Instance.BaseModule.CurrentStage; RespawnPoint respawnPoint2 = ScoreAttackSaveData.Instance.GetRespawnPoint(currentStage2); if (respawnPoint2 == null) { Core.Instance.UIManager.ShowNotification("Please set a respawn point first!\n<size=50%>It's at the bottom of the app menu!</size>", Array.Empty<string>()); } else { respawnPoint2.ApplyToPlayer(((App)this).MyPhone.player); ScoreAttackManager.StartScoreAttack(600f); ((App)this).MyPhone.CloseCurrentApp(); ((App)this).MyPhone.TurnOff(false); ScoreAttackManager.StartScoreAttack(600f); ((App)this).MyPhone.CloseCurrentApp(); ((App)this).MyPhone.TurnOff(false); } } }); base.ScrollView.AddButton((PhoneButton)(object)val); if (testingPlugin) { val = PhoneUIUtility.CreateSimpleButton("1 Minute"); SimplePhoneButton obj4 = val; ((PhoneButton)obj4).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj4).OnConfirm, (Action)delegate { //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) Debug.Log((object)"Starting 1 Minute Score Battle..."); if (ScoreAttackEncounter.IsScoreAttackActive()) { ScoreAttackEncounter scoreAttackEncounter3 = Object.FindObjectOfType<ScoreAttackEncounter>(); scoreAttackEncounter3.EndScoreAttack(); Core.Instance.SaveManager.SaveCurrentSaveSlot(); } BattleRefresh(); ScoreAttackManager.ExternalGhostLoadedFromGhostList = false; if (BannedMods.IsAdvantageousModLoaded()) { Core.Instance.UIManager.ShowNotification("The score attack app is not compatible with TrickGod!", Array.Empty<string>()); } else { Stage currentStage = Core.Instance.BaseModule.CurrentStage; RespawnPoint respawnPoint = ScoreAttackSaveData.Instance.GetRespawnPoint(currentStage); if (respawnPoint == null) { Core.Instance.UIManager.ShowNotification("Please set a respawn point first!\n<size=50%>It's at the bottom of the app menu!</size>", Array.Empty<string>()); } else { respawnPoint.ApplyToPlayer(((App)this).MyPhone.player); ScoreAttackManager.StartScoreAttack(60f); ((App)this).MyPhone.CloseCurrentApp(); ((App)this).MyPhone.TurnOff(false); ScoreAttackManager.StartScoreAttack(60f); ((App)this).MyPhone.CloseCurrentApp(); ((App)this).MyPhone.TurnOff(false); } } }); base.ScrollView.AddButton((PhoneButton)(object)val); } val = PhoneUIUtility.CreateSimpleButton("Cancel Run"); SimplePhoneButton obj5 = val; ((PhoneButton)obj5).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj5).OnConfirm, (Action)delegate { Debug.Log((object)"Cancelling Active Battle..."); ScoreAttackManager.LoadedExternalGhost = null; ScoreAttackManager.ExternalGhostLoadedFromGhostList = false; if (ScoreAttackEncounter.IsScoreAttackActive()) { ScoreAttackEncounter scoreAttackEncounter2 = Object.FindObjectOfType<ScoreAttackEncounter>(); scoreAttackEncounter2.EndScoreAttack(); Core.Instance.SaveManager.SaveCurrentSaveSlot(); } else { Core.Instance.UIManager.ShowNotification("There is no ongoing Score Battle run!", Array.Empty<string>()); } }); val.LabelUnselectedColor = Color.black; val.LabelSelectedColor = Color.red; base.ScrollView.AddButton((PhoneButton)(object)val); val = PhoneUIUtility.CreateSimpleButton("Erase All Your Personal Bests"); SimplePhoneButton obj6 = val; ((PhoneButton)obj6).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj6).OnConfirm, (Action)delegate { Debug.Log((object)"Clearing Personal Bests..."); ScoreAttackEncounter scoreAttackEncounter = Object.FindObjectOfType<ScoreAttackEncounter>(); if ((Object)(object)scoreAttackEncounter != (Object)null) { if (ScoreAttackEncounter.IsScoreAttackActive()) { Debug.LogError((object)"Can't clear PB during a run!"); Core.Instance.UIManager.ShowNotification("You are in a run! Cancel the run to clear your personal bests.", Array.Empty<string>()); } else { scoreAttackEncounter.ClearPersonalBest(); Core.Instance.UIManager.ShowNotification("Personal bests have been erased.", Array.Empty<string>()); } } else { Debug.LogError((object)"ScoreAttackEncounter instance not found!"); } }); val.LabelUnselectedColor = Color.black; val.LabelSelectedColor = Color.red; base.ScrollView.AddButton((PhoneButton)(object)val); } public static void InitializeEncounter() { globalEncounter = Object.FindObjectOfType<Encounter>(); if ((Object)(object)globalEncounter == (Object)null) { Debug.LogError((object)"Error: Encounter object not found!"); } } public static void BattleRefresh() { Player currentPlayer = WorldHandler.instance.GetCurrentPlayer(); currentPlayer.boostCharge = currentPlayer.maxBoostCharge; Debug.Log((object)"Respawning Pickups..."); Object.FindObjectsOfType<Pickup>().Where(delegate(Pickup pickup) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Invalid comparison between Unknown and I4 PickUpType pickupType = pickup.pickupType; bool flag = (int)pickupType <= 1; return flag && (Object)(object)pickup.pickupObject != (Object)null; }).ToList() .ForEach(delegate(Pickup boost) { boost.SetPickupActive(true); }); Debug.Log((object)"Restoring Vending Machines..."); List<VendingMachine> list = (from vending in Object.FindObjectsOfType<VendingMachine>() where vending.rewardCount > 0 select vending).ToList(); foreach (VendingMachine item in list) { if (item.dropCount > 0) { item.dropCount = 0; } } foreach (VendingMachine item2 in list) { if (item2.rewardCount > 0) { item2.rewardCount = 0; } } foreach (VendingMachine item3 in list) { if (item3.firstHit) { item3.firstHit = false; } } } } public class AppScoreAttackOffline : CustomApp { private static Sprite IconSprite; private PhoneButton goToRespawnButton = null; private WantedManager wantedManager; public static void Initialize() { IconSprite = TextureUtility.LoadSprite(Path.Combine(ScoreAttackPlugin.Instance.Directory, "scoreIcon.png")); PhoneAPI.RegisterApp<AppScoreAttackOffline>("score atk", IconSprite); } public void UpdateGoToRespawnButton() { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) Stage currentStage = Core.Instance.BaseModule.CurrentStage; RespawnPoint respawnPoint = ScoreAttackSaveData.Instance.GetRespawnPoint(currentStage); if (respawnPoint == null) { if (base.ScrollView.HasButton(goToRespawnButton)) { base.ScrollView.RemoveButton(goToRespawnButton); } } else if (!base.ScrollView.HasButton(goToRespawnButton)) { base.ScrollView.AddButton(goToRespawnButton); } } public override void OnAppEnable() { ((App)this).OnAppEnable(); UpdateGoToRespawnButton(); } public override void OnAppInit() { ((CustomApp)this).OnAppInit(); ((CustomApp)this).CreateTitleBar("Score Attack", IconSprite, 80f); base.ScrollView = PhoneScrollView.Create((CustomApp)(object)this, 275f, 1600f); SimplePhoneButton val = PhoneUIUtility.CreateSimpleButton("Start a Run..."); SimplePhoneButton obj = val; ((PhoneButton)obj).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj).OnConfirm, (Action)delegate { ((App)this).MyPhone.OpenApp(typeof(AppScoreAttack)); }); base.ScrollView.AddButton((PhoneButton)(object)val); val = PhoneUIUtility.CreateSimpleButton("Ghost Replays..."); SimplePhoneButton obj2 = val; ((PhoneButton)obj2).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj2).OnConfirm, (Action)delegate { ((App)this).MyPhone.OpenApp(typeof(AppGhost)); }); base.ScrollView.AddButton((PhoneButton)(object)val); val = PhoneUIUtility.CreateSimpleButton("Go to Stage..."); SimplePhoneButton obj3 = val; ((PhoneButton)obj3).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj3).OnConfirm, (Action)delegate { ((App)this).MyPhone.OpenApp(typeof(AppScoreAttackStageSelect)); }); base.ScrollView.AddButton((PhoneButton)(object)val); val = PhoneUIUtility.CreateSimpleButton("Change Style..."); SimplePhoneButton obj4 = val; ((PhoneButton)obj4).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj4).OnConfirm, (Action)delegate { ((App)this).MyPhone.OpenApp(typeof(AppMoveStyle)); }); base.ScrollView.AddButton((PhoneButton)(object)val); val = PhoneUIUtility.CreateSimpleButton("Refill Boost"); SimplePhoneButton obj5 = val; ((PhoneButton)obj5).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj5).OnConfirm, (Action)delegate { Player currentPlayer2 = WorldHandler.instance.GetCurrentPlayer(); currentPlayer2.boostCharge = currentPlayer2.maxBoostCharge; }); base.ScrollView.AddButton((PhoneButton)(object)val); val = PhoneUIUtility.CreateSimpleButton("Reset Capsules"); SimplePhoneButton obj6 = val; ((PhoneButton)obj6).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj6).OnConfirm, (Action)delegate { Debug.Log((object)"Respawning Pickups..."); Object.FindObjectsOfType<Pickup>().Where(delegate(Pickup pickup) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Invalid comparison between Unknown and I4 PickUpType pickupType = pickup.pickupType; bool flag = (int)pickupType <= 1; return flag && (Object)(object)pickup.pickupObject != (Object)null; }).ToList() .ForEach(delegate(Pickup boost) { boost.SetPickupActive(true); }); Debug.Log((object)"Restoring Vending Machines..."); List<VendingMachine> list = (from vending in Object.FindObjectsOfType<VendingMachine>() where vending.rewardCount > 0 select vending).ToList(); foreach (VendingMachine item in list) { if (item.dropCount > 0) { item.dropCount = 0; } } foreach (VendingMachine item2 in list) { if (item2.rewardCount > 0) { item2.rewardCount = 0; } } foreach (VendingMachine item3 in list) { if (item3.firstHit) { item3.firstHit = false; } } }); base.ScrollView.AddButton((PhoneButton)(object)val); val = PhoneUIUtility.CreateSimpleButton("Reset Cops"); SimplePhoneButton obj7 = val; ((PhoneButton)obj7).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj7).OnConfirm, (Action)delegate { if (PlayerIsWanted()) { wantedManager.StopPlayerWantedStatus(true); } Player currentPlayer = WorldHandler.instance.GetCurrentPlayer(); currentPlayer.ResetHP(); if (currentPlayer.AmountOfCuffs() > 0) { currentPlayer.RemoveAllCuffs((CuffMissileLauncher)null); } }); base.ScrollView.AddButton((PhoneButton)(object)val); val = PhoneUIUtility.CreateSimpleButton("Grind Debt..."); SimplePhoneButton obj8 = val; ((PhoneButton)obj8).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj8).OnConfirm, (Action)delegate { ((App)this).MyPhone.OpenApp(typeof(AppGrindDebt)); }); base.ScrollView.AddButton((PhoneButton)(object)val); val = PhoneUIUtility.CreateSimpleButton("Set FPS Limit..."); SimplePhoneButton obj9 = val; ((PhoneButton)obj9).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj9).OnConfirm, (Action)delegate { ((App)this).MyPhone.OpenApp(typeof(AppFPSLimit)); }); base.ScrollView.AddButton((PhoneButton)(object)val); val = PhoneUIUtility.CreateSimpleButton("Extras..."); SimplePhoneButton obj10 = val; ((PhoneButton)obj10).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj10).OnConfirm, (Action)delegate { ((App)this).MyPhone.OpenApp(typeof(AppExtras)); }); base.ScrollView.AddButton((PhoneButton)(object)val); val = PhoneUIUtility.CreateSimpleButton("Set Respawn"); SimplePhoneButton obj11 = val; ((PhoneButton)obj11).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj11).OnConfirm, (Action)delegate { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) Stage currentStage2 = Core.Instance.BaseModule.CurrentStage; Vector3 position = ((Component)((App)this).MyPhone.player).transform.position; Quaternion rotation = ((Component)((App)this).MyPhone.player).transform.rotation; bool usingEquippedMovestyle = ((App)this).MyPhone.player.usingEquippedMovestyle; ScoreAttackSaveData.Instance.SetRespawnPoint(currentStage2, position, rotation, usingEquippedMovestyle); UpdateGoToRespawnButton(); }); base.ScrollView.AddButton((PhoneButton)(object)val); goToRespawnButton = (PhoneButton)(object)PhoneUIUtility.CreateSimpleButton("Go to Respawn"); PhoneButton obj12 = goToRespawnButton; obj12.OnConfirm = (Action)Delegate.Combine(obj12.OnConfirm, (Action)delegate { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) Stage currentStage = Core.Instance.BaseModule.CurrentStage; ScoreAttackSaveData.Instance.GetRespawnPoint(currentStage)?.ApplyToPlayer(((App)this).MyPhone.player); }); } public void Update() { wantedManager = WantedManager.instance; } public bool PlayerIsWanted() { if ((Object)(object)wantedManager != (Object)null) { return wantedManager.Wanted; } return false; } public void StopWantedStatus() { if (PlayerIsWanted()) { wantedManager.StopPlayerWantedStatus(true); } } } public class AppScoreAttackStageSelect : CustomApp { public override bool Available => false; public static void Initialize() { PhoneAPI.RegisterApp<AppScoreAttackStageSelect>("stage select", (Sprite)null); } public override void OnAppInit() { ((CustomApp)this).OnAppInit(); ((CustomApp)this).CreateIconlessTitleBar("Stage Select", 80f); base.ScrollView = PhoneScrollView.Create((CustomApp)(object)this, 275f, 1600f); SimplePhoneButton val = CreateStageButton("Hideout", (Stage)5); base.ScrollView.AddButton((PhoneButton)(object)val); val = CreateStageButton("Versum Hill", (Stage)4); base.ScrollView.AddButton((PhoneButton)(object)val); val = CreateStageButton("Millennium Square", (Stage)11); base.ScrollView.AddButton((PhoneButton)(object)val); val = CreateStageButton("Brink Terminal", (Stage)12); base.ScrollView.AddButton((PhoneButton)(object)val); val = CreateStageButton("Millennium Mall", (Stage)6); base.ScrollView.AddButton((PhoneButton)(object)val); val = CreateStageButton("Mataan", (Stage)7); base.ScrollView.AddButton((PhoneButton)(object)val); val = CreateStageButton("Pyramid Island", (Stage)9); base.ScrollView.AddButton((PhoneButton)(object)val); val = CreateStageButton("Police Station", (Stage)8); base.ScrollView.AddButton((PhoneButton)(object)val); } private SimplePhoneButton CreateStageButton(string label, Stage stage) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) SimplePhoneButton val = PhoneUIUtility.CreateSimpleButton(label); ((PhoneButton)val).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val).OnConfirm, (Action)delegate { //IL_0011: Unknown result type (might be due to invalid IL or missing references) Core.Instance.BaseModule.StageManager.ExitCurrentStage(stage, (Stage)(-1)); }); return val; } } public class BannedMods : BaseUnityPlugin { private void Awake() { if (IsAdvantageousModLoaded()) { Core.Instance.UIManager.ShowNotification("The score attack app is not compatible with TrickGod!", Array.Empty<string>()); } } public static bool IsAdvantageousModLoaded() { return Chainloader.PluginInfos.ContainsKey("TrickGod"); } } public enum GhostDisplayMode { Hide, Show } public enum GhostWarpMode { Respawn, ToGhost } public class AppGhost : CustomApp { public override bool Available => false; public static void Initialize() { PhoneAPI.RegisterApp<AppGhost>("ghost", (Sprite)null); } public override void OnAppInit() { //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) ((CustomApp)this).OnAppInit(); ((CustomApp)this).CreateIconlessTitleBar("Ghosts\n<size=50%>Challenge Ghosts!</size>", 80f); base.ScrollView = PhoneScrollView.Create((CustomApp)(object)this, 275f, 1600f); SimplePhoneButton val = PhoneUIUtility.CreateSimpleButton("Load Ghost..."); SimplePhoneButton obj = val; ((PhoneButton)obj).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj).OnConfirm, (Action)delegate { if (GhostSaveData.Instance.GhostDisplayMode == GhostDisplayMode.Hide) { Debug.Log((object)"[ScoreAttack] Ghost display mode set to Hide. Not letting the player enter this menu."); Core.Instance.UIManager.ShowNotification("Ghost display mode is set to <color=red>hide</color>.\nPlease enable it to use ghost playback during runs.", Array.Empty<string>()); } else { ((App)this).MyPhone.OpenApp(typeof(AppGhostList)); } }); base.ScrollView.AddButton((PhoneButton)(object)val); val = PhoneUIUtility.CreateSimpleButton("Delete Ghost..."); SimplePhoneButton obj2 = val; ((PhoneButton)obj2).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj2).OnConfirm, (Action)delegate { ((App)this).MyPhone.OpenApp(typeof(AppGhostDelete)); }); base.ScrollView.AddButton((PhoneButton)(object)val); val = PhoneUIUtility.CreateSimpleButton("Ghost Settings..."); SimplePhoneButton obj3 = val; ((PhoneButton)obj3).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj3).OnConfirm, (Action)delegate { ((App)this).MyPhone.OpenApp(typeof(AppGhostSettings)); }); base.ScrollView.AddButton((PhoneButton)(object)val); AddEnumButton("Display Ghosts", () => GhostSaveData.Instance.GhostDisplayMode, GetNextDisplayMode, delegate(GhostDisplayMode m) { GhostSaveData.Instance.GhostDisplayMode = m; }); AddEnumButton("Start Position", () => GhostSaveData.Instance.GhostWarpMode, GetNextWarpMode, delegate(GhostWarpMode m) { GhostSaveData.Instance.GhostWarpMode = m; }); val = PhoneUIUtility.CreateSimpleButton("Cancel Run"); SimplePhoneButton obj4 = val; ((PhoneButton)obj4).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj4).OnConfirm, (Action)delegate { Debug.Log((object)"Cancelling Active Battle..."); ScoreAttackManager.LoadedExternalGhost = null; ScoreAttackManager.ExternalGhostLoadedFromGhostList = false; if (ScoreAttackEncounter.IsScoreAttackActive()) { ScoreAttackEncounter scoreAttackEncounter = Object.FindObjectOfType<ScoreAttackEncounter>(); scoreAttackEncounter.EndScoreAttack(); Core.Instance.SaveManager.SaveCurrentSaveSlot(); } else { Core.Instance.UIManager.ShowNotification("There is no ongoing Score Battle run!", Array.Empty<string>()); } }); val.LabelUnselectedColor = Color.black; val.LabelSelectedColor = Color.red; base.ScrollView.AddButton((PhoneButton)(object)val); } private void AddEnumButton<T>(string label, Func<T> getCurrent, Func<T, T> getNext, Action<T> setValue) { T val = getCurrent(); SimplePhoneButton button = PhoneUIUtility.CreateSimpleButton(label + "\n<size=50%><color=" + GetColorForValue(val) + ">" + FormatEnum(val) + "</color></size>"); SimplePhoneButton obj = button; ((PhoneButton)obj).OnConfirm = (Action)Delegate.Combine(((PhoneButton)obj).OnConfirm, (Action)delegate { T arg = getCurrent(); T val2 = getNext(arg); setValue(val2); ((TMP_Text)button.Label).SetText(label + "\n<size=50%><color=" + GetColorForValue(val2) + ">" + FormatEnum(val2) + "</color></size>", true); }); base.ScrollView.AddButton((PhoneButton)(object)button); } private static string FormatEnum<T>(T val) { T val2 = val; T val3 = val2; if (val3 is GhostDisplayMode) { object obj = val3; switch ((GhostDisplayMode)((obj is GhostDisplayMode) ? obj : null)) { case GhostDisplayMode.Hide: return "Hide Ghost Playback During Runs"; case GhostDisplayMode.Show: return "Show Ghost Playback During Runs"; } } else if (val3 is GhostWarpMode) { object obj2 = val3; switch ((GhostWarpMode)((obj2 is GhostWarpMode) ? obj2 : null)) { case GhostWarpMode.Respawn: return "Your Respawn Point"; case GhostWarpMode.ToGhost: return "Ghost Start Point"; } } return val.ToString(); } private static string GetColorForValue<T>(T val) { if (val is GhostDisplayMode) { object obj = val; switch ((GhostDisplayMode)((obj is GhostDisplayMode) ? obj : null)) { case GhostDisplayMode.Hide: return "red"; case GhostDisplayMode.Show: return "green"; } } else if (val is GhostWarpMode) { object obj2 = val; GhostWarpMode ghostWarpMode = (GhostWarpMode)((obj2 is GhostWarpMode) ? obj2 : null); if ((uint)ghostWarpMode <= 1u) { return "orange"; } } return "white"; } private static GhostDisplayMode GetNextDisplayMode(GhostDisplayMode mode) { return (GhostDisplayMode)((int)(mode + 1) % Enum.GetValues(typeof(GhostDisplayMode)).Length); } private static GhostWarpMode GetNextWarpMo