diff --git a/Assets/scripts/gamePlay_gameplay/settlementController.cs b/Assets/scripts/gamePlay_gameplay/settlementController.cs index 5fa6c365..ed738210 100644 --- a/Assets/scripts/gamePlay_gameplay/settlementController.cs +++ b/Assets/scripts/gamePlay_gameplay/settlementController.cs @@ -294,46 +294,31 @@ public class settlementController : MonoBehaviour int idol = sm != null ? sm.allSum_idolScore : 0; int total = pm + idol; - // compare and update per-difficulty personal/idol records - int prevPm = thisSong_so.GetPersonalRecord(diff); - int prevIdol = thisSong_so.GetIdolRecord(diff); + // 更新最高分 (仅当本次总分更高时) + thisSong_so.UpdateDifficultyRecord(diff, pm, idol); - if (pm > prevPm) - { - thisSong_so.UpdatePersonalRecord(diff, pm); - } - if (idol > prevIdol) - { - thisSong_so.UpdateIdolRecord(diff, idol); - } - - // update last-run total (chart score map / entry.lastScoreForThisDifficulty) + // 更新上次游玩分数 thisSong_so.UpdateChartScore(diff, total); - // update entry convenience fields (total and progress) only if improved + // 更新进度 (仅当进步时) if (thisSong_so.chartFiles != null) { var entry = thisSong_so.chartFiles.Find(e => e != null && e.difficulty == diff); if (entry != null) { - entry.totalPersonalRecordForThisDifficulty = thisSong_so.GetPersonalRecord(diff) + thisSong_so.GetIdolRecord(diff); - // compute progress as 0..1 - float newProgress = Mathf.Clamp01((float)entry.totalPersonalRecordForThisDifficulty / (float)maxScore_sum); + // 进度计算 (0..1) + float newProgress = Mathf.Clamp01((float)total / (float)maxScore_sum); if (newProgress > entry.levelProgressForThisDifficulty) { entry.levelProgressForThisDifficulty = newProgress; } - // if this is the currently selected difficulty for this song, update SongData.current_levelProgress if (thisSong_so.thisLevel_selectedDifficultyID == diff) { thisSong_so.current_levelProgress = Mathf.Max(thisSong_so.current_levelProgress, entry.levelProgressForThisDifficulty); } } } - - // refresh overall personalRecord cached value - thisSong_so.CalculateHighestPersonalRecord(); } } diff --git a/Assets/songsDatabase/SongData.cs b/Assets/songsDatabase/SongData.cs index d60dd55c..6d1c0e77 100644 --- a/Assets/songsDatabase/SongData.cs +++ b/Assets/songsDatabase/SongData.cs @@ -186,6 +186,94 @@ public class SongData : ScriptableObject return highest; } + // 更新指定难度的最高纪录 (只有当总分更高时才更新) + public void UpdateDifficultyRecord(int difficulty, int pmScore, int idolScore) + { + if (personalRecordMap == null) personalRecordMap = new Dictionary(); + if (idolRecordMap == null) idolRecordMap = new Dictionary(); + + int currentBestTotal = GetPersonalRecord(difficulty) + GetIdolRecord(difficulty); + int newTotal = pmScore + idolScore; + + if (newTotal > currentBestTotal) + { + personalRecordMap[difficulty] = pmScore; + idolRecordMap[difficulty] = idolScore; + + // also update corresponding ChartFileEntry if exists + var entry = chartFiles != null ? chartFiles.Find(e => e.difficulty == difficulty) : null; + if (entry != null) + { + entry.chartPersonalRecordForThisDifficulty = pmScore; + entry.idolPersonalRecordForThisDifficulty = idolScore; + entry.totalPersonalRecordForThisDifficulty = newTotal; + } + + CalculateHighestPersonalRecord(); + } + } + + // 获取全难度下的最高分及其对应的难度名称 + public void GetAbsoluteHighestScore(out int highestScore, out int bestDifficulty, out string bestDifficultyName) + { + highestScore = 0; + bestDifficulty = -1; + bestDifficultyName = ""; + + // 优先遍历 chartFiles 获取数据和名称 + if (chartFiles != null && chartFiles.Count > 0) + { + foreach (var entry in chartFiles) + { + if (entry == null) continue; + + // 重新计算总分以确保准确 + int total = GetPersonalRecord(entry.difficulty) + GetIdolRecord(entry.difficulty); + + // 如果字典里没数据,尝试用 entry 里的初始数据 + if (total <= 0) total = entry.totalPersonalRecordForThisDifficulty; + if (total <= 0) total = entry.chartPersonalRecordForThisDifficulty + entry.idolPersonalRecordForThisDifficulty; + + if (total > highestScore || bestDifficulty == -1) + { + highestScore = total; + bestDifficulty = entry.difficulty; + bestDifficultyName = !string.IsNullOrEmpty(entry.difficultyName) ? entry.difficultyName : GetDifficultyDefaultName(entry.difficulty); + } + } + } + + // 如果 chartFiles 为空,检查字典作为备选 + if (bestDifficulty == -1 && personalRecordMap != null) + { + foreach (var kvp in personalRecordMap) + { + int diff = kvp.Key; + int p = kvp.Value; + int i = GetIdolRecord(diff); + int combined = p + i; + if (combined > highestScore || bestDifficulty == -1) + { + highestScore = combined; + bestDifficulty = diff; + bestDifficultyName = GetDifficultyDefaultName(diff); + } + } + } + } + + private string GetDifficultyDefaultName(int difficulty) + { + switch (difficulty) + { + case 0: return "Easy"; + case 1: return "Hard"; + case 2: return "Incredible"; + case 3: return "Impossible"; + default: return "Unknown"; + } + } + // 更新指定难度的谱面(个人)最高成绩 public void UpdatePersonalRecord(int difficulty, int newScore) { diff --git a/Assets/songsDatabase/SongDataController/SongButton.cs b/Assets/songsDatabase/SongDataController/SongButton.cs index 73124bb7..5667b184 100644 --- a/Assets/songsDatabase/SongDataController/SongButton.cs +++ b/Assets/songsDatabase/SongDataController/SongButton.cs @@ -8,7 +8,7 @@ public class SongButton : MonoBehaviour { [Header("thisSong_so")] public ScriptableObject thisSong_so; - [Header("չʾϢ")] + [Header("显示信息")] public Text songNameText; public Text multiNameText; public Text joinTime_and_dlcName_Text; @@ -19,14 +19,14 @@ public class SongButton : MonoBehaviour public Text songIDText; public Image buttonImage; public Image scoreLevelImage; - [Header("ͷͼ")] + [Header("头像")] public Image profileImage; public int song_songSerialID; [Header("select mark")] public Image selected_boarder; public Image fade_image; - [Header("ٷֱ")] + [Header("评分阈值")] public float easePercent = 1f; public float ssPercent = 0.95f; public float sPercent = 0.9f; @@ -36,7 +36,7 @@ public class SongButton : MonoBehaviour public float dPercent = 0.5f; public float ePercent = 0.4f; public float fPercent = 0.3f; - [Header("׶ͼ")] + [Header("评级图")] public Sprite easeSprite; public Sprite ssSprite; public Sprite sSprite; @@ -75,7 +75,7 @@ public class SongButton : MonoBehaviour public void SetButtonData(string songName, int highestScore, int difficultyID, Sprite songSprite, int songID) { - Debug.Log("SetButtonData , songID : " + songID); + Debug.Log("SetButtonData called, songID: " + songID); var sd = SongDataLibrary.Instance != null ? SongDataLibrary.Instance.GetSongDataByID(songID) : null; if (sd != null) @@ -83,103 +83,34 @@ public class SongButton : MonoBehaviour if (songNameText != null) songNameText.text = sd.songName; if (multiNameText != null) - multiNameText.text = "֣" + sd.artistName + " | 棺" + sd.painter + " | ף" + sd.level_creator; + multiNameText.text = "作曲:" + sd.artistName + " | 画师:" + sd.painter + " | 制谱:" + sd.level_creator; if (joinTime_and_dlcName_Text != null) { - string join = string.IsNullOrEmpty(sd.thisLevel_addDateString) ? "δ֪" : sd.thisLevel_addDateString; - string dlc = string.IsNullOrEmpty(sd.belongsTo_whichDLC) ? "δ鵵DLC" : sd.belongsTo_whichDLC; - joinTime_and_dlcName_Text.text = "¼ʱ䣺" + join + " | " + "DLC" + dlc; + string join = string.IsNullOrEmpty(sd.thisLevel_addDateString) ? "未知" : sd.thisLevel_addDateString; + string dlc = string.IsNullOrEmpty(sd.belongsTo_whichDLC) ? "未知DLC" : sd.belongsTo_whichDLC; + joinTime_and_dlcName_Text.text = "上线时间:" + join + " | " + "所属DLC:" + dlc; } if (songOverallDescriptionText != null) { - songOverallDescriptionText.text = string.IsNullOrEmpty(sd.thisLevel_overallDescription) ? "޸顣" : sd.thisLevel_overallDescription; + songOverallDescriptionText.text = string.IsNullOrEmpty(sd.thisLevel_overallDescription) ? "关卡简介:" : sd.thisLevel_overallDescription; } - // Robust logic: compute best total across chartFiles if present - int bestTotal = -1; + // 使用 SongData 提供的统一方法获取全难度最高分及其对应的难度名称 + int bestTotal = 0; int bestDiff = -1; - - if (sd.chartFiles != null && sd.chartFiles.Count > 0) - { - foreach (var entry in sd.chartFiles) - { - if (entry == null) continue; - int total = 0; - // prefer stored total if > 0 - if (entry.totalPersonalRecordForThisDifficulty > 0) - { - total = entry.totalPersonalRecordForThisDifficulty; - } - else - { - // else compute from entry fields - int p = entry.chartPersonalRecordForThisDifficulty; - int i = entry.idolPersonalRecordForThisDifficulty; - total = p + i; - - // as fallback also check SongData maps - if (total == 0 && sd.personalRecordMap != null) - { - int pm = sd.personalRecordMap.ContainsKey(entry.difficulty) ? sd.personalRecordMap[entry.difficulty] : 0; - int im = sd.idolRecordMap != null && sd.idolRecordMap.ContainsKey(entry.difficulty) ? sd.idolRecordMap[entry.difficulty] : 0; - total = pm + im; - } - } - - if (bestDiff == -1 || total > bestTotal) - { - bestTotal = total; - bestDiff = entry.difficulty; - } - } - } - - // If still not found, fallback to maps - if (bestDiff == -1) - { - if (sd.personalRecordMap != null) - { - foreach (var kvp in sd.personalRecordMap) - { - int diff = kvp.Key; - int p = kvp.Value; - int i = sd.GetIdolRecord(diff); - int combined = p + i; - if (bestDiff == -1 || combined > bestTotal) - { - bestTotal = combined; - bestDiff = diff; - } - } - } - } - - // final fallback - if (bestDiff == -1) - { - bestTotal = sd.personalRecord; - bestDiff = sd.thisLevel_selectedDifficultyID; - } + string bestDiffName = ""; + sd.GetAbsoluteHighestScore(out bestTotal, out bestDiff, out bestDiffName); if (bestTotal < 0) bestTotal = 0; if (highestScoreText != null) highestScoreText.text = bestTotal.ToString(); - // Map difficulty index to label and set highestScoreDifficultyText as (Label) + // 在指定位置展示该最高分所属的难度名称 if (highestScoreDifficultyText != null) { - string label = ""; - switch (bestDiff) - { - case 0: label = "(Easy)"; break; - case 1: label = "(Hard)"; break; - case 2: label = "(Incredible)"; break; - case 3: label = "(Impossible)"; break; - default: label = ""; break; - } - highestScoreDifficultyText.text = label; + highestScoreDifficultyText.text = string.IsNullOrEmpty(bestDiffName) ? "" : "(" + bestDiffName + ")"; } // Assign scoreLevelImage based on thresholds relative to 2,000,000 @@ -187,30 +118,38 @@ public class SongButton : MonoBehaviour { Sprite chosenSprite = null; float baseScore = 2000000f; - // Evaluate from top to bottom thresholds - if (bestTotal >= baseScore * easePercent && easeSprite != null) - chosenSprite = easeSprite; - else if (bestTotal >= baseScore * ssPercent && ssSprite != null) - chosenSprite = ssSprite; - else if (bestTotal >= baseScore * sPercent && sSprite != null) - chosenSprite = sSprite; - else if (bestTotal >= baseScore * aPercent && aSprite != null) - chosenSprite = aSprite; - else if (bestTotal >= baseScore * bPercent && bSprite != null) - chosenSprite = bSprite; - else if (bestTotal >= baseScore * cPercent && cSprite != null) - chosenSprite = cSprite; - else if (bestTotal >= baseScore * dPercent && dSprite != null) - chosenSprite = dSprite; - else if (bestTotal >= baseScore * ePercent && eSprite != null) - chosenSprite = eSprite; - else if (bestTotal >= baseScore * fPercent && fSprite != null) - chosenSprite = fSprite; - else if (ufSprite != null) - chosenSprite = ufSprite; - if (chosenSprite != null) - scoreLevelImage.sprite = chosenSprite; + // 如果从来没玩过(总分为0),显示未完成图 + if (bestTotal <= 0) + { + chosenSprite = ufSprite; + } + else + { + // Evaluate from top to bottom thresholds + if (bestTotal >= baseScore * easePercent && easeSprite != null) + chosenSprite = easeSprite; + else if (bestTotal >= baseScore * ssPercent && ssSprite != null) + chosenSprite = ssSprite; + else if (bestTotal >= baseScore * sPercent && sSprite != null) + chosenSprite = sSprite; + else if (bestTotal >= baseScore * aPercent && aSprite != null) + chosenSprite = aSprite; + else if (bestTotal >= baseScore * bPercent && bSprite != null) + chosenSprite = bSprite; + else if (bestTotal >= baseScore * cPercent && cSprite != null) + chosenSprite = cSprite; + else if (bestTotal >= baseScore * dPercent && dSprite != null) + chosenSprite = dSprite; + else if (bestTotal >= baseScore * ePercent && eSprite != null) + chosenSprite = eSprite; + else if (bestTotal >= baseScore * fPercent && fSprite != null) + chosenSprite = fSprite; + else + chosenSprite = ufSprite; + } + + scoreLevelImage.sprite = chosenSprite; } // Determine displayed difficulty: show the highest difficultyLEVEL present in chartFiles (if any) @@ -251,7 +190,7 @@ public class SongButton : MonoBehaviour } song_songSerialID = songID; - if (songIDText != null) songIDText.text = "ݿţ" + song_songSerialID.ToString(); + if (songIDText != null) songIDText.text = "歌曲识别号:" + song_songSerialID.ToString(); } else { @@ -266,7 +205,7 @@ public class SongButton : MonoBehaviour public void OnSongButtonClick() { - Debug.Log("ť song_songSerialID: " + song_songSerialID); + Debug.Log("Song button clicked, song_songSerialID: " + song_songSerialID); SongData selectedSong = SongDataLibrary.Instance.GetSongDataByID(song_songSerialID); if (selectedSong != null) { @@ -295,7 +234,7 @@ public class SongButton : MonoBehaviour } else { - Debug.LogError("δҵӦ SongData, songID: " + song_songSerialID); + Debug.LogError("未找到对应的 SongData, songID: " + song_songSerialID); } }