Compare commits
2 Commits
5fe961846f
...
bde6825aa0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bde6825aa0 | ||
|
|
ea15b464ad |
@@ -220,12 +220,6 @@ export class SingletonModuleComp extends ecs.Comp {
|
||||
passed_wave_20: false,
|
||||
highest_dmg: 0,
|
||||
|
||||
score_combat: 0,
|
||||
score_output: 0,
|
||||
score_defense: 0,
|
||||
score_build: 0,
|
||||
score_efficiency: 0,
|
||||
|
||||
achieved_highlights: [],
|
||||
} as GameScoreStats,
|
||||
|
||||
@@ -293,11 +287,6 @@ export class SingletonModuleComp extends ecs.Comp {
|
||||
wave_all_alive_count: 0,
|
||||
passed_wave_20: false,
|
||||
highest_dmg: 0,
|
||||
score_combat: 0,
|
||||
score_output: 0,
|
||||
score_defense: 0,
|
||||
score_build: 0,
|
||||
score_efficiency: 0,
|
||||
achieved_highlights: [],
|
||||
} as GameScoreStats;
|
||||
}
|
||||
|
||||
@@ -219,14 +219,14 @@ export function getLvColor(lv: number): Color {
|
||||
export const RARITY_BG_COLORS: string[] = ["green", "blue", "purple", "yellow", "red"];
|
||||
|
||||
/**
|
||||
* 战斗结算奖励配置(每局结束后发放:英雄碎片 + 金币 + 天赋经验)。
|
||||
* 数值均为"失败基准",胜利时整体乘以 victory_multiplier。
|
||||
* 战斗结算奖励配置(每节结束后发放:英雄碎片 + 金币 + 天赋经验)。
|
||||
* 胜利奖励随关卡进度(怪物等级 = 大关号)线性增长,整体乘以 victory_multiplier。
|
||||
*/
|
||||
export const VICTORY_REWARD_SET = {
|
||||
/** 金币:base + wave_win_count × per_wave */
|
||||
gold: { base: 100, per_wave: 50 },
|
||||
/** 天赋经验:base + wave_win_count × per_wave */
|
||||
talent_exp: { base: 20, per_wave: 10 },
|
||||
/** 金币:base + monLv × per_lv */
|
||||
gold: { base: 100, per_lv: 50 },
|
||||
/** 天赋经验:base + monLv × per_lv */
|
||||
talent_exp: { base: 20, per_lv: 10 },
|
||||
/** 每个出场英雄保底碎片数 */
|
||||
played_fragment: 1,
|
||||
/** 随机英雄碎片数量(发放给随机抽中的 1 个英雄) */
|
||||
|
||||
@@ -100,13 +100,6 @@ export interface GameScoreStats {
|
||||
passed_wave_20: boolean; // 是否通过第20回合
|
||||
highest_dmg: number; // 单次最高伤害
|
||||
|
||||
// 最终结算分
|
||||
score_combat: number;
|
||||
score_output: number;
|
||||
score_defense: number;
|
||||
score_build: number;
|
||||
score_efficiency: number;
|
||||
|
||||
// 已达成的亮点成就记录
|
||||
achieved_highlights: any[];
|
||||
}
|
||||
|
||||
@@ -49,6 +49,7 @@ import { spawningEngine, WAVE_DURATION, BATTLE_TIMEOUT } from "./RogueConfig";
|
||||
import { MissionMonCompComp } from "./MissionMonComp";
|
||||
import {
|
||||
getProgressText,
|
||||
getMonsterLv,
|
||||
} from "../common/config/StageSet";
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
@@ -638,6 +639,8 @@ export class MissionComp extends CCComp {
|
||||
// 结算类型:小节胜利显示"下一节",末关通关显示"确认退出" + 通关标题
|
||||
settle_type: this._settleType,
|
||||
settle_title: this._settleTitle,
|
||||
// 关卡难度度量(= 大关号,驱动胜利奖励随进度增长)
|
||||
mon_lv: getMonsterLv(this.currentStage),
|
||||
// 失败奖励判定数据:本节坚持时间 + 击杀统计(kills=已刷出-存活)
|
||||
defeat_stats: {
|
||||
clear_time: this.clearTime,
|
||||
|
||||
@@ -180,6 +180,9 @@ export class VictoryComp extends CCComp {
|
||||
/** 失败奖励判定数据(MissionComp 传入:本节坚持时间 + 击杀统计) */
|
||||
private defeatStats: { clear_time: number; kills: number; total: number } | null = null;
|
||||
|
||||
/** 本节怪物等级(= 大关号,驱动胜利奖励随关卡进度增长) */
|
||||
private monLv: number = 1;
|
||||
|
||||
/** 加载时隐藏 loading 遮罩并绑定按钮事件 */
|
||||
protected onLoad(): void {
|
||||
this.node.getChildByName("loading").active = false
|
||||
@@ -225,6 +228,7 @@ export class VictoryComp extends CCComp {
|
||||
this.settleType = args.settle_type ?? "defeat";
|
||||
this.isVictory = !!args.victory;
|
||||
this.defeatStats = args.defeat_stats ?? null;
|
||||
this.monLv = Math.max(1, Number(args.mon_lv) || 1);
|
||||
|
||||
// 根据是否可复活决定按钮显示
|
||||
this.node.getChildByName("btns").getChildByName("next").active = !args.can_revive
|
||||
@@ -312,58 +316,38 @@ export class VictoryComp extends CCComp {
|
||||
* 计算单局总分并更新到 smc.vmdata.scores.score。
|
||||
* 同时刷新 smc.data.score 历史最高分。
|
||||
*
|
||||
* @param isVictory 是否胜利(胜利 +10 分,失败不加分)
|
||||
* @param allAlive 是否全英雄存活获胜(额外 +5 分)
|
||||
* 积分规则:
|
||||
* - 胜利 +10 分,全队存活 +5 分;失败 -10 分
|
||||
* - 暴击/闪避/击晕/冰冻每次 +1 分,单项封顶 5 分(不分胜负均计入)
|
||||
*
|
||||
* @param isVictory 是否胜利
|
||||
* @param allAlive 是否全英雄存活
|
||||
*/
|
||||
private calculateTotalScore(isVictory: boolean, allAlive: boolean) {
|
||||
const s = smc.vmdata.scores;
|
||||
|
||||
// 0. 胜负分:胜利 +10,全英雄存活获胜额外 +5,失败不加分
|
||||
let score_result = 0;
|
||||
// 0. 胜负分:胜利 +10(全队存活再 +5),失败 -10
|
||||
let base = 0;
|
||||
if (isVictory) {
|
||||
score_result = 10;
|
||||
base = 10;
|
||||
if (allAlive) {
|
||||
score_result += 5;
|
||||
base += 5;
|
||||
}
|
||||
} else {
|
||||
base = -10;
|
||||
}
|
||||
|
||||
// 1. 战绩分:衡量生存能力——活几回合、赢几场。
|
||||
s.score_combat = (s.wave_win_count * 100)
|
||||
- (s.wave_remain_monsters * 15)
|
||||
+ (s.wave_all_alive_count * 50)
|
||||
+ (s.passed_wave_20 ? 500 : 0);
|
||||
// 1. 战斗行为分:暴击/闪避/击晕/冰冻每次 +1,单项封顶 5
|
||||
const critPts = Math.min(5, s.crt_count);
|
||||
const dodgePts = Math.min(5, s.dod_count);
|
||||
const stunPts = Math.min(5, s.stun_count);
|
||||
const freezePts = Math.min(5, s.freeze_count);
|
||||
|
||||
// 2. 输出分:衡量伤害能力——团队火力如何。
|
||||
s.score_output = Math.floor(s.total_dmg / 100) * 10
|
||||
+ (s.crt_count * 5)
|
||||
// 风怒机制已停用: 风怒次数不再计入输出分
|
||||
// + (s.wf_count * 5)
|
||||
+ (s.highest_dmg * 2);
|
||||
// 存储当前局分数(失败局可为负,但总分下限钳 0)
|
||||
s.score = Math.max(0, Math.floor(base + critPts + dodgePts + stunPts + freezePts));
|
||||
|
||||
// 3. 防御分:衡量生存能力——团队多能扛。
|
||||
s.score_defense = (s.shield_block_count * 5)
|
||||
+ Math.floor(s.heal_total / 50) * 10
|
||||
+ (s.dead_trigger_count * 8);
|
||||
|
||||
// 4. 构建分:衡量阵容构建质量——团队配合程度。
|
||||
s.score_build = 0; // 待完善
|
||||
|
||||
// 5. 效率分:衡量资源利用——金币花得值不值。
|
||||
const goldRatio = s.gold_earned > 0 ? (s.gold_spent / s.gold_earned) : 0;
|
||||
const refreshRatio = s.refresh_count > 0 ? (s.refresh_hit_count / s.refresh_count) : 0;
|
||||
s.score_efficiency = Math.floor(goldRatio * 100) + Math.floor(refreshRatio * 50);
|
||||
|
||||
// 6. 亮点成就额外加分 (按等级叠加)
|
||||
const achieved = this.getAchievedHighlights(s);
|
||||
s.achieved_highlights = achieved; // 记录已达成的亮点信息
|
||||
|
||||
let highlightBonus = 0;
|
||||
for (const item of achieved) {
|
||||
highlightBonus += item.config.scoreBonus;
|
||||
}
|
||||
|
||||
// 取整并存储当前局分数
|
||||
s.score = Math.floor(score_result + s.score_combat + s.score_output + s.score_defense + s.score_build + s.score_efficiency + highlightBonus);
|
||||
// 亮点成就判定:仅作结算页亮点标签展示,不计入总分
|
||||
s.achieved_highlights = this.getAchievedHighlights(s);
|
||||
|
||||
// 记录滚动前的历史最高分(动画起始值)
|
||||
this._prevBestScore = smc.data.score;
|
||||
@@ -384,13 +368,8 @@ export class VictoryComp extends CCComp {
|
||||
(s as any).isNewRecord = isNewRecord;
|
||||
|
||||
mLogger.log(this.debugMode, 'VictoryComp', `[VictoryComp] 结算总分: ${s.score}`, {
|
||||
combat: s.score_combat,
|
||||
output: s.score_output,
|
||||
defense: s.score_defense,
|
||||
build: s.score_build,
|
||||
efficiency: s.score_efficiency,
|
||||
highlightBonus: highlightBonus,
|
||||
achievedHighlights: achieved,
|
||||
base,
|
||||
critPts, dodgePts, stunPts, freezePts,
|
||||
isNewRecord: isNewRecord,
|
||||
prevBest: this._prevBestScore
|
||||
});
|
||||
@@ -608,7 +587,9 @@ export class VictoryComp extends CCComp {
|
||||
|
||||
/**
|
||||
* 计算并发放结算奖励,结果存入 _rewardResult。
|
||||
* 胜利:原公式不变(base + wave × per_wave,整体 ×1.2)。
|
||||
* 胜利:随关卡进度增长(base + monLv × per_lv,整体 ×1.2)。
|
||||
* Why: 无回合概念后 wave_win_count 每节被 resetScores 清零恒为 1,
|
||||
* 旧的 per_wave 增长失效,改挂怪物等级(= 大关号)随关卡推进线性增长。
|
||||
* 失败:受"坚持时间 + 击杀比例"限制——
|
||||
* - 坚持 < 15s 或本节一只怪未杀 → 无任何奖励;
|
||||
* - 达标 → 坚持奖励(固定)+ 击杀比例奖励(基数 × 本节击杀比例),
|
||||
@@ -616,9 +597,7 @@ export class VictoryComp extends CCComp {
|
||||
* @param isVictory 是否胜利
|
||||
*/
|
||||
private grantRewards(isVictory: boolean) {
|
||||
const s = smc.vmdata.scores;
|
||||
const cfg = VICTORY_REWARD_SET;
|
||||
const wave = Math.max(0, s.wave_win_count || 0);
|
||||
|
||||
// 失败奖励资格判定:坚持时间与击杀数不达标则整场无奖励
|
||||
let defeatQualified = false;
|
||||
@@ -637,8 +616,8 @@ export class VictoryComp extends CCComp {
|
||||
let talentExp: number;
|
||||
if (isVictory) {
|
||||
const mult = cfg.victory_multiplier;
|
||||
gold = Math.floor((cfg.gold.base + wave * cfg.gold.per_wave) * mult);
|
||||
talentExp = Math.floor((cfg.talent_exp.base + wave * cfg.talent_exp.per_wave) * mult);
|
||||
gold = Math.floor((cfg.gold.base + this.monLv * cfg.gold.per_lv) * mult);
|
||||
talentExp = Math.floor((cfg.talent_exp.base + this.monLv * cfg.talent_exp.per_lv) * mult);
|
||||
} else if (defeatQualified) {
|
||||
// 失败达标 = 坚持奖励(固定)+ 击杀比例奖励
|
||||
gold = Math.floor(cfg.defeat.survive.gold + cfg.defeat.kill.gold * killRatio);
|
||||
@@ -690,7 +669,7 @@ export class VictoryComp extends CCComp {
|
||||
this._rewardResult = { gold, talentExp, silver, diamond, fragments };
|
||||
|
||||
mLogger.log(this.debugMode, 'VictoryComp', '[VictoryComp] 结算奖励发放', {
|
||||
isVictory, wave, gold, talentExp, silver, diamond, fragments,
|
||||
isVictory, monLv: this.monLv, gold, talentExp, silver, diamond, fragments,
|
||||
defeatStats: this.defeatStats, defeatQualified, killRatio,
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user