From aa488d55e7b8bd80c310b87547c9404e93c60d85 Mon Sep 17 00:00:00 2001 From: panFD Date: Mon, 7 Sep 2026 20:41:49 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=E9=97=AA=E9=81=BF?= =?UTF-8?q?=E4=B8=8E=E5=91=BD=E4=B8=AD=E5=B1=9E=E6=80=A7=E7=B3=BB=E7=BB=9F?= =?UTF-8?q?=EF=BC=8C=E5=AE=8C=E5=96=84=E6=88=98=E6=96=97=E5=88=A4=E5=AE=9A?= =?UTF-8?q?=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 新增全局默认闪避/命中率配置,为英雄和怪物提供缺省属性兜底 2. 扩展英雄属性组件,添加闪避、命中率属性与对应计算接口 3. 实现闪避判定逻辑,修正伤害流程,添加闪避提示效果 4. 新增闪避/命中相关buff、技能与光环配置 5. 完善属性值计算与 tooltip 显示逻辑 --- assets/script/game/common/config/BuffSet.ts | 16 +++++++++++ assets/script/game/common/config/GameSet.ts | 5 ++++ assets/script/game/common/config/SkillSet.ts | 24 ++++++++++++++++ assets/script/game/common/config/heroSet.ts | 10 ++++++- assets/script/game/hero/Hero.ts | 3 ++ assets/script/game/hero/HeroAtkSystem.ts | 21 ++++++++++++++ assets/script/game/hero/HeroAttrsComp.ts | 30 ++++++++++++++++++++ assets/script/game/hero/HeroViewComp.ts | 5 ++++ assets/script/game/hero/Mon.ts | 3 ++ assets/script/game/skill/Skill.ts | 1 + assets/script/game/skill/TooltipCom.ts | 6 ++++ 11 files changed, 123 insertions(+), 1 deletion(-) diff --git a/assets/script/game/common/config/BuffSet.ts b/assets/script/game/common/config/BuffSet.ts index 6231bc99..a12c7dd8 100644 --- a/assets/script/game/common/config/BuffSet.ts +++ b/assets/script/game/common/config/BuffSet.ts @@ -287,4 +287,20 @@ export const BuffList: Record = { modifiers: [{ attr: Attrs.hp_max, op: ModOp.PercentAdd, value: 30 }], info: "最大生命值提升 30%,并立即回复等量生命,持续 5 秒", }, + + // ==================== 闪避 / 命中系 ==================== + // 闪避爆发(限时提升闪避概率,百分点累加) + 7030: { + id: 7030, name: "闪避爆发", icon: "98-Enchant-Wind", + category: BuffCategory.Buff, duration: 5, max_stack: 1, + modifiers: [{ attr: Attrs.dodge, op: ModOp.PercentAdd, value: 20 }], + info: "闪避概率提升 20%,持续 5 秒", + }, + // 命中强化(限时提升命中概率,百分点累加) + 7031: { + id: 7031, name: "命中强化", icon: "27-Hawkeye", + category: BuffCategory.Buff, duration: 5, max_stack: 1, + modifiers: [{ attr: Attrs.accuracy, op: ModOp.PercentAdd, value: 20 }], + info: "命中概率提升 20%,持续 5 秒", + }, }; diff --git a/assets/script/game/common/config/GameSet.ts b/assets/script/game/common/config/GameSet.ts index 9ab0d223..31509ae1 100644 --- a/assets/script/game/common/config/GameSet.ts +++ b/assets/script/game/common/config/GameSet.ts @@ -76,6 +76,10 @@ export enum FightSet { INIT_REFRESH_STONE = 3, // 初始刷新石数量 /** 单次刷新消耗的刷新石数量 */ REFRESH_STONE_COST = 1, + /** 全局默认闪避率(百分点),heroSet 未配置时生效 */ + DEFAULT_DODGE = 15, + /** 全局默认命中率(百分点),heroSet 未配置时生效 */ + DEFAULT_ACCURACY = 10, } /** @@ -143,6 +147,7 @@ export const TooltipTypes = { hpup: 8, addmp: 9, shield: 10, + miss: 11, } diff --git a/assets/script/game/common/config/SkillSet.ts b/assets/script/game/common/config/SkillSet.ts index a332e8cd..f1644bb3 100644 --- a/assets/script/game/common/config/SkillSet.ts +++ b/assets/script/game/common/config/SkillSet.ts @@ -455,6 +455,16 @@ export const SkillSet: Record = { DTType: DTType.single, kind: SkillKind.Support, ap: 10, hit_count: 1, hitcd: 0.2, speed: 720, with: 0, ready: 0.2, EAnm: 0, DAnm: "", IType: IType.support, RType: RType.fixed, EType: EType.animationEnd, buff_type: Attrs.thorns_rate, info: "全体友方比例反伤提升10%, 永久生效", }, + 6415: { + uuid: 6415, name: "闪避强化", sp_name: "buff_wind", icon: "98-Enchant-Wind", TGroup: TGroup.Team, readyAnm: "up_blue", endAnm: "", act: "atk", + DTType: DTType.single, kind: SkillKind.Support, ap: 5, hit_count: 1, hitcd: 0.2, speed: 720, with: 0, ready: 0.2, EAnm: 0, DAnm: "", IType: IType.support, + RType: RType.fixed, EType: EType.animationEnd, buff_type: Attrs.dodge, info: "全体友方闪避概率提升5%, 永久生效", + }, + 6416: { + uuid: 6416, name: "命中强化", sp_name: "buff_wind", icon: "27-Hawkeye", TGroup: TGroup.Team, readyAnm: "up_blue", endAnm: "", act: "atk", + DTType: DTType.single, kind: SkillKind.Support, ap: 5, hit_count: 1, hitcd: 0.2, speed: 720, with: 0, ready: 0.2, EAnm: 0, DAnm: "", IType: IType.support, + RType: RType.fixed, EType: EType.animationEnd, buff_type: Attrs.accuracy, info: "全体友方命中概率提升5%, 永久生效", + }, 6501: { uuid: 6501, name: "复活", sp_name: "buff_wind", icon: "40-Holy", TGroup: TGroup.Self, readyAnm: "up_ap", endAnm: "", act: "atk", DTType: DTType.single, kind: SkillKind.Support, ap: 50, hit_count: 3, hitcd: 0.2, speed: 720, with: 0, ready: 0.2, EAnm: 0, DAnm: "", IType: IType.support, @@ -546,6 +556,16 @@ export const SkillSet: Record = { uuid: 6517, name: "生命爆发", sp_name: "buff_wind", icon: "29-Endure", TGroup: TGroup.Team, readyAnm: "up_green", endAnm: "", act: "atk", DTType: DTType.single, kind: SkillKind.Support, ap: 0, hit_count: 3, hitcd: 0.2, speed: 720, with: 0, ready: 0.2, EAnm: 0, DAnm: "", IType: IType.support, RType: RType.fixed, EType: EType.animationEnd, buff_type: Attrs.hp_max, timed_buff_id: 7029, info: "全体友方最大生命值提升30%, 持续5秒", + }, + 6518: { + uuid: 6518, name: "闪避爆发", sp_name: "buff_wind", icon: "98-Enchant-Wind", TGroup: TGroup.Team, readyAnm: "up_blue", endAnm: "", act: "atk", + DTType: DTType.single, kind: SkillKind.Support, ap: 0, hit_count: 3, hitcd: 0.2, speed: 720, with: 0, ready: 0.2, EAnm: 0, DAnm: "", IType: IType.support, + RType: RType.fixed, EType: EType.animationEnd, buff_type: Attrs.dodge, timed_buff_id: 7030, info: "全体友方闪避概率提升20%, 持续5秒", + }, + 6519: { + uuid: 6519, name: "命中强化", sp_name: "buff_wind", icon: "27-Hawkeye", TGroup: TGroup.Team, readyAnm: "up_blue", endAnm: "", act: "atk", + DTType: DTType.single, kind: SkillKind.Support, ap: 0, hit_count: 3, hitcd: 0.2, speed: 720, with: 0, ready: 0.2, EAnm: 0, DAnm: "", IType: IType.support, + RType: RType.fixed, EType: EType.animationEnd, buff_type: Attrs.accuracy, timed_buff_id: 7031, info: "全体友方命中概率提升20%, 持续5秒", } }; //***************驻场技能配置*************** @@ -569,6 +589,8 @@ export enum FieldSkillType { HeroPunctureDmg = 21, // 英雄穿透后伤害加成(百分点;乘算:PUNCTURE_DMG_RATIO * (1 + bonus/100)) HeroThornsDmg = 22, // 英雄固定反伤加成 HeroThornsRate = 23, // 英雄比例反伤加成(百分点) + HeroDodge = 24, // 英雄闪避率加成(百分点) + HeroHit = 25, // 英雄命中率加成(百分点) } export interface FieldSkillConfig { @@ -607,4 +629,6 @@ export const FieldSkillSet: Record = { 7016: { uuid: 7016, name: "鼓舞光环", icon: "64-Prominance", type: FieldSkillType.StartCount, info: "战斗开始触发技能次数提升" }, 7018: { uuid: 7018, name: "连击光环", icon: "74-Satisfaction", type: FieldSkillType.AtkCount, info: "攻击触发技能次数提升" }, 7019: { uuid: 7019, name: "受击光环", icon: "84-Termor", type: FieldSkillType.BeAtkCount, info: "被攻击触发技能次数提升" }, + 7023: { uuid: 7023, name: "闪避光环", icon: "98-Enchant-Wind", type: FieldSkillType.HeroDodge, info: "英雄闪避概率提升" }, + 7024: { uuid: 7024, name: "命中光环", icon: "27-Hawkeye", type: FieldSkillType.HeroHit, info: "英雄命中概率提升" }, }; diff --git a/assets/script/game/common/config/heroSet.ts b/assets/script/game/common/config/heroSet.ts index 1dfdef50..6f67e0f2 100644 --- a/assets/script/game/common/config/heroSet.ts +++ b/assets/script/game/common/config/heroSet.ts @@ -1,4 +1,4 @@ -import { v3 } from "cc" +import { v3 } from "cc" import { BoxSet, FacSet, FightSet } from "./GameSet" import { SkillOverrides, TGroup, SkillSet, FieldSkillSet, SkillConfig, SkillKind, FieldSkillConfig, FieldSkillType, mergeSkillParams } from "./SkillSet" import { BuffList, BuffConfig, ModOp } from "./BuffSet" @@ -414,6 +414,8 @@ export interface heroInfo { [SkillTriggerType.Atked]?: TriggerGrouped; // 受击后触发的技能配置,s_uuid: 技能id, t_num: 触发所需的受击次数 dis?: number; // 攻击距离(像素) speed?: number; // 移动速度(像素/秒) + dodge?: number; // 闪避率(百分点,缺省由初始化处兜底为全局默认值) + accuracy?: number; // 命中率(百分点,缺省由初始化处兜底为全局默认值) skills: Record; // 携带技能ID列表 ap_bonus?: LvBonusEntry[]; // 额外攻击加成(按 lv 升序,运行时累加 ≤英雄等级 的所有档) hp_bonus?: LvBonusEntry[]; // 额外生命加成(按 lv 升序,运行时累加 ≤英雄等级 的所有档) @@ -1257,6 +1259,10 @@ function calcBuffPermanentEquivalent(buff: BuffConfig, apEff: number, cd: number case Attrs.speed: value += (modValue / 100) * dps * weights.W_DPS_PER_SEC * seconds; break; + case Attrs.dodge: + case Attrs.accuracy: + value += modValue * weights.W_control; + break; } } } @@ -1298,6 +1304,8 @@ function calcSupportEffectValue(config: SkillConfig, hpEff: number, apEff: numbe return (value / 100) * (apEff / cd) * 0.05 * weights.W_DPS_PER_SEC * seconds; case Attrs.stun_chance: case Attrs.freeze_chance: + case Attrs.dodge: + case Attrs.accuracy: return value * weights.W_control; case Attrs.knockback_chance: // 击退强化已改为击退距离增量,按距离价值折算 diff --git a/assets/script/game/hero/Hero.ts b/assets/script/game/hero/Hero.ts index 0995d646..f87cce18 100644 --- a/assets/script/game/hero/Hero.ts +++ b/assets/script/game/hero/Hero.ts @@ -162,6 +162,9 @@ export class Hero extends ecs.Entity { } model.speed = hero.speed ?? 200; + // 闪避/命中:配置优先,缺省取全局默认值(百分点) + model.dodge = hero.dodge ?? FightSet.DEFAULT_DODGE; + model.accuracy = hero.accuracy ?? FightSet.DEFAULT_ACCURACY; // 构建技能表并注入运行时冷却字段 ccd;overrides 按英雄等级 resolve 分档(下游无感知) model.skills = {}; diff --git a/assets/script/game/hero/HeroAtkSystem.ts b/assets/script/game/hero/HeroAtkSystem.ts index cb9a4895..158b0e4c 100644 --- a/assets/script/game/hero/HeroAtkSystem.ts +++ b/assets/script/game/hero/HeroAtkSystem.ts @@ -134,6 +134,14 @@ export class HeroAtkSystem extends ecs.ComblockSystem implements ecs.ISystemUpda // 触发被攻击事件 this.onAttacked(target); + // 闪避判定(DoT 不参与):闪避率 = 目标闪避 − 施法者命中 + if (!isDot && this.checkDodge(damageEvent, TAttrsComp)) { + smc.vmdata.scores.dod_count++; + targetView?.showMiss?.(); + // 预留:闪避后触发技能(SkillTriggerType.Dodged)在此接入 + return reDate; + } + // 暴击判定 // 使用施法者的暴击率属性(damageEvent.Attrs 快照)- 被攻击者的暴击抗性 + 目标出血层数附加的被暴击率 const criticalChance = (damageEvent.Attrs[Attrs.critical] || 0) - TAttrsComp.getFinalCriticalRes() + this.getBleedCritBonus(target); @@ -528,6 +536,19 @@ export class HeroAtkSystem extends ecs.ComblockSystem implements ecs.ISystemUpda return (layers?.length ?? 0) * BLEED_CRIT_PER_STACK; } + /** + * 闪避判定:闪避率 = 目标闪避 − 施法者命中,再按该值判定是否闪避。 + * 命中未配置时(accuracy=0)闪避率 = 目标闪避,即无命中加成时闪避全额生效。 + * @param damageEvent 伤害事件(含施法者属性快照) + * @param TAttrsComp 目标属性组件 + * @returns true=闪避成功,false=命中 + */ + private checkDodge(damageEvent: DamageEvent, TAttrsComp: HeroAttrsComp): boolean { + const dodgeChance = TAttrsComp.getFinalDodge() - (damageEvent.Attrs[Attrs.accuracy] || 0); + if (dodgeChance <= 0) return false; + return this.checkChance(dodgeChance); + } + /** * 计算易伤附加伤害:汇总目标每层易伤 buff 的数值(value_override 优先),再被易伤抗性百分比减免。 * @returns 附加伤害值(向下取整,非负) diff --git a/assets/script/game/hero/HeroAttrsComp.ts b/assets/script/game/hero/HeroAttrsComp.ts index b7e37d10..2637ef2c 100644 --- a/assets/script/game/hero/HeroAttrsComp.ts +++ b/assets/script/game/hero/HeroAttrsComp.ts @@ -75,6 +75,8 @@ export class HeroAttrsComp extends ecs.Comp { // ==================== 特殊属性 ==================== critical: number = 0; // 暴击率 critical_res: number = 0; // 暴击抗性 + dodge: number = 0; // 闪避率(被攻击时闪避概率,百分点) + accuracy: number = 0; // 命中率(攻击时命中概率,百分点;削减目标闪避) freeze_chance: number = 0; // 冰冻概率 freeze_res: number = 0; // 冰冻抗性 stun_chance: number = 0; // 击晕概率 @@ -350,6 +352,18 @@ export class HeroAttrsComp extends ecs.Comp { return this.critical + HeroAttrsComp.getFieldPercentValue(FieldSkillType.HeroCrit); } + /** 英雄实时闪避率 = 基础闪避率 + 驻场闪避率。 */ + public getRuntimeDodge(): number { + if (this.fac !== FacSet.HERO) return this.dodge; + return this.dodge + HeroAttrsComp.getFieldPercentValue(FieldSkillType.HeroDodge); + } + + /** 英雄实时命中率 = 基础命中率 + 驻场命中率。 */ + public getRuntimeAccuracy(): number { + if (this.fac !== FacSet.HERO) return this.accuracy; + return this.accuracy + HeroAttrsComp.getFieldPercentValue(FieldSkillType.HeroHit); + } + /** 英雄实时冰冻率 = 基础冰冻率 + 驻场冰冻率。 */ public getRuntimeFreezeChance(): number { if (this.fac !== FacSet.HERO) return this.freeze_chance; @@ -541,6 +555,20 @@ export class HeroAttrsComp extends ecs.Comp { return this.critical_res + mods.flatSum + mods.pctSum; } + /** 最终闪避率 = 驻场实时闪避率 + 限时修饰(加法模型) */ + public getFinalDodge(): number { + const base = this.getRuntimeDodge(); + const mods = this.aggregateTimedMods(Attrs.dodge); + return base + mods.flatSum + mods.pctSum; + } + + /** 最终命中率 = 驻场实时命中率 + 限时修饰(加法模型) */ + public getFinalAccuracy(): number { + const base = this.getRuntimeAccuracy(); + const mods = this.aggregateTimedMods(Attrs.accuracy); + return base + mods.flatSum + mods.pctSum; + } + /** 最终冰冻抗性 = 基础 + 限时修饰(加法模型) */ public getFinalFreezeRes(): number { const mods = this.aggregateTimedMods(Attrs.freeze_res); @@ -687,6 +715,8 @@ export class HeroAttrsComp extends ecs.Comp { this.runtime_field = undefined; this.critical = 0; this.critical_res = 0; + this.dodge = 0; + this.accuracy = 0; this.freeze_chance = 0; this.freeze_res = 0; this.stun_chance = 0; diff --git a/assets/script/game/hero/HeroViewComp.ts b/assets/script/game/hero/HeroViewComp.ts index 54c39010..f5e2eb56 100644 --- a/assets/script/game/hero/HeroViewComp.ts +++ b/assets/script/game/hero/HeroViewComp.ts @@ -241,6 +241,11 @@ export class HeroViewComp extends CCComp { shield_tip(absorbed: number) { this.hp_tip(TooltipTypes.shield, NumberFormatter.formatNumber(Math.max(0, Math.floor(absorbed)))); } + + /** 闪避提示 */ + showMiss() { + this.hp_tip(TooltipTypes.miss, "闪避"); + } public playBuff(anm: string = "") { if (anm === "") return; var path = "game/skill/buff/" + anm; diff --git a/assets/script/game/hero/Mon.ts b/assets/script/game/hero/Mon.ts index d88c54c7..09c82591 100644 --- a/assets/script/game/hero/Mon.ts +++ b/assets/script/game/hero/Mon.ts @@ -176,6 +176,9 @@ export class Monster extends ecs.Entity { // TODO: 局外升级机制落地后,此处基础值将与存档强化累加重算 model.defense = Math.round(hero.def * coef); model.speed = hero.speed ?? 800; + // 闪避/命中:配置优先,缺省取全局默认值(百分点) + model.dodge = hero.dodge ?? FightSet.DEFAULT_DODGE; + model.accuracy = hero.accuracy ?? FightSet.DEFAULT_ACCURACY; model.type = hero.type; model.fac = FacSet.MON; // lv12 职业属性专项:按 11 级当前有效值追加 50%(怪物无局内升级,初始超档直接补齐) diff --git a/assets/script/game/skill/Skill.ts b/assets/script/game/skill/Skill.ts index 3a9a6922..71f60686 100644 --- a/assets/script/game/skill/Skill.ts +++ b/assets/script/game/skill/Skill.ts @@ -236,6 +236,7 @@ export class Skill extends ecs.Entity { sDataCom.Attrs[Attrs.knockback_skill_chance] = config.bck_chance ?? 0; sDataCom.Attrs[Attrs.puncture_chance] = cAttrsComp.getFinalPunctureChance(); // 初始化携带施法者的穿透概率 sDataCom.Attrs[Attrs.puncture_dmg_bonus] = cAttrsComp.getFinalPunctureDmgBonus(); // 初始化携带施法者的穿透伤害加成 + sDataCom.Attrs[Attrs.accuracy] = cAttrsComp.getFinalAccuracy(); // 初始化携带施法者的命中率(含驻场光环与计时 buff) sDataCom.s_uuid = s_uuid sDataCom.skill_lv = Math.max(0, skill_lv); sDataCom.fac = cAttrsComp.fac diff --git a/assets/script/game/skill/TooltipCom.ts b/assets/script/game/skill/TooltipCom.ts index 5437f77a..3a03f957 100644 --- a/assets/script/game/skill/TooltipCom.ts +++ b/assets/script/game/skill/TooltipCom.ts @@ -155,6 +155,12 @@ export class TooltipCom extends CCComp { this.setupLabel("add_life", "hp", "0"); isHeal = true; break; + case TooltipTypes.miss: // 闪避 + this.node.setPosition(v3(this.node.position.x + offsetX, currentY)); + this.node.setSiblingIndex(topSiblingIndex); + this.setupLabel("add_life", "hp", "闪避"); + isHeal = true; + break; } this.playAnimation(scaleMax, isCrit, isHeal, sx);