feat: 新增天赋系统,实现局外天赋养成与战斗属性加成

- 新增天赋配置表与相关枚举、数据结构
- 新增全局单例的天赋数据管理接口,支持升级、重置、点数管理
- 新增天赋属性加成结算逻辑,支持全局天赋与职业专精天赋
- 新增治疗强化、buff强化属性与对应天赋支持
- 新增天赋更新事件,同步UI与战斗数据
- 在英雄加载、升级流程中接入天赋加成计算
This commit is contained in:
panFD
2026-08-24 22:58:27 +08:00
parent 61e33ff754
commit 2fc085c3aa
9 changed files with 416 additions and 3 deletions

View File

@@ -9,6 +9,7 @@ import { GameScoreStats } from "./config/HeroAttrs";
import { mLogger } from "./Logger";
import { gameDataSync } from "./GameDataSync";
import { HERO_UPGRADE_NEED_FRAGMENTS } from "./config/GameSet";
import { TalentSet, getTalentUpgradeCost } from "./config/TalentSet";
/**
* 用远程数据覆盖本地数据(统一方法)
@@ -35,6 +36,10 @@ export interface GameDate {
timestamp?: number, // 用于比对本地与云端数据的最新状态
/** 英雄局外成长数据:key 为英雄 uuid,value 为成长记录 */
hero_growth?: Record<number, HeroGrowthRecord>,
/** 天赋等级表:key 为天赋 uuid,value 为当前等级(未记录视为 0 级) */
talents?: Record<number, number>,
/** 当前可用天赋点数(升级天赋消耗,经验/等级系统接入后由其产出) */
talent_points?: number,
}
export interface CloudData {
openid: string;
@@ -121,6 +126,10 @@ export class SingletonModuleComp extends ecs.Comp {
// 已满级:验证满级后 upgradeHero 返回 false
5004: { uuid: 5004, lv: 6, fragments: 999 },
} as Record<number, HeroGrowthRecord>,
/** 天赋等级表:key 为天赋 uuid,value 为当前等级 */
talents: {} as Record<number, number>,
/** 可用天赋点数 */
talent_points: 0,
}
vmdata: any = {
@@ -376,6 +385,87 @@ export class SingletonModuleComp extends ecs.Comp {
return true;
}
// ==================== 天赋系统 ====================
/**
* 获取天赋当前等级(未升级返回 0)
* @param uuid 天赋 uuid(TalentSet key)
*/
getTalentLv(uuid: number): number {
return this.data.talents?.[uuid] ?? 0;
}
/**
* 获取当前可用天赋点数
*/
getTalentPoints(): number {
return this.data.talent_points ?? 0;
}
/**
* 增加天赋点(经验/等级系统接入后由其调用)
* @param count 增加的点数(正数)
*/
addTalentPoints(count: number): void {
if (!this.data.talents) this.data.talents = {};
this.data.talent_points = Math.max(0, (this.data.talent_points ?? 0) + count);
gameDataSync.markDataDirty();
oops.message.dispatchEvent(GameEvent.TALENT_UPDATE);
}
/**
* 消耗天赋点升级天赋(升级即激活,下一局生效)
* @param uuid 天赋 uuid
* @returns 是否升级成功(天赋不存在/已满级/前置未满足/点数不足时返回 false)
*/
upgradeTalent(uuid: number): boolean {
const cfg = TalentSet[uuid];
if (!cfg) return false;
if (!this.data.talents) this.data.talents = {};
const curLv = this.getTalentLv(uuid);
if (curLv >= cfg.max_lv) return false;
// 专精天赋的前置要求:前置天赋等级不足则禁止升级
if (cfg.requires) {
for (const req of cfg.requires) {
if (this.getTalentLv(req.uuid) < req.lv) return false;
}
}
const cost = getTalentUpgradeCost(curLv);
if (cost < 0 || this.getTalentPoints() < cost) return false;
this.data.talent_points -= cost;
this.data.talents[uuid] = curLv + 1;
gameDataSync.markDataDirty();
oops.message.dispatchEvent(GameEvent.TALENT_UPDATE);
return true;
}
/**
* 重置所有天赋等级并退还全部已消耗天赋点(看广告入口)
* Why: 退还点数按"升到当前等级的累计消耗"计算,与升级消耗表严格对账,避免点数膨胀/缩水。
*/
resetTalents(): void {
if (!this.data.talents) this.data.talents = {};
let refund = 0;
for (const key in this.data.talents) {
const lv = this.data.talents[key];
for (let i = 0; i < lv; i++) {
const c = getTalentUpgradeCost(i);
if (c > 0) refund += c;
}
}
this.data.talents = {};
this.data.talent_points = (this.data.talent_points ?? 0) + refund;
gameDataSync.markDataDirty();
oops.message.dispatchEvent(GameEvent.TALENT_UPDATE);
}
/**
* 获取天赋等级表(战斗加载时供 Hero.load / applyHeroLevel 聚合加成)
*/
getTalentLevels(): Record<number, number> {
return this.data.talents ?? {};
}
/**
* 在游戏载入早期调用,预加载常用图集
*/