From 3710f7f69563c66d1add04dd70ef113b9d519876 Mon Sep 17 00:00:00 2001 From: walkpan Date: Tue, 28 Oct 2025 00:07:50 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E8=8B=B1=E9=9B=84=E7=B3=BB=E7=BB=9F):=20?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=A4=A9=E8=B5=8B=E7=BB=84=E4=BB=B6=E5=8F=8A?= =?UTF-8?q?=E9=85=8D=E5=A5=97=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 实现英雄天赋系统核心功能,包括: 1. 新增 TalComp 组件管理天赋的获取、触发和效果应用 2. 重构 TalSet 配置结构,完善天赋类型和效果枚举 3. 在 Hero/Monster 实体中集成天赋组件 4. 为 SkillConComp 和 HeroViewComp 添加天赋相关引用 --- assets/script/game/common/config/TalSet.ts | 103 ++++++++----- assets/script/game/hero/Hero.ts | 5 +- assets/script/game/hero/HeroViewComp.ts | 3 + assets/script/game/hero/Mon.ts | 3 + assets/script/game/hero/SkillConComp.ts | 3 + assets/script/game/hero/TalComp.ts | 170 +++++++++++++++++++++ assets/script/game/hero/TalComp.ts.meta | 9 ++ 7 files changed, 255 insertions(+), 41 deletions(-) create mode 100644 assets/script/game/hero/TalComp.ts create mode 100644 assets/script/game/hero/TalComp.ts.meta diff --git a/assets/script/game/common/config/TalSet.ts b/assets/script/game/common/config/TalSet.ts index fadc6ccf..54b4be33 100644 --- a/assets/script/game/common/config/TalSet.ts +++ b/assets/script/game/common/config/TalSet.ts @@ -3,7 +3,8 @@ * 支持定义英雄的特殊能力或特性 */ -import { Attrs } from "./HeroAttrs"; +import { Attrs, BType } from "./HeroAttrs"; +import { SkillSet } from "./SkillSet"; // ========== 枚举定义 ========== @@ -11,20 +12,21 @@ import { Attrs } from "./HeroAttrs"; * 天赋类型枚举,也是触发条件 */ export enum TalType { - LEVEL_TRIGGER = 1, // 基于等级触发 - ACTION_COUNT_TRIGGER = 2, // 基于普通攻击触发, skills[0]计数触发 - SKILL_COUNT_TRIGGER = 3, // 基于技能触发, > skills[0]计数触发 - DAMAGE_COUNT_TRIGGER = 4, // 基于受伤次数触发 - INIT_TRIGGER = 5, // 初始触发,如:多1个技能 - DEAD_TRIGGER = 6 // 基于死亡触发 + LEVEL = 1, // 基于特定等级触发 + LEVEL_UP = 2, // 基于等级升级触发 + ACTION_COUNT = 3, // 基于普通攻击触发, skills[0]计数触发 + SKILL_COUNT = 4, // 基于技能触发, > skills[0]计数触发 + DAMAGE_COUNT = 5, // 基于受伤次数触发 + INIT = 6, // 初始触发,如:多1个技能 + DEAD = 7 // 基于死亡触发 } /** * 触发效果 */ -export enum TalEffectType { - ATTR_MODIFY = 1, // 属性修改 - SKILL_TRIGGER = 2, // 技能触发 +export enum TalEType { + ATTRS = 1, // 属性修改 + SKILL = 2, // 技能触发 SKILL_MORE = 3, // 天生多1个技能 } @@ -35,14 +37,18 @@ export enum TalEffectType { * 定义一个完整的天赋效果 */ export interface ItalConf { - talId: number; // 天赋ID + uuid: number; // 天赋ID name: string; // 天赋名称 desc: string; // 天赋描述(说明触发条件和效果) type: TalType; - triggerType: TalEffectType; // 触发效果类型 + triggerType: TalEType; // 触发效果类型 + chance: number; // 触发概率,默认100,`0-100`之间的数字 t_value: number; // 触发的阈值(如5级触发一次, 5次攻击触发一次,初始触发) e_value: number; // 触发的效果值(如增加10%攻击力, 触发的技能uuid,增加1个技能uuid) - e_count?: number; // 触发效果的累计次数(如触发2次技能实现召唤2个召唤物) + e_name: number; // 触发的特殊值,如具体属性类型, 0表示没有特定值,对应Attrs枚举 + e_type: BType; // 效果类型, 主要针对属性修改,是百分比还是固定值 + e_scaling: number; // 效果随等级缩放系数,默认1, 0.5表示效果随等级减半 + e_count: number; // 触发效果的累计次数(如触发2次技能实现召唤2个召唤物) stackable?: boolean; // 是否可堆叠效果(默认true) maxStack?: number; // 最大堆叠次数(不设置表示无限制) } @@ -50,8 +56,12 @@ export interface ItalConf { // ========== 天赋配置表 ========== /** - * 天赋配置表 - 一维数组格式 - * 存储所有天赋的配置信息,采用2行紧凑格式 + * 天赋配置表 - 2行紧凑格式 + * 每个天赋配置压缩为2行:注释行 + 配置对象行 + * + * 格式说明: + * 第1行:// 天赋名称 - 英雄专属/通用 | 触发条件 | 效果描述 + * 第2行:{uuid, name, desc, type, triggerType, chance, t_value, e_value, e_name, e_type, e_scaling, e_count, stackable, maxStack} * * 使用说明: * 1. 等级类天赋:当英雄升级到指定等级时,每次都会触发效果 @@ -59,32 +69,47 @@ export interface ItalConf { * 3. 受伤计数类:当受伤累计达到阈值时触发,支持是否重置计数 * 4. 技能触发类:当特定条件满足时自动触发指定技能 */ -export const talConf: ItalConf[] = [ +export const talConf: Record = { // ========== 等级类天赋 ========== - /** - * 剑意提升 - 刘邦专属 - * 每升5级,攻击力增加10% - */ - -]; + // 剑意提升 - 刘邦专属 | 每5级 | 攻击力+10% + 7001: {uuid: 7001, name: "剑意提升", desc: "每升5级,攻击力增加10%", type: TalType.LEVEL_UP, triggerType: TalEType.ATTRS, + chance: 100, t_value: 5, e_value: 0.10, e_name: Attrs.AP, e_type: BType.RATIO, e_scaling: 1, e_count: 1, stackable: true, maxStack: 10}, + + // 胡服骑射 - 赵武灵王专属 | 每3级 | 攻击速度+5% + 7002: {uuid: 7002, name: "胡服骑射", desc: "每升3级,攻击速度增加5%", type: TalType.LEVEL_UP, triggerType: TalEType.ATTRS, + chance: 100, t_value: 3, e_value: 0.05, e_name: Attrs.AS, e_type: BType.RATIO, e_scaling: 1.2, e_count: 1, stackable: true, maxStack: 15}, + + // 运筹帷幄 - 张良专属 | 每4级 | 魔法攻击力+8% + 7004: {uuid: 7004, name: "运筹帷幄", desc: "每升4级,魔法攻击力增加8%", type: TalType.LEVEL_UP, triggerType: TalEType.ATTRS, + chance: 100, t_value: 4, e_value: 0.08, e_name: Attrs.MAP, e_type: BType.RATIO, e_scaling: 1.3, e_count: 1, stackable: true, maxStack: 12}, + + // 后勤保障 - 萧何专属 | 每6级 | 生命回复+3点 + 7006: {uuid: 7006, name: "后勤保障", desc: "每升6级,生命回复增加3点", type: TalType.LEVEL_UP, triggerType: TalEType.ATTRS, + chance: 100, t_value: 6, e_value: 3, e_name: Attrs.HP_REGEN, e_type: BType.VALUE, e_scaling: 1, e_count: 1, stackable: true, maxStack: 8}, + + // 离骚诗韵 - 屈原专属 | 每8次攻击 | 火焰伤害+2% + 7101: {uuid: 7101, name: "离骚诗韵", desc: "每攻击8次,触发火焰buff,火焰山航海加成增加2%,持续10秒", type: TalType.ACTION_COUNT, triggerType: TalEType.SKILL, + chance: 100, t_value: 8, e_value: SkillSet[6005].uuid, e_name: 0, e_type: BType.VALUE, e_scaling: 1, e_count: 1, stackable: true, maxStack: 15}, + + // ========== 初始触发类天赋 ========== + // 霸王之威 - 项羽专属 | 初始 | 生命值+100 + 7201: {uuid: 7201, name: "霸王之威", desc: "初始获得额外100点生命值", type: TalType.INIT, triggerType: TalEType.ATTRS, + chance: 100, t_value: 1, e_value: 100, e_name: Attrs.HP_MAX, e_type: BType.VALUE, e_scaling: 1, e_count: 1, stackable: false}, + // 兵圣之道 - 孙武专属 | 初始 | 额外技能 + 7202: {uuid: 7202, name: "兵圣之道", desc: "初始获得额外一个技能", type: TalType.INIT, triggerType: TalEType.SKILL_MORE, + chance: 100, t_value: 1, e_value: SkillSet[6005].uuid, e_name: 0, e_type: BType.VALUE, e_scaling: 1, e_count: 1, stackable: false}, + + // ========== 受伤触发类天赋 ========== + // 坚韧意志 - 通用 | 每3次受伤 | 防御力+2点 + 7301: {uuid: 7301, name: "坚韧意志", desc: "每受伤3次,50%纪律,触发[坚韧意志],防御力增加2点,持续10秒", type: TalType.DAMAGE_COUNT, triggerType: TalEType.SKILL, + chance: 50, t_value: 3, e_value: SkillSet[6005].uuid, e_name: 0, e_type: BType.VALUE, e_scaling: 1, e_count: 1, stackable: true, maxStack: 12}, + // ========== 特定等级触发类天赋 ========== + // 坚韧意志 - 通用 | 每3次受伤 | 防御力+2点 + 7401: {uuid: 7401, name: "坚韧意志", desc: "20级是获得[坚韧意志]技能,防御力增加2点,持续10秒", type: TalType.LEVEL, triggerType: TalEType.SKILL_MORE, + chance: 100, t_value: 20, e_value: SkillSet[6005].uuid, e_name: 0, e_type: BType.VALUE, e_scaling: 1, e_count: 1, stackable: true, maxStack: 12}, + + }; // ========== 工具函数 ========== -/** - * 根据天赋ID获取天赋配置 - * @param talId 天赋ID - * @returns 天赋配置,不存在返回undefined - */ -export const getTalConf = (talId: number): ItalConf | undefined => { - return talConf.find(tal => tal.talId === talId); -}; - - -/** - * 获取所有天赋ID列表 - * @returns 天赋ID数组 - */ -export const getAllTalIds = (): number[] => { - return talConf.map(tal => tal.talId); -}; diff --git a/assets/script/game/hero/Hero.ts b/assets/script/game/hero/Hero.ts index 6f3c2bea..cd5c9823 100644 --- a/assets/script/game/hero/Hero.ts +++ b/assets/script/game/hero/Hero.ts @@ -11,6 +11,7 @@ import { GameEvent } from "../common/config/GameEvent"; import { SkillSet } from "../common/config/SkillSet"; import { time } from "console"; import { getNeAttrs, getAttrs ,Attrs} from "../common/config/HeroAttrs"; +import { TalComp } from "./TalComp"; /** 角色实体 */ @ecs.register(`Hero`) @@ -22,14 +23,14 @@ export class Hero extends ecs.Entity { this.addComponents( BattleMoveComp, HeroModelComp, + TalComp ); } destroy(): void { this.remove(HeroViewComp); this.remove(HeroModelComp); - - + this.remove(TalComp); super.destroy(); } diff --git a/assets/script/game/hero/HeroViewComp.ts b/assets/script/game/hero/HeroViewComp.ts index 2210af53..dafd8acc 100644 --- a/assets/script/game/hero/HeroViewComp.ts +++ b/assets/script/game/hero/HeroViewComp.ts @@ -13,6 +13,7 @@ import { FightSet, TooltipTypes } from "../common/config/Mission"; import { RandomManager } from "db://oops-framework/core/common/random/RandomManager"; import { AttrSet, HeroInfo, HeroUpSet } from "../common/config/heroSet"; import { Attrs, AttrsType, BType, NeAttrs } from "../common/config/HeroAttrs"; +import { TalComp } from "./TalComp"; const { ccclass, property } = _decorator; /** @@ -73,6 +74,7 @@ export interface BuffInfo { @ecs.register('HeroView', false) // 定义ECS 组件 export class HeroViewComp extends CCComp { BUFFCOMP:BuffComp=null! + TALCOMP:any=null! as: HeroSpine = null! status:String = "idle" hero_uuid:number = 1001; @@ -143,6 +145,7 @@ export class HeroViewComp extends CCComp { start () { this.as.idle() this.BUFFCOMP=this.node.getComponent(BuffComp); + this.TALCOMP=this.node.getComponent(TalComp); // console.log("[HeroViewComp]:heroview"+this.hero_name,this.Attrs) /** 方向 */ this.node.setScale(this.scale,1); diff --git a/assets/script/game/hero/Mon.ts b/assets/script/game/hero/Mon.ts index f3eda510..eaf20c56 100644 --- a/assets/script/game/hero/Mon.ts +++ b/assets/script/game/hero/Mon.ts @@ -10,6 +10,7 @@ import { BattleMoveComp } from "../common/ecs/position/BattleMoveComp"; import { SkillConComp } from "./SkillConComp"; import { SkillSet } from "../common/config/SkillSet"; import { getNeAttrs, getAttrs ,Attrs} from "../common/config/HeroAttrs"; +import { TalComp } from "./TalComp"; /** 角色实体 */ @ecs.register(`Monster`) export class Monster extends ecs.Entity { @@ -21,12 +22,14 @@ export class Monster extends ecs.Entity { this.addComponents( BattleMoveComp, MonModelComp, + TalComp, ); } destroy(): void { this.remove(HeroViewComp); this.remove(MonModelComp); + this.remove(TalComp); super.destroy(); } diff --git a/assets/script/game/hero/SkillConComp.ts b/assets/script/game/hero/SkillConComp.ts index 611cd761..b360cc2a 100644 --- a/assets/script/game/hero/SkillConComp.ts +++ b/assets/script/game/hero/SkillConComp.ts @@ -10,6 +10,7 @@ import { MonModelComp } from './MonModelComp'; import { HeroModelComp } from './HeroModelComp'; import { SkillEnt } from '../skill/SkillEnt'; import { Attrs } from '../common/config/HeroAttrs'; +import { TalComp } from './TalComp'; const { ccclass, property } = _decorator; @ccclass('SkillCon') @@ -17,6 +18,7 @@ const { ccclass, property } = _decorator; export class SkillConComp extends CCComp { HeroView:any=null; HeroEntity:any=null; + TALCOMP:any=null; skill_cd=0 private _timers: { [key: string]: any } = {}; init(): void { @@ -24,6 +26,7 @@ export class SkillConComp extends CCComp { } onLoad(){ this.HeroView=this.node.getComponent(HeroViewComp) + this.TALCOMP=this.node.getComponent(TalComp) } start() { this.HeroEntity=this.HeroView.ent diff --git a/assets/script/game/hero/TalComp.ts b/assets/script/game/hero/TalComp.ts new file mode 100644 index 00000000..35131f6a --- /dev/null +++ b/assets/script/game/hero/TalComp.ts @@ -0,0 +1,170 @@ +import { _decorator } from "cc"; +import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS"; +import { CCComp } from "../../../../extensions/oops-plugin-framework/assets/module/common/CCComp"; +import { ItalConf, TalType, TalEType, talConf } from "../common/config/TalSet"; +import { BuffConf, SkillSet } from "../common/config/SkillSet"; +import { HeroInfo } from "../common/config/heroSet"; + +const { ccclass } = _decorator; + +/** + * 天赋触发统计接口 + * 记录各种触发条件的计数器,用于判断天赋是否满足触发条件 + */ +interface FightStats { + aCount: number; // 普通攻击计数 - 用于 ACTION_COUNT 类型天赋 + sCount: number; // 技能使用计数 - 用于 SKILL_COUNT 类型天赋 + dCount: number; // 受伤次数计数 - 用于 DAMAGE_COUNT 类型天赋 + level: number; // 当前等级 - 用于 LEVEL/LEVEL_UP 类型天赋 +} + +/** + * 天赋效果实例接口 + * 记录已激活天赋的当前状态,包括堆叠层数和最后触发时间 + */ +interface TalEffect { + uuid: number; // 天赋uuid + stack: number; // 当前堆叠层数,用于可堆叠天赋 + lTTime: number; // 上次触发时间戳,可用于时效判断 +} + +/** + * 天赋系统组件类 + * 继承自 CCComp,作为 ECS 架构中的组件存在 + * 负责管理英雄的天赋系统,包括天赋获取、触发、效果应用等 + */ +@ccclass('TalComp') +@ecs.register('TalComp', false) +export class TalComp extends CCComp { + /** 英雄视图组件引用,运行时获取避免循环引用 */ + private heroView: any = null; + private skillCon:any=null; + /** 英雄唯一标识符,用于从配置中获取英雄信息 */ + private heroUuid: number = 0; + + /** 天赋触发统计,记录各种触发条件的当前状态 */ + private FStats: FightStats = { aCount: 0, sCount: 0, dCount: 0, level: 1 }; + + /** 活跃天赋效果映射,存储已激活的天赋实例 */ + private activeTals: TalEffect[] = []; + private talEffects: ItalConf[] = []; + /** 初始化标志,防止重复初始化 */ + private isInitialized: boolean = false; + + /** + * 组件生命周期函数 - 启动时调用 + * 获取英雄视图组件并初始化天赋系统 + */ + start() { + // 运行时获取组件,避免编译时循环引用 + this.heroView = this.node.getComponent("HeroViewComp" as any); + this.skillCon = this.node.getComponent("SkillConComp" as any); + if (this.heroView) { + this.heroUuid = this.heroView.hero_uuid; + this.initializeTalents(); + } + } + + private initializeTalents(): void { + if (this.isInitialized || !this.heroView) return; + this.FStats.level = this.heroView.lv || 1; + this.getHeroTalents() + this.isInitialized = true; + } + + private getHeroTalents(): ItalConf[] { + this.activeTals = []; + this.talEffects = []; + if (!this.heroView) return []; + const heroInfo = HeroInfo[this.heroUuid]; + if (!heroInfo?.tal) return []; + for(let id of heroInfo.tal){ + let conf = talConf[id]; + if(conf){ + this.talEffects.push(conf) + } + } + } + + private doTalEffect(tal:ItalConf){ + console.log("doTalEffect",tal) + if(tal.triggerType == TalEType.ATTRS){ + console.log("doTalEffect ATTRS",tal) + let buff:BuffConf = { + buff:tal.e_name, + BType:tal.e_type, + value:tal.e_value, + time:0, + chance:tal.chance, + } + this.heroView.addBuff(buff) + } + + if(tal.triggerType == TalEType.SKILL){ + console.log("doTalEffect SKILL",tal) + let skill = SkillSet[tal.e_value]; + if(this.skillCon){ + this.skillCon.doSkill(skill,false,0) + } + } + + if(tal.triggerType == TalEType.SKILL_MORE){ + console.log("doTalEffect SKILL_MORE",tal) + this.heroView.skills.push(tal.e_value) + } + + } + private checkTrigger(tal:ItalConf) { + let stats = this.FStats; + switch (tal.type) { + case TalType.LEVEL: return stats.level >= tal.t_value; + case TalType.LEVEL_UP: return stats.level % tal.t_value === 0; + case TalType.ACTION_COUNT: return stats.aCount >= tal.t_value; + case TalType.SKILL_COUNT: return stats.sCount >= tal.t_value; + case TalType.DAMAGE_COUNT: return stats.dCount >= tal.t_value; + case TalType.INIT: return true; + case TalType.DEAD: return false; // 单独处理 + default: return false; + } + } + private checkHasTal(TalType:TalType) { + for(let tal of this.talEffects){ + if(TalType == tal.type){ + if (this.checkTrigger(tal)){ + this.doTalEffect(tal) + } + } + } + } + public onAction(): void { + this.FStats.aCount++; + this.checkHasTal(TalType.ACTION_COUNT); + } + + public onSkillUse(): void { + this.FStats.sCount++; + this.checkHasTal(TalType.SKILL_COUNT); + } + + public onDamageTaken(): void { + this.FStats.dCount++; + this.checkHasTal(TalType.DAMAGE_COUNT); + } + + public onLevelUp(newLevel: number): void { + this.FStats.level = newLevel; + this.checkHasTal(TalType.LEVEL); + this.checkHasTal(TalType.LEVEL_UP); + } + + public onDeath(): void { + this.checkHasTal(TalType.DEAD); + } + + + + reset() { + this.isInitialized = false; + this.node.destroy(); + } +} \ No newline at end of file diff --git a/assets/script/game/hero/TalComp.ts.meta b/assets/script/game/hero/TalComp.ts.meta new file mode 100644 index 00000000..52c6de0e --- /dev/null +++ b/assets/script/game/hero/TalComp.ts.meta @@ -0,0 +1,9 @@ +{ + "ver": "4.0.24", + "importer": "typescript", + "imported": true, + "uuid": "5944233e-8492-4880-9084-77083cfdf326", + "files": [], + "subMetas": {}, + "userData": {} +}