diff --git a/FC AP.csproj b/FC AP.csproj index 430a5a2..140fc72 100644 --- a/FC AP.csproj +++ b/FC AP.csproj @@ -10,6 +10,7 @@ FC_AP FC AP v4.7.2 + 10.0 512 true diff --git a/Indicator.cs b/Indicator.cs index f81d877..1eacbea 100644 --- a/Indicator.cs +++ b/Indicator.cs @@ -1,6 +1,4 @@ -using Assets.Scripts.GameCore.HostComponent; -using Assets.Scripts.PeroTools.Commons; -using System; +using System; using UnityEngine; using UnityEngine.UI; using static MuseDashMirror.BattleComponent; @@ -9,121 +7,130 @@ using static MuseDashMirror.UICreate.Fonts; using static MuseDashMirror.UICreate.TextGameObjectCreate; -namespace FC_AP +namespace FC_AP; +internal class Indicator : MonoBehaviour { - internal class Indicator : MonoBehaviour + public Indicator(IntPtr intPtr) : base(intPtr) { - internal static int GreatNum { get; set; } - internal static int MissNum { get; set; } - internal static int CurrentMissNum { get; set; } - internal static int GhostMiss { get; set; } - internal static int CollectableNoteMiss { get; set; } - private static GameObject AP { get; set; } - private static GameObject FC { get; set; } - private static GameObject Miss { get; set; } - - public Indicator(IntPtr intPtr) : base(intPtr) - { - } + } + + private static GameObject AP { get; set; } + private static GameObject FC { get; set; } + private static GameObject Miss { get; set; } + + private void Start() + { + LoadFonts(); + } + + private void OnDestroy() + { + AP = null; + FC = null; + Miss = null; + UnloadFonts(); + } + + internal static void SetAPToggle() + { + CreateCanvas("Indicator Canvas", "Camera_2D"); + AP = SetGameObject("AP", Color.yellow, "AP"); + } + + internal static void UpdateFCGameObject() + { + // if no great, return + if (GreatNum == 0) return; - private void Start() + // if has miss, don't need update FC + if (TotalMissNum != 0) return; + + if (FC is null) { - LoadFonts(); + Destroy(AP); + FC = SetGameObject("FC", Blue, "FC " + GreatNum + "G"); } - - private void Update() + else { - // if indicator is enabled and not set, also is in game - if (Save.Settings.FC_APEnabled && AP == null && FC == null && Miss == null && IsInGame) - { - CreateCanvas("Indicator Canvas", "Camera_2D"); - AP = SetGameObject("AP", Color.yellow, "AP"); - } - - //if AP is set, FC is not set and get a great - if (AP != null && FC == null && Miss == null && Great != 0) - { - Destroy(AP); - //if not AP then it must be 1 Great - GreatNum = 1; - FC = SetGameObject("FC", Blue, "FC " + GreatNum + "G"); - } + FC.GetComponent().text = "FC " + GreatNum + "G"; + } + } - //if AP is set, FC is not set and ghost not count as miss - if (AP != null && FC == null && GhostMiss != 0) - { - Destroy(AP); - FC = SetGameObject("FC", Blue, "FC"); - } + internal static void UpdateMissGameObject() + { + // if no miss, return + if (TotalMissNum == 0) return; - //if AP is set, FC is not set and collectable note not count as miss - if (AP != null && FC == null && CollectableNoteMiss != 0) - { - Destroy(AP); - FC = SetGameObject("FC", Blue, "FC"); - } + Destroy(AP); + Destroy(FC); - //if AP or FC is set, Miss doesn't set and get normal miss or ghost miss when enabled or collectable note miss when enabled - if (Miss == null && (AP != null || FC != null) && CurrentMissNum != 0) - { - Destroy(AP); - Destroy(FC); - MissNum = 1; - if (GreatNum == 0) - { - Miss = SetGameObject("Miss", Silver, MissNum + "M"); - } - else - { - Miss = SetGameObject("Miss", Silver, MissNum + "M " + GreatNum + "G"); - } - } + int currentMiss; + // if collectable note not count as miss and FC is null + if (!Save.Settings.CollectableMissEnabled && CollectableNoteMissNum != 0) + { + currentMiss = NormalMissNum + GhostMissNum; + if (Miss is null) + FC = SetFC(); + } - //if FC or Miss is set and great number are not correct then +1 - if (GreatNum < Singleton.instance.m_GreatResult) - { - GreatNum++; - if (FC != null) - { - FC.GetComponent().text = "FC " + GreatNum + "G"; - } - if (Miss != null) - { - Miss.GetComponent().text = MissNum + "M " + GreatNum + "G"; - } - } + // if collectable note not count as miss and FC is null + else if (!Save.Settings.GhostMissEnabled && GhostMissNum != 0) + { + currentMiss = NormalMissNum + CollectableNoteMissNum; + if (Miss is null) + FC = SetFC(); + } - // if Miss is set and miss number are not correct then +1 - if (MissNum < CurrentMissNum) - { - MissNum++; - if (Miss != null) - { - if (GreatNum == 0) - { - Miss.GetComponent().text = MissNum + "M"; - } - else - { - Miss.GetComponent().text = MissNum + "M " + GreatNum + "G"; - } - } - } + // if collectable note and ghost not count as miss and FC is null + else if (!Save.Settings.CollectableMissEnabled && CollectableNoteMissNum != 0 && !Save.Settings.GhostMissEnabled && GhostMissNum != 0) + { + currentMiss = NormalMissNum; + if (Miss is null) + FC = SetFC(); + } + else + { + currentMiss = TotalMissNum; + Miss ??= SetMiss(currentMiss); + } - //Destroy gameobject in result screen - if (GameObject.Find("PnlVictory_2D") != null) + if (Miss is null) + { + if (currentMiss > NormalMissNum || NormalMissNum > 0) { - Destroy(AP); Destroy(FC); - Destroy(Miss); + Miss = SetMiss(currentMiss); } } - - private static GameObject SetGameObject(string name, Color color, string text) + else { - var gameobject = CreateTextGameObject("Indicator Canvas", name, text, TextAnchor.UpperLeft, true, new Vector3(-102.398f, 367.2864f, 0f), new Vector2(960, 216), 100, SnapsTasteFont, color); - return gameobject; + Miss.GetComponent().text = GreatNum == 0 ? currentMiss + "M" : currentMiss + "M " + GreatNum + "G"; } } + + private static GameObject SetFC() + { + var fc = GreatNum == 0 ? SetGameObject("FC", Blue, "FC") : SetGameObject("FC", Blue, "FC " + GreatNum + "G"); + return fc; + } + + private static GameObject SetMiss(int missNum) + { + var miss = GreatNum == 0 ? SetGameObject("Miss", Silver, missNum + "M") : SetGameObject("Miss", Silver, missNum + "M " + GreatNum + "G"); + return miss; + } + + internal static void DestroyGameObject() + { + Destroy(AP); + Destroy(FC); + Destroy(Miss); + } + + private static GameObject SetGameObject(string name, Color color, string text) + { + var gameobject = CreateTextGameObject("Indicator Canvas", name, text, TextAnchor.UpperLeft, true, new Vector3(-102.398f, 367.2864f, 0f), new Vector2(960, 216), 100, SnapsTasteFont, color); + return gameobject; + } } \ No newline at end of file diff --git a/Main.cs b/Main.cs index 337895c..f41fe49 100644 --- a/Main.cs +++ b/Main.cs @@ -1,62 +1,53 @@ -using Assets.Scripts.UI.Panels; -using Il2CppSystem.IO; +using Il2CppSystem.IO; using MelonLoader; -using MuseDashMirror; -using MuseDashMirror.CommonPatches; -using MuseDashMirror.UICreate; -using System; using Tomlet; using UnhollowerRuntimeLib; using UnityEngine; +using static MuseDashMirror.CommonPatches.PatchEvents; +using static MuseDashMirror.BattleComponent; +using static MuseDashMirror.SceneInfo; +using static FC_AP.Indicator; -namespace FC_AP +namespace FC_AP; + +public class Main : MelonMod { - public class Main : MelonMod + public override void OnInitializeMelon() { - public override void OnInitializeMelon() - { - Save.Load(); - PatchEvents.PnlMenuEvent += new Action(Patch.PnlMenuPostfix); - PatchEvents.SwitchLanguagesEvent += new Action(Patch.SwitchLanguagesPostfix); - PatchEvents.MenuSelectEvent += new Action(DisableToggle); - SceneInfo.EnterGameScene += new Action(RegisterGameObject); - SceneInfo.ExitGameScene += new Action(Reset); - LoggerInstance.Msg("FC/AP indicator is loaded!"); - } + Save.Load(); + PnlMenuEvent += Patch.PnlMenuPostfix; + SwitchLanguagesEvent += Patch.SwitchLanguagesPostfix; + MenuSelectEvent += DisableToggle; + EnterGameScene += RegisterGameObject; + GameStartEvent += SetAPToggle; + OnVictoryEvent += DestroyGameObject; + AddScoreEvent += UpdateFCGameObject; + MissCubeEvent += UpdateMissGameObject; + LoggerInstance.Msg("FC/AP indicator is loaded!"); + } - public override void OnDeinitializeMelon() - { - File.WriteAllText(Path.Combine("UserData", "FC AP.cfg"), TomletMain.TomlStringFrom(Save.Settings)); - } + public override void OnDeinitializeMelon() + { + File.WriteAllText(Path.Combine("UserData", "FC AP.cfg"), TomletMain.TomlStringFrom(Save.Settings)); + } - private void RegisterGameObject() - { - ClassInjector.RegisterTypeInIl2Cpp(); - GameObject gameObject = new GameObject("Indicator"); - UnityEngine.Object.DontDestroyOnLoad(gameObject); - gameObject.AddComponent(); - } + private void RegisterGameObject() + { + if (!Save.Settings.FC_APEnabled) return; + ClassInjector.RegisterTypeInIl2Cpp(); + var gameObject = new GameObject("Indicator"); + gameObject.AddComponent(); + } - private void Reset() + private void DisableToggle(int listIndex, int index, bool isOn) + { + if (listIndex == 0 && index == 0 && isOn) { - Indicator.GreatNum = 0; - Indicator.CurrentMissNum = 0; - Indicator.MissNum = 0; - Indicator.GhostMiss = 0; - Indicator.CollectableNoteMiss = 0; - Fonts.UnloadFonts(); + Patch.FC_APToggle.SetActive(true); } - - private void DisableToggle(int listIndex, int index, bool isOn) + else { - if (listIndex == 0 && index == 0 && isOn) - { - Patch.FC_APToggle.SetActive(true); - } - else - { - Patch.FC_APToggle.SetActive(false); - } + Patch.FC_APToggle.SetActive(false); } } } \ No newline at end of file diff --git a/MelonBuildInfo.cs b/MelonBuildInfo.cs index f8b7ace..5821662 100644 --- a/MelonBuildInfo.cs +++ b/MelonBuildInfo.cs @@ -1,17 +1,16 @@ -namespace FC_AP +namespace FC_AP; + +internal static class MelonBuildInfo { - internal static class MelonBuildInfo - { - public const string Name = "FC AP indicator"; + public const string Name = "FC AP indicator"; - public const string Description = "Indicators for whether you are on FC/AP pace"; + public const string Description = "Indicators for whether you are on FC/AP pace"; - public const string Author = "lxy"; + public const string Author = "lxy"; - public const string Company = null; + public const string Company = null; - public const string Version = "1.5.4"; + public const string Version = "1.6.0"; - public const string DownloadLink = "https://github.com/MDModsDev/FC-AP-Indicator/releases/latest"; - } + public const string DownloadLink = "https://github.com/MDModsDev/FC-AP-Indicator/releases/latest"; } \ No newline at end of file diff --git a/Patch.cs b/Patch.cs index aa96fee..fa4f91e 100644 --- a/Patch.cs +++ b/Patch.cs @@ -1,120 +1,36 @@ -using Assets.Scripts.GameCore.HostComponent; -using Assets.Scripts.PeroTools.Commons; -using Assets.Scripts.UI.Panels; -using FormulaBase; -using GameLogic; -using HarmonyLib; +using Assets.Scripts.UI.Panels; using MuseDashMirror.UICreate; using UnityEngine; using UnityEngine.UI; -namespace FC_AP -{ - internal static class Patch - { - internal static GameObject FC_APToggle { get; set; } +namespace FC_AP; - internal static unsafe void SwitchLanguagesPostfix() - { - fixed (bool* fc_apEnabled = &Save.Settings.FC_APEnabled) - { - FC_APToggle.transform.Find("Txt").GetComponent().text = "FC/AP On/Off"; - } - } +internal static class Patch +{ + internal static GameObject FC_APToggle { get; set; } - internal static unsafe void PnlMenuPostfix(PnlMenu __instance) - { - GameObject vSelect = null; - foreach (Il2CppSystem.Object @object in __instance.transform.parent.parent.Find("Forward")) - { - Transform transform = @object.Cast(); - if (transform.name == "PnlVolume") - { - vSelect = transform.gameObject; - } - } - fixed (bool* fc_apEnabled = &Save.Settings.FC_APEnabled) - { - if (FC_APToggle == null && vSelect != null) - { - FC_APToggle = ToggleCreate.CreatePnlMenuToggle("FC AP Indicator Toggle", fc_apEnabled, "FC/AP On/Off"); - } - } - } + internal static void SwitchLanguagesPostfix() + { + FC_APToggle.transform.Find("Txt").GetComponent().text = "FC/AP On/Off"; } - // Hold miss - [HarmonyPatch(typeof(BattleEnemyManager), "SetPlayResult")] - internal static class SetPlayResultPatch + internal static unsafe void PnlMenuPostfix(PnlMenu __instance) { - private static void Postfix(int idx, byte result, bool isMulStart = false, bool isMulEnd = false, bool isLeft = false) + GameObject vSelect = null; + foreach (var @object in __instance.transform.parent.parent.Find("Forward")) { - MusicData musicDataByIdx = Singleton.instance.GetMusicDataByIdx(idx); - if (result == 1 && musicDataByIdx.noteData.type == 3) + var transform = @object.Cast(); + if (transform.name == "PnlVolume") { - Indicator.CurrentMissNum++; + vSelect = transform.gameObject; } } - } - [HarmonyPatch(typeof(GameMissPlay), "MissCube")] - internal static class MissCubePatch - { - private static void Postfix(int idx, decimal currentTick) + fixed (bool* fc_apEnabled = &Save.Settings.FC_APEnabled) { - int result = Singleton.instance.GetPlayResult(idx); - MusicData musicDataByIdx = Singleton.instance.GetMusicDataByIdx(idx); - if (result == 0) - { - // air ghost miss - if (musicDataByIdx.noteData.type == 4) - { - Indicator.GhostMiss++; - if (Save.Settings.GhostMissEnabled) - { - Indicator.CurrentMissNum++; - } - } - // air collectable note miss - else if (musicDataByIdx.noteData.type == 7) - { - Indicator.CollectableNoteMiss++; - if (Save.Settings.CollectableMissEnabled) - { - Indicator.CurrentMissNum++; - } - } - // normal miss - else if (musicDataByIdx.noteData.type != 2 && !musicDataByIdx.isDouble) - { - Indicator.CurrentMissNum++; - } - } - if (result == 1) + if (FC_APToggle == null && vSelect != null) { - // ground ghost miss - if (musicDataByIdx.noteData.type == 4) - { - Indicator.GhostMiss++; - if (Save.Settings.GhostMissEnabled) - { - Indicator.CurrentMissNum++; - } - } - // ground collectable note miss - else if (musicDataByIdx.noteData.type == 7) - { - Indicator.CollectableNoteMiss++; - if (Save.Settings.CollectableMissEnabled) - { - Indicator.CurrentMissNum++; - } - } - // normal miss - else - { - Indicator.CurrentMissNum++; - } + FC_APToggle = ToggleCreate.CreatePnlMenuToggle("FC AP Indicator Toggle", fc_apEnabled, "FC/AP On/Off"); } } } diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs index f9f235e..9225e1e 100644 --- a/Properties/AssemblyInfo.cs +++ b/Properties/AssemblyInfo.cs @@ -1,16 +1,17 @@ -using FC_AP; -using MelonLoader; -using System.Reflection; +using System.Reflection; using System.Runtime.InteropServices; +using MelonLoader; +using static FC_AP.MelonBuildInfo; +using Main = FC_AP.Main; // 有关程序集的一般信息由以下 // 控制。更改这些特性值可修改 // 与程序集关联的信息。 -[assembly: AssemblyTitle(MelonBuildInfo.Name)] -[assembly: AssemblyDescription(MelonBuildInfo.Description)] +[assembly: AssemblyTitle(Name)] +[assembly: AssemblyDescription(Description)] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] -[assembly: AssemblyProduct(MelonBuildInfo.Name)] +[assembly: AssemblyProduct(Name)] [assembly: AssemblyCopyright("Copyright © 2022")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] @@ -33,7 +34,7 @@ //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值 //通过使用 "*",如下所示: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion(MelonBuildInfo.Version)] -[assembly: AssemblyFileVersion(MelonBuildInfo.Version)] -[assembly: MelonInfo(typeof(FC_AP.Main), MelonBuildInfo.Name, MelonBuildInfo.Version, MelonBuildInfo.Author)] +[assembly: AssemblyVersion(Version)] +[assembly: AssemblyFileVersion(Version)] +[assembly: MelonInfo(typeof(Main), Name, Version, Author)] [assembly: MelonGame("PeroPeroGames", "MuseDash")] \ No newline at end of file diff --git a/Save.cs b/Save.cs index b39a0c1..5943da6 100644 --- a/Save.cs +++ b/Save.cs @@ -2,41 +2,41 @@ using Tomlet; using Tomlet.Attributes; -namespace FC_AP +namespace FC_AP; + +internal static class Save { - internal static class Save - { - private static Data Default = new Data(true, true, true); - internal static Data Settings; + private static readonly Data Default = new(true, true, true); + internal static Data Settings; - public static void Load() + public static void Load() + { + if (!File.Exists(Path.Combine("UserData", "FC AP.cfg"))) { - if (!File.Exists(Path.Combine("UserData", "FC AP.cfg"))) - { - string defaultConfig = TomletMain.TomlStringFrom(Default); - File.WriteAllText(Path.Combine("UserData", "FC AP.cfg"), defaultConfig); - } - string Datas = File.ReadAllText(Path.Combine("UserData", "FC AP.cfg")); - Settings = TomletMain.To(Datas); + var defaultConfig = TomletMain.TomlStringFrom(Default); + File.WriteAllText(Path.Combine("UserData", "FC AP.cfg"), defaultConfig); } + + var datas = File.ReadAllText(Path.Combine("UserData", "FC AP.cfg")); + Settings = TomletMain.To(datas); } +} - internal struct Data - { - [TomlPrecedingComment("Whether the FC AP indicator is enabled")] - internal bool FC_APEnabled; +internal struct Data +{ + [TomlPrecedingComment("Whether the FC AP indicator is enabled")] + internal bool FC_APEnabled; - [TomlPrecedingComment("Whether delete FC indicator when missing a ghost")] - internal bool GhostMissEnabled; + [TomlPrecedingComment("Whether delete FC indicator when missing a ghost")] + internal bool GhostMissEnabled; - [TomlPrecedingComment("Whether delete FC indicator when missing a collectable notes")] - internal bool CollectableMissEnabled; + [TomlPrecedingComment("Whether delete FC indicator when missing a collectable notes")] + internal bool CollectableMissEnabled; - internal Data(bool fc_apEnabled, bool ghostMiss, bool collectableMiss) - { - FC_APEnabled = fc_apEnabled; - GhostMissEnabled = ghostMiss; - CollectableMissEnabled = collectableMiss; - } + internal Data(bool fc_apEnabled, bool ghostMissEnabled, bool collectableMissEnabled) + { + FC_APEnabled = fc_apEnabled; + GhostMissEnabled = ghostMissEnabled; + CollectableMissEnabled = collectableMissEnabled; } } \ No newline at end of file