1. 新增REWARD_CLAIMED游戏事件用于通知奖励领取完成 2. 新建RewardSet配置文件,定义段位和闯关奖励数据结构与具体配置 3. 在SingletonModuleComp中新增奖励领取相关逻辑: - 新增奖励领取状态存档字段 - 实现可领取奖励查询、奖励领取、通关标记等方法 - 新增统一的奖励发放工具方法
77 lines
3.5 KiB
TypeScript
77 lines
3.5 KiB
TypeScript
/**
|
||
* @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)];
|
||
}
|