using System; using System.Collections; using System.Collections.Generic; using System.Linq; using AK.Wwise; using Ichni.RhythmGame; using Sirenix.OdinInspector; using SLSUtilities.WwiseAssistance; using UnityEngine; using UnityEngine.Serialization; namespace Ichni.Menu { [CreateAssetMenu(fileName = "DefaultChapter", menuName = "Ichni/UI/ChapterSelectionUnit", order = 0)] public partial class ChapterSelectionUnit : SerializedScriptableObject { public string chapterIndex; public string chapterName; public string chapterSubtitle; public Color themeColor; public Sprite avatar; public Switch chapterSwitch; /// /// 章节剧情入口与选曲入口共用的内容解锁规则。 /// 留空表示章节从新档开始即可访问;需要锁定时请使用 , /// 并遵守 中的下划线 Key 规则。 /// [LabelText("Unlock Requirement")] public UnlockRequirement unlockRequirement = new UnlockRequirement(); [Searchable] public List songs = new List(); [Button] public void SetUpDefaultDifficulties() { foreach (SongItemData song in songs) { if (song.difficultyDataList.All(d => d.difficultyName != "Easy")) { song.difficultyDataList.Add(new DifficultyData( 0, "Easy", "Easy", 0, "", new Color(0f, 0.7f, 0.2f, 1f))); } if (song.difficultyDataList.All(d => d.difficultyName != "Hard")) { song.difficultyDataList.Add(new DifficultyData( 1, "Hard", "Hard", 0, "", new Color(1f, 0.2f, 0.2f, 1f))); } } } [Button] public void SelectSwitch() { AudioManager.SetSwitch(chapterSwitch); } } public partial class ChapterSelectionUnit { public (int, int, int, int, int) GetChapterSaveInfo() { int beatmapCount = 0; int finishedSongCount = 0; int finishedBeatmapCount = 0; int fullComboCount = 0; int allPerfectCount = 0; foreach (SongItemData song in songs) { if (GameSaveManager.instance.SongSaveModule.songStatusSaves.TryGetValue(song.songName, out var songStatus)) { bool thisSongFinished = false; foreach (DifficultyData difficulty in song.difficultyDataList) { if (difficulty == null || difficulty.saveDifficultyId < 0) { continue; } beatmapCount++; if (!songStatus.TryGetBeatmapSave(difficulty.saveDifficultyId, out BeatmapSave beatmapSave)) { continue; } if (!beatmapSave.IsEmpty()) { thisSongFinished = true; finishedBeatmapCount++; if (beatmapSave.isFullCombo) { fullComboCount++; } if (beatmapSave.isAllPerfect) { allPerfectCount++; } } } if (thisSongFinished) { finishedSongCount++; } } } return (beatmapCount, finishedSongCount, finishedBeatmapCount, fullComboCount, allPerfectCount); } } [InlineProperty] [Serializable] public class SongItemData { [FoldoutGroup("$songName", false)] public string songName; [FoldoutGroup("$songName")] public string displaySongName; [FoldoutGroup("$songName")] public string composer; [FoldoutGroup("$songName")] public Switch songSwitch; [FoldoutGroup("$songName")] public Sprite illustration; [FoldoutGroup("$songName")] public string illustratorName; [FoldoutGroup("$songName")] public string additionalInformation; [FoldoutGroup("$songName")] public List difficultyDataList; /// /// 歌曲自身的内容解锁规则。章节是否开放由 单独判断; /// 真正进入歌曲时两者必须同时满足。 /// [FoldoutGroup("$songName")] [LabelText("Unlock Requirement")] public UnlockRequirement unlockRequirement = new UnlockRequirement(); } [Serializable] public class DifficultyData { /// /// 歌曲成绩的稳定 ID,不等同于选曲 UI 的难度列表位置。 /// 发布后不要更改或复用既有 ID;新增难度必须使用从未分配过的非负 ID。 /// [FormerlySerializedAs("difficultyIndex")] public int saveDifficultyId; public string difficultyName; public string displayDifficultyName; public int difficultyValue; public string charterName; public Color color; public bool isAvailable; public bool ForceFullScreenJudge = false; [MinValue(1)] [Tooltip("仅当 Note、Timing 或判定规则变化,导致成绩不可与旧谱面比较时递增;UI、文本、封面和音量调整不递增。")] public int chartRevision = 1; public DifficultyData() { } public DifficultyData(int saveDifficultyId, string difficultyName, string displayDifficultyName, int difficultyValue, string charterName, Color color, bool ForceFullScreenJudge = false) { this.saveDifficultyId = saveDifficultyId; this.difficultyName = difficultyName; this.displayDifficultyName = displayDifficultyName; this.charterName = charterName; this.difficultyValue = difficultyValue; this.color = color; this.isAvailable = true; this.ForceFullScreenJudge = ForceFullScreenJudge; } public string GetDifficultyName() { return string.IsNullOrEmpty(displayDifficultyName) ? difficultyName : displayDifficultyName; } /// /// 返回合法的 Revision。配置侧始终至少使用 1;0 只会被视为未初始化值并被钳制。 /// public int GetChartRevision() { return Mathf.Max(1, chartRevision); } } }