Files
pixelheros/assets/script/game/common/config/RewardSet.ts
pan 88ac1337a4 feat: 添加段位和闯关奖励领取系统
1. 新增REWARD_CLAIMED游戏事件用于通知奖励领取完成
2. 新建RewardSet配置文件,定义段位和闯关奖励数据结构与具体配置
3. 在SingletonModuleComp中新增奖励领取相关逻辑:
   - 新增奖励领取状态存档字段
   - 实现可领取奖励查询、奖励领取、通关标记等方法
   - 新增统一的奖励发放工具方法
2026-09-11 17:08:55 +08:00

77 lines
3.5 KiB
TypeScript
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.
/**
* @file RewardSet.ts
* @description 段位奖励 + 闯关奖励配置(纯数据,无逻辑)
*
* 定位差异化:
* - 段位奖励(RANK_REWARDS):稀有向——钻石 + 英雄碎片,荣誉回报
* - 闯关奖励(STAGE_REWARDS):养成向——金币 + 天赋经验,进程回报(精英关/Boss 关加成)
*
* 领取模式:玩家点击领取(SMC.claimRankReward / claimStageReward),
* 状态持久化于 smc.data.reward_claimed,不领不丢、跨局保留。
*/
import { HeroInfo } from "./heroSet";
import { FacSet } from "./GameSet";
import { ScoreTier } from "./ScoreRankSet";
/** 奖励资源类型 */
export type RewardType = 'gold' | 'silver' | 'diamond' | 'talent_exp' | 'fragment';
/** 单条奖励 */
export interface RewardItem {
/** 资源类型 */
type: RewardType;
/** 数量 */
value: number;
/** 英雄碎片专用:指定英雄 uuid,缺省随机抽取 */
heroUuid?: number;
}
/**
* 段位首达奖励(每档一份,跨档可补领)
* 阈值与段位定义见 ScoreRankSet.ScoreRankList
*/
export const RANK_REWARDS: Record<ScoreTier, RewardItem[]> = {
[ScoreTier.BRONZE]: [{ type: 'diamond', value: 10 }],
[ScoreTier.SILVER]: [{ type: 'diamond', value: 20 }, { type: 'fragment', value: 3 }],
[ScoreTier.GOLD]: [{ type: 'diamond', value: 30 }, { type: 'fragment', value: 5 }],
[ScoreTier.PLATINUM]: [{ type: 'diamond', value: 50 }, { type: 'fragment', value: 8 }],
[ScoreTier.DIAMOND]: [{ type: 'diamond', value: 80 }, { type: 'fragment', value: 10 }],
[ScoreTier.MASTER]: [{ type: 'diamond', value: 120 }, { type: 'fragment', value: 15 }],
[ScoreTier.LEGEND]: [{ type: 'diamond', value: 200 }, { type: 'fragment', value: 20 }],
};
/**
* 闯关奖励(每大关首通一份,共 10 份)
* 养成向:金币 + 天赋经验;第 5 关(精英)/第 10 关(Boss)额外附赠银币
*/
export const STAGE_REWARDS: Record<number, RewardItem[]> = {
1: [{ type: 'gold', value: 200 }, { type: 'talent_exp', value: 20 }],
2: [{ type: 'gold', value: 300 }, { type: 'talent_exp', value: 30 }],
3: [{ type: 'gold', value: 400 }, { type: 'talent_exp', value: 40 }],
4: [{ type: 'gold', value: 500 }, { type: 'talent_exp', value: 50 }],
5: [{ type: 'gold', value: 700 }, { type: 'talent_exp', value: 70 }, { type: 'silver', value: 10 }],
6: [{ type: 'gold', value: 600 }, { type: 'talent_exp', value: 60 }],
7: [{ type: 'gold', value: 700 }, { type: 'talent_exp', value: 70 }],
8: [{ type: 'gold', value: 800 }, { type: 'talent_exp', value: 80 }],
9: [{ type: 'gold', value: 900 }, { type: 'talent_exp', value: 90 }],
10: [{ type: 'gold', value: 1500 }, { type: 'talent_exp', value: 150 }, { type: 'silver', value: 20 }],
};
/**
* 从全英雄池随机抽取 1 个英雄 uuid(排除指定集合,池空时兜底返回 0)
* @param exclude 需排除的 uuid 集合(可空)
* @returns 随机英雄 uuid;英雄池为空返回 0
*/
export function pickRandomHeroUuid(exclude?: Set<number>): number {
const excludeSet = exclude ?? new Set<number>();
// 仅英雄池参与抽取(HeroInfo 同时含怪物条目,碎片属英雄局外成长)
const all = Object.keys(HeroInfo)
.map(k => Number(k))
.filter(u => u > 0 && HeroInfo[u]?.fac === FacSet.HERO);
const candidates = all.filter(u => !excludeSet.has(u));
const pool = candidates.length > 0 ? candidates : all;
if (pool.length === 0) return 0;
return pool[Math.floor(Math.random() * pool.length)];
}