refactor(debug-log): 优化全模块调试日志格式与默认开关

1.  将BuffManager的静态DEBUG开关改为运行时可配置的debug属性,默认开启
2.  统一所有模块的调试日志输出格式,增加技能/ buff名称、UUID、目标信息和判定详情
3.  为HeroAtkSystem的概率判定添加统一日志,修复击退判定逻辑并补充日志
4.  开启SkillView和HeroAtkSystem的默认调试模式
This commit is contained in:
pan
2026-09-08 10:03:40 +08:00
parent 2cc9678f74
commit 4d7e54f833
4 changed files with 38 additions and 22 deletions

View File

@@ -47,7 +47,7 @@ interface FinalData {
@ecs.register('HeroAtkSystem')
export class HeroAtkSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate {
private debugMode: boolean = false; // 是否启用调试模式
private debugMode: boolean = true; // 是否启用调试模式
/**
* 过滤器:处理拥有伤害队列的实体
@@ -145,7 +145,7 @@ export class HeroAtkSystem extends ecs.ComblockSystem implements ecs.ISystemUpda
// 暴击判定
// 使用施法者的暴击率属性(damageEvent.Attrs 快照)- 被攻击者的暴击抗性 + 目标出血层数附加的被暴击率
const criticalChance = (damageEvent.Attrs[Attrs.critical] || 0) - TAttrsComp.getFinalCriticalRes() + this.getBleedCritBonus(target);
const isCrit = this.checkChance(criticalChance);
const isCrit = this.checkChance(criticalChance, `暴击->${TAttrsComp.hero_name}`);
// 计算基础伤害:DoT 直接用固定 tick 值,普攻走 dmgCount 公式
let damage = isDot ? (damageEvent.dot_dmg ?? 0) : this.dmgCount(damageEvent, TAttrsComp);
@@ -214,15 +214,15 @@ export class HeroAtkSystem extends ecs.ComblockSystem implements ecs.ISystemUpda
// 冰冻判定
const freezeChance = (damageEvent.Attrs[Attrs.freeze_chance] || 0) - (TAttrsComp.freeze_res || 0);
const isFrost = !TAttrsComp.isFrost() && this.checkChance(freezeChance);
const isFrost = !TAttrsComp.isFrost() && this.checkChance(freezeChance, `冰冻->${TAttrsComp.hero_name}`);
// 击晕判定
const stunChance = (damageEvent.Attrs[Attrs.stun_chance] || 0) - TAttrsComp.getFinalStunRes();
const isStun = !TAttrsComp.isStun() && this.checkChance(stunChance);
const isStun = !TAttrsComp.isStun() && this.checkChance(stunChance, `击晕->${TAttrsComp.hero_name}`);
// 麻痹判定(无麻痹抗性,仅按概率)
const paralyzeChance = damageEvent.Attrs[Attrs.paralyze_chance] || 0;
const isParalyze = !TAttrsComp.isParalyze() && this.checkChance(paralyzeChance);
const isParalyze = !TAttrsComp.isParalyze() && this.checkChance(paralyzeChance, `麻痹->${TAttrsComp.hero_name}`);
// ✅ 触发视图层表现(伤害数字、受击动画、冰冻、击晕、击退)
if (targetView) {
@@ -234,7 +234,11 @@ export class HeroAtkSystem extends ecs.ComblockSystem implements ecs.ISystemUpda
// 击退概率判定:概率来自技能配置 bck_chance(heroSet overrides 可覆写),未配置视为 0 不击退。
// 不复用 checkChance:其 70% 上限封顶会把 100% 击退(近战普攻 6004)削成 70%
const knockbackChance = damageEvent.Attrs[Attrs.knockback_skill_chance] || 0;
const isKnockback = knockbackChance >= 100 || (knockbackChance > 0 && Math.random() * 100 < knockbackChance);
const knockbackRand = knockbackChance >= 100 ? 0 : Math.random() * 100;
const isKnockback = knockbackChance >= 100 || (knockbackChance > 0 && knockbackRand < knockbackChance);
if (knockbackChance > 0) {
mLogger.log(this.debugMode, 'HeroAtkSystem', `[概率判定] 击退->${TAttrsComp.hero_name} 概率:${knockbackChance.toFixed(1)}% 随机:${knockbackRand.toFixed(1)} -> ${isKnockback ? "✔成功" : "✘失败"}`);
}
// 击退距离增量 = 施法者击退强化(原击退概率)- 被攻击者击退抗性 + 击退距离强化(仅命中击退时生效)
const knockbackBonus = (damageEvent.Attrs[Attrs.knockback_chance] || 0) - (TAttrsComp.getFinalKnockbackRes() || 0);
@@ -279,13 +283,18 @@ export class HeroAtkSystem extends ecs.ComblockSystem implements ecs.ISystemUpda
// 施法者 ap/完整属性快照取自伤害事件,供 BuffSystem tick 缩放与暴击/冰冻/击晕判定
if (!isDot && skillConf.timed_buff_id) {
const buffChance = skillConf.buff_chance ?? 100;
if (buffChance >= 100 || Math.random() * 100 < buffChance) {
const buffRand = buffChance >= 100 ? 0 : Math.random() * 100;
if (buffChance >= 100 || buffRand < buffChance) {
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;
for (const buffTarget of this.resolveBuffTargets(target, casterEid, TAttrsComp.fac, skillConf.buff_target)) {
const buffTargets = this.resolveBuffTargets(target, casterEid, TAttrsComp.fac, skillConf.buff_target);
mLogger.log(this.debugMode, 'HeroAtkSystem', `[概率判定] 附带buff「${BuffList[skillConf.timed_buff_id]?.name ?? "?"}」 概率:${buffChance.toFixed(1)}% 随机:${buffRand.toFixed(1)} -> ✔成功(技能「${skillConf.name}」命中 ${TAttrsComp.hero_name},${buffTargets.length} 个目标)`);
for (const buffTarget of buffTargets) {
buffManager.applyBuff(buffTarget, skillConf.timed_buff_id, casterEid, damageEvent.Attrs[Attrs.ap] || 0, buffOverrides);
}
} else {
mLogger.log(this.debugMode, 'HeroAtkSystem', `[概率判定] 附带buff「${BuffList[skillConf.timed_buff_id]?.name ?? "?"}」 概率:${buffChance.toFixed(1)}% 随机:${buffRand.toFixed(1)} -> ✘失败(技能「${skillConf.name}」命中 ${TAttrsComp.hero_name})`);
}
}
@@ -295,16 +304,20 @@ export class HeroAtkSystem extends ecs.ComblockSystem implements ecs.ISystemUpda
if (!isDot && damageEvent.proc_skill) {
const proc = damageEvent.proc_skill;
const procChance = proc.chance ?? 100;
if (procChance >= 100 || Math.random() * 100 < procChance) {
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})`);
}
}
@@ -507,11 +520,15 @@ export class HeroAtkSystem extends ecs.ComblockSystem implements ecs.ISystemUpda
*
* @important 概率为0或负数时直接返回false,避免不必要的随机数计算
*/
private checkChance(rate: number): boolean {
private checkChance(rate: number, label?: string): boolean {
if (rate <= 0) return false;
if (rate >= 70) rate = 70
const capped = Math.min(rate, 70); // 70% 概率封顶
const r = Math.random() * 100;
return r < rate;
const ok = r < capped;
if (label !== undefined) {
mLogger.log(this.debugMode, 'HeroAtkSystem', `[概率判定] ${label} 概率:${rate.toFixed(1)}%(封顶${capped}%) 随机:${r.toFixed(1)} -> ${ok ? "✔成功" : "✘失败"}`);
}
return ok;
}
@@ -546,7 +563,7 @@ export class HeroAtkSystem extends ecs.ComblockSystem implements ecs.ISystemUpda
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);
return this.checkChance(dodgeChance, `闪避:${TAttrsComp.hero_name}`);
}
/**