From 071afc8fa2d0749dc866f1f4bedf67414784d4c6 Mon Sep 17 00:00:00 2001 From: panFD Date: Sat, 5 Sep 2026 12:22:18 +0800 Subject: [PATCH] =?UTF-8?q?feat(skill):=20=E6=B7=BB=E5=8A=A0=E8=AE=A1?= =?UTF-8?q?=E6=97=B6buff=E7=9B=AE=E6=A0=87=E8=A6=86=E5=86=99=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 新增BuffTarget枚举定义计时buff的四种施加目标类型 2. 扩展SkillOverrides接口添加buff_target配置项 3. 实现resolveBuffTargets方法解析buff实际施加目标 4. 调整普攻buff施加逻辑适配新的目标配置规则 5. 修复伤害技能误给敌方挂友方buff的问题 6. 清理英雄技能配置中多余的summon_count参数 --- assets/script/game/common/config/SkillSet.ts | 14 +++++++ assets/script/game/common/config/heroSet.ts | 18 ++++----- assets/script/game/hero/HeroAtkSystem.ts | 40 ++++++++++++++++++-- assets/script/game/hero/SCastSystem.ts | 5 ++- 4 files changed, 63 insertions(+), 14 deletions(-) diff --git a/assets/script/game/common/config/SkillSet.ts b/assets/script/game/common/config/SkillSet.ts index d8ddaae7..ae0e0757 100644 --- a/assets/script/game/common/config/SkillSet.ts +++ b/assets/script/game/common/config/SkillSet.ts @@ -20,6 +20,18 @@ export enum DTType { range = 1, } +/** + * 计时 buff(timed_buff_id)的施加目标。 + * 缺省(undefined)时按技能主效果推导:伤害技能挂被命中者,辅助技能挂友方目标。 + * 显式配置后打破 TGroup 默认绑定,实现"伤害技能命中后给自己回血"等跨阵营效果。 + */ +export enum BuffTarget { + Hit = 0, // 被命中者(敌方技能的默认行为) + Self = 1, // 施法者自身 + Ally = 2, // 全体友方(含施法者) + Enemy = 3, // 全体敌方(辅助技能给敌人挂 debuff 用) +} + export enum SkillKind { Damage = 0, Heal = 1, @@ -178,6 +190,8 @@ export interface SkillOverrides { buff_value?: number; buff_duration?: number; buff_chance?: number; + /** 计时 buff 施加目标覆写:缺省按技能主效果推导(伤害→被命中者,辅助→友方) */ + buff_target?: BuffTarget; call_hero?: number; /** 单次施法召唤的技能实体个数(覆盖 prefab 上 SkillView.summon_count;>1 视为召唤类,不再参与风怒等额外触发) */ summon_count?: number; diff --git a/assets/script/game/common/config/heroSet.ts b/assets/script/game/common/config/heroSet.ts index d3d55f1d..bc1e900b 100644 --- a/assets/script/game/common/config/heroSet.ts +++ b/assets/script/game/common/config/heroSet.ts @@ -599,10 +599,10 @@ export const HeroInfo: Record = { { lv: 2, s_lv: SkillLv.Lv2, overrides: {"stun":10}, desc: "挥斧对{target}造成攻击力{ap}%伤害,{stun}%概率击晕" }, ], }, - 6104: { uuid: 6104, name: "开山斧", lv: 1, cd: 8, ccd: 0, overrides: {"ap":300,"stun":100,"summon_count":1}, desc: "劈出开山斧,对{target}造成攻击力{ap}%伤害,必定击晕", + 6104: { uuid: 6104, name: "开山斧", lv: 1, cd: 8, ccd: 0, overrides: {"ap":300,"stun":100}, desc: "劈出开山斧,对{target}造成攻击力{ap}%伤害,必定击晕", lv_entries: [ - { lv: 8, s_lv: SkillLv.Lv2, overrides: {"ap":450,"stun":100,"summon_count":1} }, - { lv: 16, s_lv: SkillLv.Lv3, overrides: {"ap":450,"stun":100,"summon_count":2} }, + { lv: 8, s_lv: SkillLv.Lv2, overrides: {"ap":450,"stun":100} }, + { lv: 16, s_lv: SkillLv.Lv3, overrides: {"ap":450,"stun":100} }, ], }, }, @@ -620,10 +620,10 @@ export const HeroInfo: Record = { { lv: 2, s_lv: SkillLv.Lv2, overrides: {"crt":10}, desc: "挥刀对{target}造成攻击力{ap}%伤害,{crt}%概率暴击" }, ], }, - 6100: { uuid: 6100, name: "光闪", lv: 1, cd: 8, ccd: 0, overrides: {"ap":150,"summon_count":1}, desc: "斩出光闪,对{target}造成攻击力{ap}%伤害", + 6100: { uuid: 6100, name: "光闪", lv: 1, cd: 8, ccd: 0, overrides: {"ap":150}, desc: "斩出光闪,对{target}造成攻击力{ap}%伤害", lv_entries: [ - { lv: 8, s_lv: SkillLv.Lv2, overrides: {"ap":250,"summon_count":1} }, - { lv: 16, s_lv: SkillLv.Lv3, overrides: {"ap":350,"summon_count":2} }, + { lv: 8, s_lv: SkillLv.Lv2, overrides: {"ap":250} }, + { lv: 16, s_lv: SkillLv.Lv3, overrides: {"ap":350} }, ], }, }, @@ -641,10 +641,10 @@ export const HeroInfo: Record = { { lv: 2, s_lv: SkillLv.Lv2, overrides: {"timed_buff_id":7007,"buff_value":30,"buff_chance":30}, desc: "挥刀对{target}造成攻击力{ap}%伤害,{buff_chance}%概率使目标出血(每0.5秒受到{buff_value}点伤害,持续{dur}秒)" }, ], }, - 6103: { uuid: 6103, name: "闪电斩", lv: 1, cd: 8, ccd: 0, overrides: {"ap":150,"summon_count":1}, desc: "召唤落雷斩击{target},造成攻击力{ap}%伤害", + 6103: { uuid: 6103, name: "闪电斩", lv: 1, cd: 8, ccd: 0, overrides: {"ap":150}, desc: "召唤落雷斩击{target},造成攻击力{ap}%伤害", lv_entries: [ - { lv: 8, s_lv: SkillLv.Lv2, overrides: {"ap":250,"timed_buff_id":7007,"summon_count":1}, desc: "召唤落雷斩击{target},造成攻击力{ap}%伤害,并使目标出血(每0.5秒受到{buff_value}点伤害,持续{dur}秒)" }, - { lv: 16, s_lv: SkillLv.Lv3, overrides: {"ap":350,"para":50,"timed_buff_id":7007,"buff_value":60,"summon_count":2}, desc: "召唤落雷斩击{target},造成攻击力{ap}%伤害,{para}%概率麻痹,并使目标出血(每0.5秒受到{buff_value}点伤害,持续{dur}秒)" }, + { lv: 8, s_lv: SkillLv.Lv2, overrides: {"ap":250,"timed_buff_id":7007}, desc: "召唤落雷斩击{target},造成攻击力{ap}%伤害,并使目标出血(每0.5秒受到{buff_value}点伤害,持续{dur}秒)" }, + { lv: 16, s_lv: SkillLv.Lv3, overrides: {"ap":350,"para":50,"timed_buff_id":7007,"buff_value":60}, desc: "召唤落雷斩击{target},造成攻击力{ap}%伤害,{para}%概率麻痹,并使目标出血(每0.5秒受到{buff_value}点伤害,持续{dur}秒)" }, ], }, }, diff --git a/assets/script/game/hero/HeroAtkSystem.ts b/assets/script/game/hero/HeroAtkSystem.ts index 946d676f..684d44d1 100644 --- a/assets/script/game/hero/HeroAtkSystem.ts +++ b/assets/script/game/hero/HeroAtkSystem.ts @@ -11,7 +11,7 @@ import { HeroInfo } from "../common/config/heroSet"; import { oops } from "db://oops-framework/core/Oops"; import { GameEvent } from "../common/config/GameEvent"; import { SkillTriggerType } from "../common/config/heroSet"; -import { FieldSkillType } from "../common/config/SkillSet"; +import { FieldSkillType, BuffTarget } from "../common/config/SkillSet"; import { mLogger } from "../common/Logger"; import { SkillTriggerHelper } from "./SkillTriggerHelper"; @@ -257,7 +257,7 @@ export class HeroAtkSystem extends ecs.ComblockSystem implements ecs.ISystemUpda } } - // 命中附带 debuff(如灼烧 DoT):仅普攻路径,复用友方 timed_buff_id 机制; + // 命中附带 buff:仅普攻路径;buff_target 缺省挂被命中者,显式配置可改为挂施法者/全体友方/全体敌方 // 施法者 ap/完整属性快照取自伤害事件,供 BuffSystem tick 缩放与暴击/冰冻/击晕判定 if (!isDot && skillConf.timed_buff_id) { const buffChance = skillConf.buff_chance ?? 100; @@ -265,7 +265,9 @@ export class HeroAtkSystem extends ecs.ComblockSystem implements ecs.ISystemUpda const buffOverrides: BuffApplyOverrides = { source_attrs: damageEvent.Attrs }; if (skillConf.buff_value !== undefined) buffOverrides.value = skillConf.buff_value; if (skillConf.buff_duration !== undefined) buffOverrides.duration = skillConf.buff_duration; - buffManager.applyBuff(target, skillConf.timed_buff_id, casterEid, damageEvent.Attrs[Attrs.ap] || 0, buffOverrides); + for (const buffTarget of this.resolveBuffTargets(target, casterEid, TAttrsComp.fac, skillConf.buff_target)) { + buffManager.applyBuff(buffTarget, skillConf.timed_buff_id, casterEid, damageEvent.Attrs[Attrs.ap] || 0, buffOverrides); + } } } @@ -527,6 +529,38 @@ export class HeroAtkSystem extends ecs.ComblockSystem implements ecs.ISystemUpda return { remainingDamage: damage - absorbed, absorbedDamage: absorbed }; } + /** + * 解析 timed_buff_id 的施加目标实体列表。 + * 缺省(undefined / BuffTarget.Hit)返回被命中者;显式配置可切换到施法者自身、全体友方或全体敌方。 + * @param hitTarget 被命中实体(伤害事件的 target) + * @param casterEid 施法者 eid + * @param targetFac 被命中者阵营(用于推导敌我网格) + * @param buffTarget 技能配置上的目标覆写 + */ + private resolveBuffTargets(hitTarget: ecs.Entity, casterEid: number, targetFac: number, buffTarget?: BuffTarget): ecs.Entity[] { + if (buffTarget === undefined || buffTarget === BuffTarget.Hit) { + return [hitTarget]; + } + if (buffTarget === BuffTarget.Self) { + const caster = ecs.getEntityByEid(casterEid); + return caster ? [caster] : []; + } + // 全体友方/敌方:以施法者阵营为基准(命中者必为敌方,施法方网格即友方) + const casterFac = targetFac === FacSet.HERO ? FacSet.MON : FacSet.HERO; + const grid = buffTarget === BuffTarget.Ally + ? (casterFac === FacSet.HERO ? smc.mission.heroGrid : smc.mission.monGrid) + : (casterFac === FacSet.HERO ? smc.mission.monGrid : smc.mission.heroGrid); + const targets: ecs.Entity[] = []; + for (const eid of grid) { + if (eid < 0) continue; + const ent = ecs.getEntityByEid(eid); + if (!ent) continue; + const attrs = ent.get(HeroAttrsComp); + if (attrs && !attrs.is_dead && !attrs.is_reviving) targets.push(ent); + } + return targets; + } + /** * 被攻击时触发的事件 * diff --git a/assets/script/game/hero/SCastSystem.ts b/assets/script/game/hero/SCastSystem.ts index 259954dd..f2dfcfe2 100644 --- a/assets/script/game/hero/SCastSystem.ts +++ b/assets/script/game/hero/SCastSystem.ts @@ -2,7 +2,7 @@ import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ec import { Vec3, Prefab, instantiate, tween, Node } from "cc"; import { HeroAttrsComp } from "./HeroAttrsComp"; import { HeroViewComp } from "./HeroViewComp"; -import { DTType, RType, SkillConfig, SkillKind, SkillSet, TGroup, SkillOverrides, mergeSkillParams } from "../common/config/SkillSet"; +import { DTType, RType, SkillConfig, SkillKind, SkillSet, TGroup, SkillOverrides, mergeSkillParams, BuffTarget } from "../common/config/SkillSet"; import { Skill } from "../skill/Skill"; import { SkillView } from "../skill/SkillView"; import { smc } from "../common/SingletonModuleComp"; @@ -545,7 +545,8 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate if (config.buff_type !== undefined) { // 计时性 buff:配置了 timed_buff_id 时走 buffManager 限时路径, // 同一技能不应既永久加成又限时加成,故提前 return 跳过下方永久 add_* 逻辑 - if (config.timed_buff_id) { + // buff_target=Enemy 时 timed_buff_id 已在 applyFriendlySkillEffects 入口分流到敌方网格,此处跳过避免误挂友方 + if (config.timed_buff_id && config.buff_target !== BuffTarget.Enemy) { // 汇总 buff 覆写参数:value 覆写修饰数值,duration 覆写持续时间 const buffOverrides: { value?: number; duration?: number } = {}; if (config.buff_value !== undefined) buffOverrides.value = config.buff_value;