diff --git a/assets/script/game/common/config/SkillSet.ts b/assets/script/game/common/config/SkillSet.ts
index b6eb57a3..312b7b89 100644
--- a/assets/script/game/common/config/SkillSet.ts
+++ b/assets/script/game/common/config/SkillSet.ts
@@ -180,7 +180,8 @@ export interface SkillConfig {
summon_count?: number, // 单次施法召唤的技能实体个数(未配置时回退 prefab 上 SkillView.summon_count)
is_accel?: boolean, // 是否逐渐加速飞行
/**
- * 命中后概率触发额外技能(技能级触发器)。
+ * 施法后概率触发额外技能(技能级触发器)。
+ * 出手即判定(一次施法只判定一次,与召唤/多发实体数量无关),不再依赖命中。
* s_uuid: 被触发的技能 uuid;chance: 触发概率(百分点,缺省 100)。
* overrides: 透传给被触发技能的覆写参数(如 ap/hit_count 等),用于自定义被触发技能的伤害/数值;
* 与被触发技能自身在 heroSet 中的 overrides 叠加(本次传入优先)。
diff --git a/assets/script/game/hero/DamageQueueComp.ts b/assets/script/game/hero/DamageQueueComp.ts
index d8f662c3..4654a432 100644
--- a/assets/script/game/hero/DamageQueueComp.ts
+++ b/assets/script/game/hero/DamageQueueComp.ts
@@ -1,6 +1,5 @@
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
import { HeroViewComp } from "./HeroViewComp";
-import { SkillOverrides } from "../common/config/SkillSet";
/** 命中后对敌 debuff 快照(由施法技能实体自合并后配置提取并透传,HeroAtkSystem 据此结算) */
export interface TimedDebuffSnapshot {
@@ -38,9 +37,6 @@ export interface DamageEvent {
* 跳过 dmgCount 公式直接用该值,且不走击退/受击动画,其余(暴击/冰冻/击晕/护盾/死亡链)与普攻一致
*/
dot_dmg?: number
- /** 命中后概率触发额外技能(由施法技能实体快照自合并后配置,HeroAtkSystem 据此判定;
- * overrides 字段透传给被触发技能,用于自定义伤害/数值) */
- proc_skill?: { s_uuid: number; chance?: number; overrides?: SkillOverrides }
/** 命中后对敌 debuff(由施法技能实体自合并后配置快照透传;缺省时 HeroAtkSystem 回退读 SkillSet 底座) */
timed_debuff?: TimedDebuffSnapshot
}
@@ -79,7 +75,7 @@ export class DamageQueueComp extends ecs.Comp {
/**
* 添加伤害事件到队列
*/
- addDamageEvent(attrs: any, casterEid: number, s_uuid: number, ext_dmg: number = 0, dmg_ratio: number = 1, dot_dmg: number = 0, proc_skill?: { s_uuid: number; chance?: number; overrides?: SkillOverrides }, timed_debuff?: TimedDebuffSnapshot): void {
+ addDamageEvent(attrs: any, casterEid: number, s_uuid: number, ext_dmg: number = 0, dmg_ratio: number = 1, dot_dmg: number = 0, timed_debuff?: TimedDebuffSnapshot): void {
const timestamp = Date.now();
const damageEvent: DamageEvent = {
@@ -91,7 +87,6 @@ export class DamageQueueComp extends ecs.Comp {
ext_dmg: ext_dmg,
dmg_ratio: dmg_ratio,
dot_dmg: dot_dmg,
- proc_skill: proc_skill,
timed_debuff: timed_debuff,
};
@@ -198,7 +193,7 @@ export class DamageQueueHelper {
* 为实体添加伤害事件
* 如果实体没有伤害队列组件,会自动创建
*/
- static addDamageToEntity(entity: ecs.Entity, attrs: any, casterEid: number, s_uuid: number, ext_dmg: number = 0, dmg_ratio: number = 1, dot_dmg: number = 0, proc_skill?: { s_uuid: number; chance?: number; overrides?: SkillOverrides }, timed_debuff?: TimedDebuffSnapshot): void {
+ static addDamageToEntity(entity: ecs.Entity, attrs: any, casterEid: number, s_uuid: number, ext_dmg: number = 0, dmg_ratio: number = 1, dot_dmg: number = 0, timed_debuff?: TimedDebuffSnapshot): void {
let damageQueue = entity.get(DamageQueueComp);
// 如果实体没有伤害队列组件,创建一个
@@ -207,7 +202,7 @@ export class DamageQueueHelper {
}
// 添加伤害事件到队列
- damageQueue.addDamageEvent(attrs, casterEid, s_uuid, ext_dmg, dmg_ratio, dot_dmg, proc_skill, timed_debuff);
+ damageQueue.addDamageEvent(attrs, casterEid, s_uuid, ext_dmg, dmg_ratio, dot_dmg, timed_debuff);
}
/**
diff --git a/assets/script/game/hero/HeroAtkSystem.ts b/assets/script/game/hero/HeroAtkSystem.ts
index fd106c5b..ee1fc78d 100644
--- a/assets/script/game/hero/HeroAtkSystem.ts
+++ b/assets/script/game/hero/HeroAtkSystem.ts
@@ -323,29 +323,7 @@ export class HeroAtkSystem extends ecs.ComblockSystem implements ecs.ISystemUpda
}
}
- // 命中概率触发额外技能(proc_skill):配置由施法技能实体快照自合并后配置(含 heroSet overrides/lv_entries),
- // 触发走 SkillTriggerHelper/forceCastTriggerSkill 通道(无视 CD、无施法前摇),与 atking 同一通道。
- // 防递归:被触发的技能经 forceCastTriggerSkill 不再产生 proc_skill 伤害事件之外的新事件,且不会累加 atk_count。
- if (!isDot && damageEvent.proc_skill) {
- const proc = damageEvent.proc_skill;
- const procChance = proc.chance ?? 100;
- const procRand = procChance >= 100 ? 0 : Math.random() * 100;
- if (procChance >= 100 || procRand < procChance) {
- const caster = ecs.getEntityByEid(casterEid);
- if (caster) {
- const casterAttrs = caster.get(HeroAttrsComp);
- const casterView = caster.get(HeroViewComp);
- if (casterAttrs && casterView && !casterAttrs.is_dead && !casterAttrs.is_reviving) {
- mLogger.log(this.debugMode, 'HeroAtkSystem', `[概率判定] 额外技能「${SkillSet[proc.s_uuid]?.name ?? "?"}」 概率:${procChance.toFixed(1)}% 随机:${procRand.toFixed(1)} -> ✔成功(技能「${skillConf.name}」命中 ${TAttrsComp.hero_name},由 ${casterAttrs.hero_name} 释放)`);
- // proc_skill.overrides 透传给被触发技能(如自定义 ap 伤害),与被触发技能自身 overrides 叠加(本次传入优先)
- SkillTriggerHelper.dispatchSinglePublic(proc.s_uuid, casterAttrs, casterView, SkillTriggerType.Atking, proc.overrides);
- }
- }
- } else {
- mLogger.log(this.debugMode, 'HeroAtkSystem', `[概率判定] 额外技能「${SkillSet[proc.s_uuid]?.name ?? "?"}」 概率:${procChance.toFixed(1)}% 随机:${procRand.toFixed(1)} -> ✘失败(技能「${skillConf.name}」命中 ${TAttrsComp.hero_name})`);
- }
- }
-
+ // proc_skill 已改为施法后触发(SCastSystem 在出手时判定),不再随伤害事件命中触发
// 检查死亡
if (TAttrsComp.hp <= 0) {
diff --git a/assets/script/game/hero/SCastSystem.ts b/assets/script/game/hero/SCastSystem.ts
index 12db6769..54d6c57f 100644
--- a/assets/script/game/hero/SCastSystem.ts
+++ b/assets/script/game/hero/SCastSystem.ts
@@ -91,9 +91,7 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
targetEids = this.collectFriendlyTargetEids(FacSet.HERO, undefined, true); // 获取所有英雄阵营的目标
}
- // 召唤数量由技能 prefab 的 SkillView.summon_count 决定;召唤类技能(>1)默认不再参与风怒多发
const summonCount = this.resolveSummonCount(config);
- // 多发次数由 overrides.num 提供(技能卡差异化多发),限制在 [0, 2];召唤类技能屏蔽风怒多发
const cNum = summonCount > 1 ? 0 : Math.min(2, Math.max(0, Math.floor(overrides?.num ?? 0)));
const castTimes = Math.max(summonCount, 1 + cNum);
@@ -168,6 +166,8 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
setTimeout(exec, i * FightSet.SUMMON_INTERVAL * 1000);
}
}
+ // 施法后概率触发额外技能(proc_skill,原命中触发改为出手即判定;卡牌技能无视 CD、无施法主体)
+ this.tryProcSkill(config, null, null, SkillTriggerType.Atking);
}
/** 专用于卡牌施放的技能实体生成 */
@@ -315,9 +315,7 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
}
}
- // 召唤数量由技能 prefab 的 SkillView.summon_count 决定;召唤类技能(>1)默认不再参与风怒多发
const summonCount = this.resolveSummonCount(config);
- // 多发次数由 overrides.num 提供(技能卡差异化多发),限制在 [0, 2];召唤类技能屏蔽风怒多发
const cNum = summonCount > 1 ? 0 : Math.min(2, Math.max(0, Math.floor(overrides?.num ?? 0)));
const castTimes = Math.max(summonCount, 1 + cNum);
let val = ""
@@ -342,6 +340,8 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
this.applyEnemySkillEffects(s_uuid, skillLv, config, heroView, heroAttrs, enemyTargetPos, i, overrides);
}, i * FightSet.SUMMON_INTERVAL);
}
+ // 施法后概率触发额外技能(proc_skill,原命中触发改为出手即判定,无视 CD)
+ this.tryProcSkill(config, heroAttrs, heroView, triggerType);
}
/**
@@ -397,10 +397,8 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
config = mergeSkillParams(config, overrides);
- // 召唤数量由技能 prefab 的 SkillView.summon_count 决定;召唤类技能(summon_count>1)不再触发风怒
const summonCount = this.resolveSummonCount(config);
const isSummonSkill = summonCount > 1;
- // 多发次数由 overrides.num 提供(技能卡差异化多发),限制在 [0, 2];召唤类技能屏蔽风怒多发
const cNum = isSummonSkill ? 0 : Math.min(2, Math.max(0, Math.floor(overrides?.num ?? 0)));
const castTimes = Math.max(summonCount, 1 + cNum);
@@ -413,13 +411,16 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
// 因为 castSkill 只由 update 循环调用,处理的必然是 heroAttrs.skills 中的普通技能
// 特殊触发技能(call/dead/atking等)走的是 forceCastTriggerSkill,不会调用 castSkill
- // 召唤类技能(summon_count>1)不再计入普攻链,避免触发 atking(风怒类)附加技能
+ // 召唤类技能(summon_count>1)不再计入普攻链,避免触发 atking 附加技能
const skillIds = heroAttrs.getSkillIds();
if (!isSummonSkill && skillIds.includes(s_uuid)) {
heroAttrs.atk_count++;
this.checkAndTriggerAtkingSkills(heroAttrs, heroView);
}
+ // 施法后概率触发额外技能(proc_skill,出手即判定,无视 CD,不再依赖命中)
+ this.tryProcSkill(config, heroAttrs, heroView, SkillTriggerType.Atking);
+
// 优先使用技能配置的前摇时间,否则使用全局默认值
// 注意:这里仍然是基于时间的延迟,受帧率波动影响。
// 若需精确同步,建议在动画中添加帧事件并在 HeroViewComp 中监听。
@@ -452,6 +453,30 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
SkillTriggerHelper.trigger(SkillTriggerType.Atking, heroAttrs, heroView);
}
+ /**
+ * 施法后概率触发额外技能(proc_skill)。
+ * 语义由“命中触发”调整为“施法出手即判定”,一次施法只判定一次(与召唤/多发的实体数量无关),
+ * 走 TriggerSkill 通道(forceCastTriggerSkill),无视 CD、无施法前摇。
+ * @param config 合并后(含 overrides)的技能配置
+ * @param heroAttrs 施法者属性组件(卡牌技能传 null)
+ * @param heroView 施法者视图组件(卡牌技能传 null)
+ * @param triggerType 触发类型语义(仅日志标识用)
+ */
+ private tryProcSkill(config: SkillConfig, heroAttrs: HeroAttrsComp | null, heroView: HeroViewComp | null, triggerType?: string) {
+ const proc = config.proc_skill;
+ if (!proc) return;
+ const chance = proc.chance ?? 100;
+ const rand = chance >= 100 ? 0 : Math.random() * 100;
+ const casterName = heroAttrs?.hero_name ?? "卡牌";
+ if (chance >= 100 || rand < chance) {
+ if (!heroAttrs || !heroView) return; // 卡牌技能无施法主体,proc 仅支持英雄触发
+ mLogger.log(this.debugMode, "SCastSystem", `[概率判定] 额外技能「${SkillSet[proc.s_uuid]?.name ?? "?"}」 概率:${chance.toFixed(1)}% 随机:${rand.toFixed(1)} -> ✔成功(技能「${config.name}」施法后触发,由 ${casterName} 释放)`);
+ SkillTriggerHelper.dispatchSinglePublic(proc.s_uuid, heroAttrs, heroView, SkillTriggerType.Atking, proc.overrides);
+ } else {
+ mLogger.log(this.debugMode, "SCastSystem", `[概率判定] 额外技能「${SkillSet[proc.s_uuid]?.name ?? "?"}」 概率:${chance.toFixed(1)}% 随机:${rand.toFixed(1)} -> ✘失败(技能「${config.name}」施法后未触发)`);
+ }
+ }
+
/** 多发/召唤的纵向扇形偏移档位(像素),索引按 中/上/下/上上/下下... 循环 */
private static readonly REPEAT_Y_OFFSETS: number[] = [0, 15, -15, 30, -30, 45, -45, 60, -60];
diff --git a/assets/script/game/skill/SDataCom.ts b/assets/script/game/skill/SDataCom.ts
index c3a800d0..144ae65f 100644
--- a/assets/script/game/skill/SDataCom.ts
+++ b/assets/script/game/skill/SDataCom.ts
@@ -1,6 +1,5 @@
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
import { BoxSet } from "../common/config/GameSet";
-import { SkillOverrides } from "../common/config/SkillSet";
import { TimedDebuffSnapshot } from "../hero/DamageQueueComp";
/** 业务层对象 */
@@ -18,9 +17,6 @@ export class SDataCom extends ecs.Comp {
dmg_ratio:number=1 //伤害比例
hit_count:number=0 //击中数量
max_hit_count:number=0 //最大可命中次数
- /** 命中后概率触发额外技能(由 Skill.load 从合并后配置快照;DamageEvent 透传给 HeroAtkSystem 判定;
- * overrides 字段透传给被触发技能,用于自定义伤害/数值) */
- proc_skill?: { s_uuid: number; chance?: number; overrides?: SkillOverrides };
/** 命中后对敌 debuff(由 Skill.load 从合并后配置快照;DamageEvent 透传给 HeroAtkSystem 结算) */
timed_debuff?: TimedDebuffSnapshot;
reset() {
@@ -34,7 +30,6 @@ export class SDataCom extends ecs.Comp {
this.max_hit_count=0
this.ext_dmg=0
this.dmg_ratio=1
- this.proc_skill=undefined
this.timed_debuff=undefined
}
}
diff --git a/assets/script/game/skill/Skill.ts b/assets/script/game/skill/Skill.ts
index 865c2aa4..acb0db20 100644
--- a/assets/script/game/skill/Skill.ts
+++ b/assets/script/game/skill/Skill.ts
@@ -243,8 +243,7 @@ export class Skill extends ecs.Entity {
sDataCom.ext_dmg = ext_dmg
sDataCom.hit_count = 0
sDataCom.max_hit_count = Math.max(1, sHit)
- // 快照合并后(基础配置+heroSet overrides/lv_entries)的 proc_skill,命中时由 HeroAtkSystem 判定触发
- sDataCom.proc_skill = config.proc_skill;
+ // proc_skill 已改为施法后触发(SCastSystem 判定),此处不再快照到伤害链
// 快照合并后的对敌 debuff 配置,命中时由 HeroAtkSystem 结算(heroSet overrides/lv_entries 注入的 debuff 依赖此透传)
sDataCom.timed_debuff = config.timed_debuff_id
? { id: config.timed_debuff_id, value: config.debuff_value, duration: config.debuff_duration, chance: config.debuff_chance }
diff --git a/assets/script/game/skill/SkillView.ts b/assets/script/game/skill/SkillView.ts
index 003c2401..df383a7c 100644
--- a/assets/script/game/skill/SkillView.ts
+++ b/assets/script/game/skill/SkillView.ts
@@ -219,7 +219,6 @@ export class SkillView extends CCComp {
this.sData.ext_dmg,
finalRatio,
0,
- this.sData.proc_skill,
this.sData.timed_debuff,
);
}
diff --git a/put/server/data/heroes.json编辑指引.md b/put/server/data/heroes.json编辑指引.md
index 52d74111..d3ecea0a 100644
--- a/put/server/data/heroes.json编辑指引.md
+++ b/put/server/data/heroes.json编辑指引.md
@@ -92,7 +92,7 @@
特殊存储格式(导出时由 server 还原为 TS 枚举表达式):
- `TGroup`:JSON 存字符串(如 `"Team"`),导出还原 `TGroup.Team`;`null` 表示不覆写;
- `buff_target`:存数字 0~3(Hit/Self/Ally/Enemy),导出还原 `BuffTarget.X`;
-- `proc_skill`:对象 `{s_uuid, chance?, overrides?}`(命中后概率触发另一技能);
+- `proc_skill`:对象 `{s_uuid, chance?, overrides?}`(施法后概率触发另一技能,出手即判定,与命中/弹道数无关);
- `icon`:字符串图标帧名(uicons 图集),非数值;
- 其余一律直存数值。
@@ -126,11 +126,11 @@
**语义陷阱**:`timed_buff_id` 在伤害技能上缺省挂**施法者自身**——若想"命中给敌人挂减益",必须用 `timed_debuff_id`,否则会把减益挂到自己身上。
-### 6.2 proc_skill(命中概率触发主动技能)
+### 6.2 proc_skill(施法后概率触发主动技能)
-**定位**:命中后概率触发一个**主动技能**(大招/触发技底座,如 6100+/6200+ 段伤害技能),以施法者身份完整释放(含伤害/弹道/特效)。它是技能触发器,不是挂 buff 的方式——debuff 注入请用 `timed_buff_id`(见 §6.1)。
+**定位**:施法出手后概率触发一个**主动技能**(大招/触发技底座,如 6100+/6200+ 段伤害技能),以施法者身份完整释放(含伤害/弹道/特效)。它是技能触发器,不是挂 buff 的方式——debuff 注入请用 `timed_buff_id`(见 §6.1)。
-**编辑器 UI**:overrides 添加 `proc_skill 命中概率触发主动技能` 行后展开结构化编辑:
+**编辑器 UI**:overrides 添加 `proc_skill 施法后概率触发技能` 行后展开结构化编辑:
1. `被触发技能 uuid`:下拉列出全部 SkillSet(`uuid 名称`);
2. `概率%`:0~100 数字输入,默认 100;
3. `被触发技能覆写`:内嵌 OverrideEditor(同套白名单),可递归覆写被触发技能的 `ap`/`TGroup`/`hit_count` 等。
@@ -145,14 +145,16 @@
```
**运行时行为**:
-- 触发链路:技能命中 → 掷 `chance` 骰(≥100 直接成功不掷骰;无 70% 封顶)→ 以施法者身份走 `forceCastTriggerSkill`(无视 CD、无施法前摇,触发类型记为 atking);
+- 触发链路:施法出手 → 掷 `chance` 骰(≥100 直接成功不掷骰;无 70% 封顶)→ 以施法者身份走 `forceCastTriggerSkill`(无视 CD、无施法前摇,触发类型记为 atking);
+- 出手即判定:**一次施法只判定一次**,与命中次数、弹道数、召唤数均无关(多弹道技能不会按实体数重复判定);
+- 不再依赖命中:即使技能落空/无目标可命中,只要施法动作出手就会判定;
- `overrides` 与被触发技能自身 heroSet overrides 叠加,本次传入优先;
-- DoT 伤害不触发 proc;被触发的技能不再累加普攻计数(防递归);
+- 被触发的技能不再累加普攻计数(防递归);
- 内嵌 `TGroup` 可改变被触发技能的释放对象(如触发一个友方增益)。
**选型指引**(对敌附带效果):
- 挂 debuff(冰冻/中毒/易伤等)→ `timed_buff_id`:写入 SkillSet 底座,或用友方技能 + `buff_target: 3` 分流挂敌;
-- 命中后追发一个主动技能(陨石/火球等完整释放)→ `proc_skill`。
+- 施法后追发一个主动技能(陨石/火球等完整释放)→ `proc_skill`。
## 7. 新增英雄操作清单
diff --git a/put/server/index.js b/put/server/index.js
index 51cbdbe9..d41fafa2 100644
--- a/put/server/index.js
+++ b/put/server/index.js
@@ -268,12 +268,12 @@ function overrideShort(ov, { includeAp = true } = {}) {
const chance = ov.debuff_chance != null ? `debuff_chance${ov.debuff_chance}` : ''
parts.push(`命中附加${val}${debuffName}${ov.timed_debuff_id}${chance}`)
}
- // proc_skill:命中后概率触发额外技能,标注被触发技能名/概率/覆写 ap(若有)
+ // proc_skill:施法后概率触发额外技能(出手即判定,与命中/弹道数无关),标注被触发技能名/概率/覆写 ap(若有)
if (ov.proc_skill?.s_uuid != null) {
const procName = cache?.SkillSet?.[ov.proc_skill.s_uuid]?.name || ''
const procChance = ov.proc_skill.chance != null ? `${ov.proc_skill.chance}%` : '100%'
const procAp = ov.proc_skill.overrides?.ap != null ? `ap${ov.proc_skill.overrides.ap}` : ''
- parts.push(`触发${procName}${ov.proc_skill.s_uuid}(${procChance}${procAp ? `;${procAp}` : ''})`)
+ parts.push(`施法触发${procName}${ov.proc_skill.s_uuid}(${procChance}${procAp ? `;${procAp}` : ''})`)
}
return parts.join(';')
}
diff --git a/put/web/src/App.vue b/put/web/src/App.vue
index 705bdb66..91615175 100644
--- a/put/web/src/App.vue
+++ b/put/web/src/App.vue
@@ -242,8 +242,6 @@ const allSkills = computed(() => Object.values(skillMap.value).sort((a, b) => a.
const fieldOptions = computed(() => Object.values(meta.value?.FieldSkillSet || {}).sort((a, b) => a.uuid - b.uuid))
// buff 候选:timed_buff_id 覆写下拉用(BuffList 按 id 升序)
const buffOptions = computed(() => Object.values(meta.value?.BuffList || {}).sort((a, b) => a.id - b.id))
-// 复活已纳入 dead 触发组,通过 dead 编辑器的 overrides 配置 revive_hp / revive_count
-const reviveOptions = computed(() => allSkills.value.filter((s) => s.uuid >= 6500 && s.uuid < 6600))
const roleBase = computed(() => {
if (!current.value || !meta.value?.HERO_ROLE_BASE) return null
diff --git a/put/web/src/components/OverrideEditor.vue b/put/web/src/components/OverrideEditor.vue
index 05444197..a74f884f 100644
--- a/put/web/src/components/OverrideEditor.vue
+++ b/put/web/src/components/OverrideEditor.vue
@@ -27,7 +27,7 @@
>
-
+
删除
+
+
+ 添加覆盖
@@ -137,6 +148,9 @@ const isEnemyHost = computed(() => {
// 对敌技能且注入了 timed_buff_id → 运行时断链不生效,警示引导改用 proc_skill / 底座表
const showEnemyBuffWarn = computed(() => isEnemyHost.value && rows.value.some((r) => r.key === 'timed_buff_id'))
+// 是否配置了 proc_skill(施法后概率触发主动技能):控制触发语义提示显隐
+const hasProcSkill = computed(() => rows.value.some((r) => r.key === 'proc_skill'))
+
// 易伤 buff id(与游戏侧 BuffSet.VULNERABLE_BUFF_ID 对应),取值语义特殊需单独提示
const VULNERABLE_ID = 7002
diff --git a/put/web/src/constants.js b/put/web/src/constants.js
index e1a04d52..b61f5db9 100644
--- a/put/web/src/constants.js
+++ b/put/web/src/constants.js
@@ -141,8 +141,8 @@ export const OVERRIDE_KEYS = [
{ key: 'call_hero', label: 'call_hero 召唤英雄id' },
{ key: 'revive_hp', label: 'revive_hp 复活回血比例(%)' },
{ key: 'revive_count', label: 'revive_count 复活次数上限' },
- // 对象型覆写:命中后概率触发主动技能(大招/触发技),含 s_uuid/chance/overrides 子字段
- { key: 'proc_skill', label: 'proc_skill 命中概率触发主动技能', type: 'object' },
+ // 对象型覆写:施法后概率触发主动技能(大招/触发技),出手即判定、一次施法一次判定,含 s_uuid/chance/overrides 子字段
+ { key: 'proc_skill', label: 'proc_skill 施法后概率触发技能', type: 'object' },
// 字符串型覆写:value 为图标ID(uicons 图集帧名),非数值
{ key: 'icon', label: 'icon 英雄语境图标(覆写 SkillSet.icon)', type: 'string' },
]
diff --git a/put/web/src/main.js b/put/web/src/main.js
index 91d83f30..c905721b 100644
--- a/put/web/src/main.js
+++ b/put/web/src/main.js
@@ -6,5 +6,6 @@ import App from './App.vue'
import './style.css'
const app = createApp(App)
-app.use(ElementPlus, { locale: zhCn })
+// 全局 small 尺寸:编辑页所有 Element Plus 控件(输入框/下拉/按钮等)默认缩小一档
+app.use(ElementPlus, { locale: zhCn, size: 'small' })
app.mount('#app')
diff --git a/put/web/src/style.css b/put/web/src/style.css
index a56195e6..0184bf52 100644
--- a/put/web/src/style.css
+++ b/put/web/src/style.css
@@ -28,9 +28,19 @@ body {
/* 行间距压缩:表单项下边距 + 行高收紧 */
.hero-app .el-form-item { margin-bottom: 8px; line-height: 1.2; }
.hero-app .el-form-item__label { line-height: 1.2; padding-bottom: 2px; }
-.hero-app .el-button { font-size: 12px; height: 26px; padding: 8px 10px; }
-.hero-app .el-button--small { height: 22px; padding: 5px 8px; }
-.hero-app .el-input__inner { --el-input-height: 26px; }
+.hero-app .el-button { font-size: 12px; height: 24px; padding: 5px 10px; }
+.hero-app .el-button--small { height: 20px; padding: 4px 8px; }
+/* 控件高度压缩:用 CSS 变量统一覆盖 Element Plus 各尺寸档(small 由 main.js 全局注册) */
+.hero-app {
+ --el-component-size-small: 22px;
+ --el-component-size: 24px;
+ --el-component-size-large: 28px;
+ --el-input-height: 22px;
+}
+.hero-app .el-input__wrapper { padding: 0 8px; }
+.hero-app .el-select__wrapper { min-height: 22px; padding: 0 8px; }
+.hero-app .el-input-number { width: auto; }
+.hero-app .el-input-number .el-input__inner { text-align: left; }
.hero-app .el-tabs__item { font-size: 12px; height: 30px; }
.hero-app .el-tabs__header { margin-bottom: 8px; }
.hero-app .el-tabs__nav-wrap::after { height: 1px; }