refactor(score): 重构积分段位与生涯积分逻辑
1. 更新段位配置阈值,改为按局均20分估算的累计分标准 2. 修改生涯积分逻辑,改为累计正贡献分且不会回退 3. 优化结算页积分展示和涨幅提示逻辑,新增升段提示 4. 完善文档注释,修正积分规则描述
This commit is contained in:
@@ -1,6 +1,9 @@
|
||||
/**
|
||||
* 玩家得分段位配置
|
||||
* 依据玩家历史最高分(smc.data.score)划分段位:黄铜 -> 传说
|
||||
* @file 玩家得分段位配置
|
||||
* @description 依据生涯累计分(smc.data.score,只涨不跌)划分段位:黄铜 -> 传说
|
||||
*
|
||||
* 阈值尺度(慢节奏,局均 ~20 分估算):
|
||||
* 白银 5 局 / 黄金 15 局 / 铂金 40 局 / 钻石 80 局 / 大师 160 局 / 传说 320 局
|
||||
*/
|
||||
|
||||
/** 段位标识 */
|
||||
@@ -31,13 +34,13 @@ export interface ScoreRankInfo {
|
||||
* 顺序必须保持 minScore 升序,供二分/逆序查找使用
|
||||
*/
|
||||
export const ScoreRankList: ScoreRankInfo[] = [
|
||||
{ tier: ScoreTier.BRONZE, name: "黄铜", minScore: 0, icon: "League_1_Bronze" },
|
||||
{ tier: ScoreTier.SILVER, name: "白银", minScore: 2000, icon: "League_2_Silver" },
|
||||
{ tier: ScoreTier.GOLD, name: "黄金", minScore: 5000, icon: "League_3_Gold" },
|
||||
{ tier: ScoreTier.PLATINUM, name: "铂金", minScore: 10000, icon: "League_4_Platinum" },
|
||||
{ tier: ScoreTier.DIAMOND, name: "钻石", minScore: 20000, icon: "League_5_Diamond" },
|
||||
{ tier: ScoreTier.MASTER, name: "大师", minScore: 40000, icon: "League_6_Master" },
|
||||
{ tier: ScoreTier.LEGEND, name: "传说", minScore: 80000, icon: "League_7_Legendary" },
|
||||
{ tier: ScoreTier.BRONZE, name: "黄铜", minScore: 0, icon: "League_1_Bronze" },
|
||||
{ tier: ScoreTier.SILVER, name: "白银", minScore: 100, icon: "League_2_Silver" },
|
||||
{ tier: ScoreTier.GOLD, name: "黄金", minScore: 300, icon: "League_3_Gold" },
|
||||
{ tier: ScoreTier.PLATINUM, name: "铂金", minScore: 800, icon: "League_4_Platinum" },
|
||||
{ tier: ScoreTier.DIAMOND, name: "钻石", minScore: 1600, icon: "League_5_Diamond" },
|
||||
{ tier: ScoreTier.MASTER, name: "大师", minScore: 3200, icon: "League_6_Master" },
|
||||
{ tier: ScoreTier.LEGEND, name: "传说", minScore: 6400, icon: "League_7_Legendary" },
|
||||
];
|
||||
|
||||
/**
|
||||
|
||||
@@ -158,9 +158,9 @@ export class VictoryComp extends CCComp {
|
||||
|
||||
/** 动画期间实时显示的分数(tween 驱动) */
|
||||
private _displayScore: number = 0;
|
||||
/** 滚动前的历史最高分(动画起始值) */
|
||||
/** 滚动前的生涯累计分(动画起始值) */
|
||||
private _prevBestScore: number = 0;
|
||||
/** 本局总分(动画结束值) */
|
||||
/** 滚动后的生涯累计分(动画结束值) */
|
||||
private _finalScore: number = 0;
|
||||
/** 滚动起始段位(用于检测跨段) */
|
||||
private _startRank: ScoreRankInfo = null!;
|
||||
@@ -313,15 +313,14 @@ export class VictoryComp extends CCComp {
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算单局总分并更新到 smc.vmdata.scores.score。
|
||||
* 同时刷新 smc.data.score 历史最高分。
|
||||
* 计算本局得分并累加到生涯总分(smc.data.score 为累计分,驱动段位)。
|
||||
*
|
||||
* 积分规则:
|
||||
* - 胜利 +10 分,全队存活 +5 分;失败 -10 分
|
||||
* - 暴击/闪避/击晕/冰冻每次 +1 分,单项封顶 5 分(不分胜负均计入)
|
||||
* - 单局:胜利 +10(全队存活再 +5)/ 失败 -10;暴击/闪避/击晕/冰冻每次 +1、单项封顶 5
|
||||
* - 累计:生涯分 += max(0, 本局分),负分局不回退(不掉段),累计下限钳 0
|
||||
*
|
||||
* @param isVictory 是否胜利
|
||||
* @param allAlive 是否全英雄存活
|
||||
* @param allAlive 是否全队存活
|
||||
*/
|
||||
private calculateTotalScore(isVictory: boolean, allAlive: boolean) {
|
||||
const s = smc.vmdata.scores;
|
||||
@@ -343,35 +342,32 @@ export class VictoryComp extends CCComp {
|
||||
const stunPts = Math.min(5, s.stun_count);
|
||||
const freezePts = Math.min(5, s.freeze_count);
|
||||
|
||||
// 存储当前局分数(失败局可为负,但总分下限钳 0)
|
||||
s.score = Math.max(0, Math.floor(base + critPts + dodgePts + stunPts + freezePts));
|
||||
// 本局得分:失败局可为负(结算页如实展示)
|
||||
s.score = Math.floor(base + critPts + dodgePts + stunPts + freezePts);
|
||||
|
||||
// 亮点成就判定:仅作结算页亮点标签展示,不计入总分
|
||||
s.achieved_highlights = this.getAchievedHighlights(s);
|
||||
|
||||
// 记录滚动前的历史最高分(动画起始值)
|
||||
// 累计生涯分:正贡献累加、负分不回退(声望式不掉段),下限钳 0
|
||||
this._prevBestScore = smc.data.score;
|
||||
this._finalScore = s.score;
|
||||
const gain = Math.max(0, s.score);
|
||||
smc.data.score = Math.max(0, this._prevBestScore + gain);
|
||||
this._finalScore = smc.data.score;
|
||||
|
||||
// 判定是否打破历史最高分记录
|
||||
let isNewRecord = false;
|
||||
if (s.score > smc.data.score) {
|
||||
smc.data.score = s.score;
|
||||
isNewRecord = true;
|
||||
// 更新云端/本地存储,保存新记录
|
||||
if (typeof smc.updateCloudData === "function") {
|
||||
smc.updateCloudData();
|
||||
}
|
||||
// 持久化生涯分(云端/本地同步)
|
||||
if (typeof smc.updateCloudData === "function") {
|
||||
smc.updateCloudData();
|
||||
}
|
||||
|
||||
// 借用 scores 对象传递新记录标记,供 UI 渲染使用
|
||||
(s as any).isNewRecord = isNewRecord;
|
||||
// 借用 scores 对象传递标记:本局有正贡献(供涨幅标签展示)
|
||||
(s as any).isNewRecord = gain > 0;
|
||||
|
||||
mLogger.log(this.debugMode, 'VictoryComp', `[VictoryComp] 结算总分: ${s.score}`, {
|
||||
mLogger.log(this.debugMode, 'VictoryComp', `[VictoryComp] 本局得分: ${s.score}`, {
|
||||
base,
|
||||
critPts, dodgePts, stunPts, freezePts,
|
||||
isNewRecord: isNewRecord,
|
||||
prevBest: this._prevBestScore
|
||||
gain,
|
||||
careerTotal: this._finalScore,
|
||||
prevTotal: this._prevBestScore
|
||||
});
|
||||
}
|
||||
|
||||
@@ -510,21 +506,23 @@ export class VictoryComp extends CCComp {
|
||||
}
|
||||
|
||||
/**
|
||||
* 滚动定格后显示 +N 涨幅标签(仅破纪录时)
|
||||
* 滚动定格后显示 +N 涨幅标签(本局有正贡献时;跨段位时附加升段文案)
|
||||
*/
|
||||
private showGainLabel() {
|
||||
if (!this.gain_label) return;
|
||||
|
||||
const s = smc.vmdata.scores;
|
||||
const isNewRecord = (s as any).isNewRecord === true;
|
||||
const hasGain = (s as any).isNewRecord === true;
|
||||
const gain = this._finalScore - this._prevBestScore;
|
||||
|
||||
if (!isNewRecord || gain <= 0) {
|
||||
if (!hasGain || gain <= 0) {
|
||||
this.gain_label.node.active = false;
|
||||
return;
|
||||
}
|
||||
|
||||
this.gain_label.string = `+${gain} 新纪录!`;
|
||||
// 跨段位判定:滚动前后段位不一致即为升段(累计分只涨不跌,不存在降段)
|
||||
const rankUp = getRankByScore(this._finalScore).tier !== getRankByScore(this._prevBestScore).tier;
|
||||
this.gain_label.string = rankUp ? `+${gain} 升段!` : `+${gain}`;
|
||||
this.gain_label.node.active = true;
|
||||
|
||||
// 浮现动效:从 0 缩放淡入
|
||||
|
||||
Reference in New Issue
Block a user