Files
heros/assets/script/game/common/config/TalSet_Example.ts
2025-10-27 11:17:15 +08:00

483 lines
14 KiB
TypeScript

/**
* 天赋系统集成示例
* 展示如何在实际游戏系统中使用 TalSet 配置
*/
import {
TalType,
TalAttrType,
TalActionType,
ItalConf,
getTalConf,
getTalConfByType,
getAllTalIds,
talConf
} from "./TalSet";
// ========== 天赋实时数据结构 ==========
/**
* 英雄天赋实例数据
* 记录单个英雄某个天赋的实时数据
*/
export interface HeroTalentInstance {
talId: number; // 天赋ID
stackCount: number; // 当前堆叠层数
actionCounter: number; // 行为计数器(用于计数类天赋)
damageCounter: number; // 受伤计数器(用于受伤类天赋)
lastTriggerLevel: number; // 最后一次触发的等级(用于等级类天赋)
isActive: boolean; // 是否激活
}
/**
* 英雄天赋管理数据
* 记录一个英雄的所有天赋数据
*/
export interface HeroTalentManager {
heroId: number;
talents: Map<number, HeroTalentInstance>;
}
// ========== 天赋触发系统 ==========
/**
* 天赋触发管理器
* 处理天赋的所有触发逻辑
*/
export class TalentTriggerManager {
private talentInstances: Map<number, HeroTalentManager> = new Map();
/**
* 初始化英雄的天赋系统
* @param heroId 英雄ID
* @param talentIds 天赋ID数组
*/
public initHeroTalents(heroId: number, talentIds: number[]): void {
const talentManager: HeroTalentManager = {
heroId,
talents: new Map(),
};
talentIds.forEach(talId => {
const talConfig = getTalConf(talId);
if (talConfig) {
talentManager.talents.set(talId, {
talId,
stackCount: 0,
actionCounter: 0,
damageCounter: 0,
lastTriggerLevel: 0,
isActive: true,
});
}
});
this.talentInstances.set(heroId, talentManager);
}
/**
* 处理英雄等级提升事件
* @param heroId 英雄ID
* @param newLevel 新等级
*/
public onHeroLevelUp(heroId: number, newLevel: number): void {
const talentManager = this.talentInstances.get(heroId);
if (!talentManager) return;
talentManager.talents.forEach((instance, talId) => {
const talConfig = getTalConf(talId);
if (!talConfig || talConfig.talType !== TalType.LEVEL_ATTR) return;
const levelTrigger = talConfig.trigger as any;
const triggerInterval = levelTrigger.level;
// 检查是否应该触发
if (newLevel % triggerInterval === 0) {
// 检查是否还能堆叠
if (talConfig.maxStack && instance.stackCount >= talConfig.maxStack) {
console.warn(`天赋 ${talConfig.name} 已达到最大堆叠次数`);
return;
}
instance.stackCount++;
instance.lastTriggerLevel = newLevel;
console.log(`[天赋触发] ${talConfig.name}: 堆叠层数 ${instance.stackCount}`);
this.applyTalentEffect(heroId, talConfig, instance);
}
// 处理 resetPerLevel 选项
if ((talConfig.trigger as any).resetPerLevel) {
instance.actionCounter = 0;
instance.damageCounter = 0;
}
});
}
/**
* 处理攻击事件
* @param heroId 英雄ID
* @param damage 造成的伤害值
*/
public onHeroAttack(heroId: number, damage: number): void {
this.handleActionCounter(heroId, TalActionType.ATTACK);
}
/**
* 处理技能释放事件
* @param heroId 英雄ID
* @param skillId 技能ID
*/
public onHeroSkillCast(heroId: number, skillId: number): void {
this.handleActionCounter(heroId, TalActionType.SKILL);
}
/**
* 处理受伤事件
* @param heroId 英雄ID
* @param damage 受到的伤害值
*/
public onHeroDamaged(heroId: number, damage: number): void {
const talentManager = this.talentInstances.get(heroId);
if (!talentManager) return;
talentManager.talents.forEach((instance, talId) => {
const talConfig = getTalConf(talId);
if (!talConfig || talConfig.talType !== TalType.DAMAGE_COUNT_ATTR) return;
const damageTrigger = talConfig.trigger as any;
instance.damageCounter++;
// 检查是否应该触发
if (instance.damageCounter % damageTrigger.count === 0) {
// 检查是否还能堆叠
if (talConfig.maxStack && instance.stackCount >= talConfig.maxStack) {
console.warn(`天赋 ${talConfig.name} 已达到最大堆叠次数`);
return;
}
instance.stackCount++;
console.log(`[天赋触发] ${talConfig.name}: 堆叠层数 ${instance.stackCount}`);
this.applyTalentEffect(heroId, talConfig, instance);
}
});
}
/**
* 处理行为计数
* @private
*/
private handleActionCounter(heroId: number, actionType: TalActionType): void {
const talentManager = this.talentInstances.get(heroId);
if (!talentManager) return;
talentManager.talents.forEach((instance, talId) => {
const talConfig = getTalConf(talId);
if (!talConfig || talConfig.talType !== TalType.ACTION_COUNT_ATTR) return;
const actionTrigger = talConfig.trigger as any;
if (actionTrigger.actionType !== actionType) return;
instance.actionCounter++;
// 检查是否应该触发
if (instance.actionCounter % actionTrigger.count === 0) {
// 检查是否还能堆叠
if (talConfig.maxStack && instance.stackCount >= talConfig.maxStack) {
console.warn(`天赋 ${talConfig.name} 已达到最大堆叠次数`);
return;
}
instance.stackCount++;
console.log(`[天赋触发] ${talConfig.name}: 堆叠层数 ${instance.stackCount}`);
this.applyTalentEffect(heroId, talConfig, instance);
}
});
}
/**
* 应用天赋效果
* @private
*/
private applyTalentEffect(
heroId: number,
talConfig: ItalConf,
instance: HeroTalentInstance
): void {
const effect = talConfig.effect;
switch (effect.type) {
case "attrModify":
this.applyAttrModify(heroId, talConfig);
break;
case "skillTrigger":
this.triggerSkill(heroId, talConfig);
break;
}
}
/**
* 应用属性修改效果
* @private
*/
private applyAttrModify(heroId: number, talConfig: ItalConf): void {
const effect = talConfig.effect as any;
const { attr, value, percent } = effect;
console.log(
`应用属性修改: 英雄${heroId}, 属性${attr}, ` +
`${percent ? '百分比' : '固定值'}: ${value}`
);
// 这里应该调用实际的英雄属性修改系统
// 示例:
// const hero = getHeroData(heroId);
// hero.modifyAttribute(attr, value, percent);
}
/**
* 触发技能效果
* @private
*/
private triggerSkill(heroId: number, talConfig: ItalConf): void {
const effect = talConfig.effect as any;
const { skillId } = effect;
console.log(`自动释放技能: 英雄${heroId}, 技能ID: ${skillId}`);
// 这里应该调用实际的技能释放系统
// 示例:
// const hero = getHeroData(heroId);
// hero.castSkill(skillId);
}
/**
* 获取英雄的天赋实例信息
*/
public getHeroTalentInfo(heroId: number): HeroTalentManager | undefined {
return this.talentInstances.get(heroId);
}
/**
* 获取英雄特定天赋的实例数据
*/
public getHeroTalentInstance(
heroId: number,
talId: number
): HeroTalentInstance | undefined {
const talentManager = this.talentInstances.get(heroId);
return talentManager?.talents.get(talId);
}
}
// ========== 天赋查询工具 ==========
/**
* 天赋查询助手
*/
export class TalentQueryHelper {
/**
* 获取某类型英雄的所有天赋
*/
public static getTalentsByType(talType: TalType): ItalConf[] {
return getTalConfByType(talType);
}
/**
* 获取某属性的所有相关天赋
*/
public static getTalentsByAttribute(attr: TalAttrType): ItalConf[] {
return Object.values(talConf).filter(tal => {
const effect = tal.effect as any;
return effect.type === "attrModify" && effect.attr === attr;
});
}
/**
* 获取基于某行为的所有天赋
*/
public static getTalentsByAction(actionType: TalActionType): ItalConf[] {
return Object.values(talConf).filter(tal => {
const trigger = tal.trigger as any;
return (
(trigger.type === "actionCount" && trigger.actionType === actionType) ||
(trigger.type === "damageCount")
);
});
}
/**
* 获取所有可堆叠的天赋
*/
public static getStackableTalents(): ItalConf[] {
return Object.values(talConf).filter(tal => tal.stackable !== false);
}
/**
* 获取所有技能触发类天赋
*/
public static getSkillTriggerTalents(): ItalConf[] {
return getTalConfByType(TalType.ACTION_TRIGGER_SKILL);
}
/**
* 打印所有天赋信息(调试用)
*/
public static printAllTalents(): void {
console.log("========== 所有天赋配置 ==========");
Object.values(talConf).forEach(tal => {
console.log(`[${tal.talId}] ${tal.name}`);
console.log(` 类型: ${this.getTalTypeString(tal.talType)}`);
console.log(` 描述: ${tal.desc}`);
console.log(` 可堆叠: ${tal.stackable !== false ? "是" : "否"}`);
if (tal.maxStack) {
console.log(` 最大堆叠: ${tal.maxStack}`);
}
});
}
/**
* 获取天赋类型的字符串表示
* @private
*/
private static getTalTypeString(talType: TalType): string {
const typeMap: Record<number, string> = {
[TalType.LEVEL_ATTR]: "等级属性",
[TalType.ACTION_COUNT_ATTR]: "行为计数属性",
[TalType.DAMAGE_COUNT_ATTR]: "受伤计数属性",
[TalType.ACTION_TRIGGER_SKILL]: "技能触发",
};
return typeMap[talType] || "未知";
}
}
// ========== 使用示例 ==========
/**
* 示例:初始化和使用天赋系统
*/
export class TalentSystemExample {
private triggerManager = new TalentTriggerManager();
/**
* 示例:初始化英雄刘邦的天赋
*/
public initLiuBangTalents(): void {
const liuBangId = 5001;
const talentIds = [7001, 7202]; // 剑意提升 + 防御强化
console.log("初始化刘邦的天赋系统...");
this.triggerManager.initHeroTalents(liuBangId, talentIds);
}
/**
* 示例:模拟刘邦升级流程
*/
public simulateLevelUp(): void {
const liuBangId = 5001;
console.log("\n--- 刘邦升级模拟 ---");
for (let level = 1; level <= 20; level++) {
this.triggerManager.onHeroLevelUp(liuBangId, level);
}
}
/**
* 示例:模拟战斗中的天赋触发
*/
public simulateCombat(): void {
const liuBangId = 5001;
console.log("\n--- 战斗模拟 ---");
// 模拟攻击
for (let i = 0; i < 25; i++) {
this.triggerManager.onHeroAttack(liuBangId, 50);
}
// 模拟受伤
for (let i = 0; i < 15; i++) {
this.triggerManager.onHeroDamaged(liuBangId, 30);
}
// 查询当前天赋状态
const talentInfo = this.triggerManager.getHeroTalentInfo(liuBangId);
if (talentInfo) {
console.log("\n当前天赋状态:");
talentInfo.talents.forEach((instance, talId) => {
const talConfig = getTalConf(talId);
console.log(
`${talConfig?.name}: 堆叠 ${instance.stackCount}` +
` (计数: 行为${instance.actionCounter}, 受伤${instance.damageCounter})`
);
});
}
}
/**
* 示例:查询天赋信息
*/
public queryTalentInfo(): void {
console.log("\n--- 天赋查询示例 ---");
// 查询所有等级类天赋
const levelTals = TalentQueryHelper.getTalentsByType(TalType.LEVEL_ATTR);
console.log(`\n等级类天赋 (${levelTals.length}个):`);
levelTals.forEach(tal => console.log(` - ${tal.name}`));
// 查询与攻击相关的天赋
const attackTals = TalentQueryHelper.getTalentsByAction(TalActionType.ATTACK);
console.log(`\n与攻击相关的天赋 (${attackTals.length}个):`);
attackTals.forEach(tal => console.log(` - ${tal.name}`));
// 查询所有技能触发类天赋
const skillTals = TalentQueryHelper.getSkillTriggerTalents();
console.log(`\n技能触发类天赋 (${skillTals.length}个):`);
skillTals.forEach(tal => console.log(` - ${tal.name}`));
// 打印所有天赋
TalentQueryHelper.printAllTalents();
}
}
// ========== 全局单例 ==========
/** 全局天赋触发管理器实例 */
export const globalTalentManager = new TalentTriggerManager();
/**
* 快捷函数:初始化英雄天赋
*/
export function initHeroTalents(heroId: number, talentIds: number[]): void {
globalTalentManager.initHeroTalents(heroId, talentIds);
}
/**
* 快捷函数:处理英雄升级
*/
export function onHeroLevelUp(heroId: number, newLevel: number): void {
globalTalentManager.onHeroLevelUp(heroId, newLevel);
}
/**
* 快捷函数:处理英雄攻击
*/
export function onHeroAttack(heroId: number, damage: number): void {
globalTalentManager.onHeroAttack(heroId, damage);
}
/**
* 快捷函数:处理技能释放
*/
export function onHeroSkillCast(heroId: number, skillId: number): void {
globalTalentManager.onHeroSkillCast(heroId, skillId);
}
/**
* 快捷函数:处理英雄受伤
*/
export function onHeroDamaged(heroId: number, damage: number): void {
globalTalentManager.onHeroDamaged(heroId, damage);
}