-
Notifications
You must be signed in to change notification settings - Fork 51
又力大砖飞了一个模组,但是直接在fade模组上修改的。经过1.55+版本测试正常。 #107
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 12 commits
606e372
e514c7b
5acfb37
9af16af
a0f4e65
7b69c29
692d10b
17c953e
f2917f5
ec12ce6
80e835c
ebda3da
0ca1e8f
b32ca44
58b9fe8
1985afb
055469f
1f43eac
a76e507
f47d540
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,118 +4,230 @@ | |
| using Process; | ||
| using UnityEngine; | ||
| using UnityEngine.UI; | ||
| using System.Reflection; | ||
| using System; | ||
| using System.IO; | ||
| using Manager; | ||
| using MelonLoader; | ||
| using System.Collections.Generic; | ||
| using System.Text.RegularExpressions; | ||
| using Monitor; | ||
|
|
||
| namespace AquaMai.Mods.Fancy; | ||
|
|
||
| [ConfigSection( | ||
| name: "转场动画", | ||
| [ConfigSection(name: "转场动画PLUS", | ||
| en: "Set Fade Animation", | ||
| zh: "修改转场动画为其他变种" | ||
| )] | ||
|
|
||
| zh: "修改转场动画为其他变种")] | ||
| public class SetFade | ||
| { | ||
| [ConfigEntry( | ||
| name: "转场类型", | ||
| en: "Type: Non-Plus 0, Plus 1. (If SDEZ 1.60 can choose Festa 2)", | ||
| zh: "类型: Non-Plus 0, Plus 1. (SDEZ 1.60 限定可选 Festa 2)")] | ||
| [ConfigEntry(name: "转场类型", zh: "0:Normal, 1:Plus, 2:Festa(仅限1.60+)")] | ||
| public static readonly int FadeType = 0; | ||
|
|
||
| [ConfigEntry(name: "[仅限1.55+]启用特殊KLD转场,需要下载额外JSON文件", zh: "仅在配置过的歌曲启用KLD转场。1.50及以下版本无效。1.50我不想适配了如果有人想适配可以dd我)@力大砖飞")] | ||
Haisairova-Official marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| public static readonly bool isKLDEnabled = true; | ||
|
|
||
| private static readonly string JSONDir = "LocalAssets"; | ||
| private static readonly string JSONFileName = "CommonFadeList.json"; | ||
Haisairova-Official marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| private static bool isInitialized = false; | ||
| private static bool isResourcePatchEnabled = false; | ||
| private static bool _isInitialized = false; | ||
| private static Sprite[] subBGs = new Sprite[3]; | ||
| private static List<CommonFadeEntry> cachedEntries = new List<CommonFadeEntry>(); | ||
|
|
||
| // 计数锁定逻辑变量 | ||
| private static int _kldRemainingCharges = 0; | ||
| private static CommonFadeEntry _activeKldConfig = null; | ||
|
|
||
| public class CommonFadeEntry { public int ID; public int isBlack; public int Type; public int FadeType; } | ||
|
|
||
| [HarmonyPrepare] | ||
| public static bool SetFade_Prepare() | ||
| public static bool Prepare() | ||
| { | ||
| SetFade_Initialize(); | ||
| if (!isInitialized) | ||
| MelonLogger.Msg("[SetFade] Initialization failed, this patch will not be applied."); | ||
| return isInitialized; | ||
| if (_isInitialized) return true; | ||
| subBGs[0] = Resources.Load<Sprite>("Process/ChangeScreen/Sprites/Sub_01"); | ||
| subBGs[1] = Resources.Load<Sprite>("Process/ChangeScreen/Sprites/Sub_02"); | ||
| subBGs[2] = (GameInfo.GameVersion >= 26000) ? Resources.Load<Sprite>("Process/ChangeScreen/Sprites/Sub_03") : subBGs[0]; | ||
|
Comment on lines
+53
to
+55
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 新的 建议恢复对加载资源的空值检查,并在加载失败时记录错误日志,以提高模组的健壮性。 subBGs[0] = Resources.Load<Sprite>("Process/ChangeScreen/Sprites/Sub_01");
subBGs[1] = Resources.Load<Sprite>("Process/ChangeScreen/Sprites/Sub_02");
subBGs[2] = (GameInfo.GameVersion >= 26000) ? Resources.Load<Sprite>("Process/ChangeScreen/Sprites/Sub_03") : subBGs[0];
if (subBGs[0] == null || subBGs[1] == null || (GameInfo.GameVersion >= 26000 && subBGs[2] == null))
{
MelonLogger.Error("[SetFade] Failed to load one or more SubBG sprites. The mod may not function correctly.");
} |
||
| LoadJsonManual(); | ||
| _isInitialized = true; | ||
| return true; | ||
| } | ||
|
|
||
| private static void SetFade_Initialize() | ||
| // --- 1. 实时监听选曲:充能点 --- | ||
| [HarmonyPostfix] | ||
| [HarmonyPatch(typeof(MusicSelectMonitor), "UpdateRivalScore")] | ||
| [HarmonyPatch(typeof(MusicSelectMonitor), "SetRivalScore")] | ||
| public static void OnMusicSelectionChanged(MusicSelectProcess ____musicSelect) | ||
clansty marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| { | ||
| bool areSubBGsValid; | ||
| bool isFadeTypeValid; | ||
| if (!isKLDEnabled || ____musicSelect == null) return; | ||
|
|
||
| if (GameInfo.GameVersion != 26000) | ||
| { | ||
| subBGs[0] = Resources.Load<Sprite>("Process/ChangeScreen/Sprites/Sub_01"); | ||
| subBGs[1] = Resources.Load<Sprite>("Process/ChangeScreen/Sprites/Sub_02"); | ||
| areSubBGsValid = subBGs[0] != null && subBGs[1] != null; | ||
| isFadeTypeValid = FadeType == 0 || FadeType == 1; | ||
| } | ||
| else | ||
| { | ||
| subBGs[0] = Resources.Load<Sprite>("Process/ChangeScreen/Sprites/Sub_01"); | ||
| subBGs[1] = Resources.Load<Sprite>("Process/ChangeScreen/Sprites/Sub_02"); | ||
| subBGs[2] = Resources.Load<Sprite>("Process/ChangeScreen/Sprites/Sub_03"); | ||
| areSubBGsValid = subBGs[0] != null && subBGs[1] != null && subBGs[2] != null; | ||
| isFadeTypeValid = FadeType == 0 || FadeType == 1 || FadeType == 2; | ||
| } | ||
|
|
||
| if (!areSubBGsValid) | ||
| MelonLogger.Msg($"[SwitchFade] Couldn't find SubBG sprites."); | ||
|
|
||
| if (!isFadeTypeValid) | ||
| MelonLogger.Msg($"[SwitchFade] Invalid FadeType."); | ||
|
|
||
| isInitialized = areSubBGsValid && isFadeTypeValid; | ||
| try { | ||
| var musicData = ____musicSelect.GetMusic(0)?.MusicData; | ||
| if (musicData != null) | ||
| { | ||
| var matched = cachedEntries.Find(e => e.ID == musicData.name.id); | ||
| if (matched != null) | ||
| { | ||
| if (_activeKldConfig != matched) | ||
| { | ||
| _activeKldConfig = matched; | ||
| _kldRemainingCharges = 3; // 锁定 3 次机会 | ||
|
||
| MelonLogger.Msg($"[SetFade] 目标锁定:ID {matched.ID},KLD 已充能 (3次)"); | ||
| } | ||
| } | ||
| else | ||
| { | ||
| _activeKldConfig = null; | ||
| _kldRemainingCharges = 0; | ||
| } | ||
| } | ||
| } catch { } | ||
|
||
| } | ||
|
|
||
|
|
||
| // 在显示转场前启用patch | ||
| // --- 2. 资源拦截触发 --- | ||
| [HarmonyPrefix] | ||
| [HarmonyPatch(typeof(FadeProcess), "OnStart")] | ||
| public static void FadeProcessOnStartPreFix() { isResourcePatchEnabled = true; } | ||
| [HarmonyPrefix] | ||
| [HarmonyPatch(typeof(AdvertiseProcess), "InitFade")] | ||
| public static void AdvertiseProcessInitFadePreFix() { isResourcePatchEnabled = true; } | ||
| [HarmonyPrefix] | ||
| [HarmonyPatch(typeof(NextTrackProcess), "OnStart")] | ||
| public static void NextTrackProcessOnStartPreFix() { isResourcePatchEnabled = true; } | ||
| public static void StartFadePrefix() | ||
| { | ||
| // 只有在有充能次数且配置存在时才开启拦截 | ||
| isResourcePatchEnabled = (_kldRemainingCharges > 0 && _activeKldConfig != null); | ||
| } | ||
|
|
||
| [HarmonyPrefix] | ||
| [HarmonyPatch(typeof(Resources), "Load", new[] { typeof(string), typeof(global::System.Type) })] | ||
| public static bool ResourcesLoadPrefix(ref string path, global::System.Type systemTypeInstance, ref UnityEngine.Object __result) | ||
| { | ||
| // 如果 KLD 拦截未激活,则执行普通重定向(力大砖飞) | ||
| if (!isResourcePatchEnabled) | ||
| { | ||
| if (FadeType >= 0 && FadeType <= 2) | ||
| { | ||
| string targetPath = $"Process/ChangeScreen/Prefabs/ChangeScreen_0{FadeType + 1}"; | ||
| if (path.StartsWith("Process/ChangeScreen/Prefabs/ChangeScreen_0") && path != targetPath) | ||
| { | ||
| if (GameInfo.GameVersion < 26000 && FadeType == 2) return true; | ||
| __result = Resources.Load(targetPath, systemTypeInstance); | ||
| return false; | ||
| } | ||
| } | ||
| return true; | ||
| } | ||
|
|
||
| // KLD 资源拦截 | ||
| if (path.StartsWith("Process/ChangeScreen/Prefabs/ChangeScreen_0")) | ||
| { | ||
| __result = Resources.Load("Process/Kaleidxscope/Prefab/UI_KLD_ChangeScreen", systemTypeInstance); | ||
| return false; | ||
| } | ||
| if (path.StartsWith("Process/ChangeScreen/Prefabs/Sub_ChangeScreen")) | ||
| { | ||
| __result = Resources.Load("Process/Kaleidxscope/Prefab/UI_KLD_Sub_ChangeScreen", systemTypeInstance); | ||
| return false; | ||
| } | ||
| return true; | ||
| } | ||
|
|
||
| // 在显示转场后禁用patch | ||
| // --- 3. 后置处理:消耗次数与动画播放 --- | ||
| [HarmonyPostfix] | ||
| [HarmonyPatch(typeof(FadeProcess), "OnStart")] | ||
| public static void FadeProcessOnStartPostFix(GameObject[] ___fadeObject) { ReplaceSubBG(___fadeObject); } | ||
| [HarmonyPostfix] | ||
| [HarmonyPatch(typeof(AdvertiseProcess), "InitFade")] | ||
| public static void AdvertiseProcessInitFadePostFix(GameObject[] ___fadeObject) { ReplaceSubBG(___fadeObject); } | ||
| [HarmonyPostfix] | ||
| [HarmonyPatch(typeof(NextTrackProcess), "OnStart")] | ||
| public static void NextTrackProcessOnStartPostFix(GameObject[] ___fadeObject) { ReplaceSubBG(___fadeObject); } | ||
|
|
||
|
|
||
| private static void ReplaceSubBG(GameObject[] fadeObjects) | ||
| public static void GlobalPostfix(GameObject[] ___fadeObject) | ||
| { | ||
| isResourcePatchEnabled = false; | ||
| foreach (var monitor in fadeObjects) | ||
| if (isResourcePatchEnabled && _activeKldConfig != null) | ||
| { | ||
| var subBG = monitor.transform.Find("Canvas/Sub/Sub_ChangeScreen(Clone)/Sub_BG").GetComponent<Image>(); | ||
| subBG.sprite = subBGs[FadeType]; | ||
| _kldRemainingCharges--; // 消耗一次 | ||
| MelonLogger.Msg($"[SetFade] 触发 KLD 成功,剩余次数: {_kldRemainingCharges}"); | ||
|
|
||
| if (___fadeObject != null) | ||
| { | ||
| foreach (var monitor in ___fadeObject) | ||
| DriveKLDAnimation(monitor, _activeKldConfig); | ||
| } | ||
| } | ||
| else if (___fadeObject != null) | ||
| { | ||
| // 普通重定向模式下的 SubBG 替换 | ||
| foreach (var monitor in ___fadeObject) | ||
| ReplaceSubBG(monitor); | ||
| } | ||
|
|
||
| isResourcePatchEnabled = false; // 关闭当次拦截锁 | ||
|
|
||
| // 次数耗尽清理配置 | ||
| if (_kldRemainingCharges <= 0) _activeKldConfig = null; | ||
| } | ||
|
|
||
| [HarmonyPrefix] | ||
| [HarmonyPatch(typeof(Resources), "Load", new[] { typeof(string), typeof(Type) })] | ||
| public static bool ResourcesLoadPrefix(ref string path, Type systemTypeInstance, ref UnityEngine.Object __result) | ||
| private static void ReplaceSubBG(GameObject monitor) | ||
| { | ||
| if (FadeType < 0 || FadeType >= subBGs.Length) return; | ||
| try { | ||
| var subBG = monitor.transform.Find("Canvas/Sub/Sub_ChangeScreen(Clone)/Sub_BG")?.GetComponent<Image>(); | ||
| if (subBG != null) subBG.sprite = subBGs[FadeType]; | ||
| } catch { } | ||
|
||
| } | ||
|
|
||
| private static void DriveKLDAnimation(GameObject monitor, CommonFadeEntry cfg) | ||
| { | ||
| if (isResourcePatchEnabled) | ||
| try | ||
| { | ||
| if (path.StartsWith("Process/ChangeScreen/Prefabs/ChangeScreen_0") && | ||
| path != $"Process/ChangeScreen/Prefabs/ChangeScreen_0{FadeType + 1}") // 避免无限递归 | ||
| var main = monitor.transform.Find("Canvas/Main/UI_KLD_ChangeScreen(Clone)"); | ||
| var sub = monitor.transform.Find("Canvas/Sub/UI_KLD_Sub_ChangeScreen(Clone)"); | ||
|
|
||
| // 根据你的要求修正动画映射 | ||
| string animName = cfg.FadeType switch { | ||
| 1 => "Out", | ||
| 2 => "Out_02", | ||
| 3 => "Out_03", | ||
| _ => "Out" | ||
| }; | ||
|
|
||
| if (main != null) | ||
| { | ||
| __result = Resources.Load($"Process/ChangeScreen/Prefabs/ChangeScreen_0{FadeType + 1}", systemTypeInstance); | ||
| return false; | ||
| var ctrl = main.GetComponent<KaleidxScopeFadeController>(); | ||
| if (ctrl != null) { | ||
| ctrl.SetBackGroundType(cfg.isBlack != 0 ? KaleidxScopeFadeController.BackGroundType.Black : KaleidxScopeFadeController.BackGroundType.Normal); | ||
| ctrl.SetSpriteType((KaleidxScopeFadeController.SpriteType)cfg.Type); | ||
| if (Enum.TryParse<KaleidxScopeFadeController.AnimState>(animName, out var state)) | ||
| ctrl.PlayAnimation(state); | ||
| } | ||
| } | ||
| } | ||
| return true; | ||
| if (sub != null) | ||
| { | ||
| var sCtrl = sub.GetComponent<KaleidxScopeSubFadeController>(); | ||
| if (sCtrl != null) { | ||
| sCtrl.SetBackGroundType(cfg.isBlack != 0 ? KaleidxScopeSubFadeController.BackGroundType.Black : KaleidxScopeSubFadeController.BackGroundType.Normal); | ||
| sCtrl.SetSpriteType((KaleidxScopeSubFadeController.SpriteType)cfg.Type); | ||
| sCtrl.PlayAnimation(KaleidxScopeSubFadeController.AnimState.In); | ||
| } | ||
| } | ||
| } catch { } | ||
|
||
| } | ||
|
|
||
| private static void LoadJsonManual() | ||
| { | ||
| try { | ||
| string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, JSONDir, JSONFileName); | ||
| if (!File.Exists(path)) return; | ||
| string content = File.ReadAllText(path); | ||
| cachedEntries.Clear(); | ||
| var matches = Regex.Matches(content, @"\{[^{}]+\}"); | ||
| foreach (Match m in matches) { | ||
| string raw = m.Value; | ||
| var e = new CommonFadeEntry { | ||
| ID = ExtractInt(raw, "ID"), | ||
| isBlack = ExtractInt(raw, "isBlack"), | ||
| Type = ExtractInt(raw, "Type"), | ||
| FadeType = ExtractInt(raw, "FadeType") | ||
| }; | ||
| if (e.ID > 0) cachedEntries.Add(e); | ||
| } | ||
| MelonLogger.Msg($"[SetFade] 共载入 {cachedEntries.Count} 条 KLD 特殊配置。"); | ||
| } catch (Exception e) { MelonLogger.Error($"[SetFade] JSON加载出错: {e.Message}"); } | ||
| } | ||
|
||
|
|
||
| private static int ExtractInt(string text, string key) { | ||
| var m = Regex.Match(text, $"\"{key}\"\\s*:\\s*\"?(\\d+)\"?"); | ||
|
||
| return (m.Success && int.TryParse(m.Groups[1].Value, out int res)) ? res : 0; | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
我觉得既然两个功能要合在一起的话,这里应该提供一个选项叫 不更改
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
其实我在想写的时候预留过一个5)