Files
ichni_Official/Assets/Scripts/Saving/BeatmapSave.cs

119 lines
4.0 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Ichni.RhythmGame
{
/// <summary>
/// 单个歌曲难度的最佳成绩。
/// 这里只保存当前 Chart Revision 下可比较的最佳记录,不保存逐局历史、判定时间线或 Replay。
/// </summary>
public class BeatmapSave
{
/// <summary>历史最高 Accuracy固定使用 0 到 1显示时由 UI 乘以 100。</summary>
public float accuracy;
/// <summary>当前 Revision 下是否曾达成 Full Combo。</summary>
public bool isFullCombo;
/// <summary>当前 Revision 下是否曾达成 All Perfect。</summary>
public bool isAllPerfect;
/// <summary>成绩对应的谱面修订号0 表示尚未绑定 Revision 的新建或异常记录。</summary>
public int chartRevision;
/// <summary>当前 Revision 下的历史最高连击数。</summary>
public int maxCombo;
public BeatmapSave()
{
}
public BeatmapSave(float accuracy, bool isFullCombo, bool isAllPerfect)
{
this.accuracy = accuracy;
this.isFullCombo = isFullCombo;
this.isAllPerfect = isAllPerfect;
}
/// <summary>
/// 令存档成绩匹配当前谱面 Revision。
/// <para>仅当 Note、Timing 或判定规则改变、导致成绩不再可比较时才递增 Revision。</para>
/// <para>未绑定 Revision 的记录会保留已有成绩并绑定到当前 Revision之后出现真正的 Revision
/// 变化时,才仅重置该谱面的可比成绩。</para>
/// </summary>
public bool EnsureChartRevision(int currentChartRevision)
{
currentChartRevision = Mathf.Max(1, currentChartRevision);
if (chartRevision <= 0)
{
chartRevision = currentChartRevision;
return true;
}
if (chartRevision == currentChartRevision)
{
return false;
}
accuracy = 0f;
isFullCombo = false;
isAllPerfect = false;
maxCombo = 0;
chartRevision = currentChartRevision;
return true;
}
/// <summary>
/// 合并一次完整演奏的成绩。
/// <see cref="accuracy"/> 在持久化记录中始终使用 0 到 1 的归一化值,
/// 而 <see cref="PlayingRecorder.accuracy"/> 的运行时显示值为 0 到 100。
/// 写入规则是“最高 Accuracy / 最高 Max Combo / FC 与 AP 成就粘性保留”,而不是保存最近一次成绩。
/// </summary>
public bool ApplyPlayResult(PlayingRecorder recorder, int currentChartRevision)
{
if (recorder == null || recorder.totalCount <= 0)
{
return false;
}
bool changed = EnsureChartRevision(currentChartRevision);
float normalizedAccuracy = Mathf.Clamp01(recorder.accuracy / 100f);
if (normalizedAccuracy > accuracy)
{
accuracy = normalizedAccuracy;
changed = true;
}
bool achievedFullCombo = recorder.isFullCombo || recorder.isAllPerfect;
if (achievedFullCombo && !isFullCombo)
{
isFullCombo = true;
changed = true;
}
if (recorder.isAllPerfect && !isAllPerfect)
{
isAllPerfect = true;
changed = true;
}
if (recorder.maxCombo > maxCombo)
{
maxCombo = recorder.maxCombo;
changed = true;
}
return changed;
}
/// <summary>用于章节完成度统计Revision 本身不代表玩家已经游玩过该谱面。</summary>
public bool IsEmpty()
{
return accuracy == 0f && !isFullCombo && !isAllPerfect && maxCombo == 0;
}
}
}