feedback5 WL: 生命回复速度 is not 治疗 — the 吟游者 trait, 调香师, 瑕光 S2, 铃兰 S3 and 锡人 give an hpRegen buff, so 无法被友方治疗 / 禁疗 units get it and 治疗加成 does not scale it (GitHub #96 / #137)

PRTS: 分支特性信息 吟游者 「特性为基于自身攻击力来增加受益者的“生命回复速度”属性」 (魔王, 浊心斯卡蒂); the 备注 of 调香师 熏衣草,
瑕光 S2, 铃兰 S3 and 锡人 S2 「生命恢复的提供方式为增加目标的“生命回复速度”属性…不受治疗加成和禁疗影响」 (铃兰: none in the
first second, refreshed every second); 异常效果 禁疗 「增减生命回复速度…的效果不会被识别为治疗类能力」. These were heals from
the provider, which damage.js refused on 收割者 / 不屈者 / 武者 (noHeal) and under 禁疗 — 隐德来希 gained nothing under 魔王.
This is the separation proposed in PR #135 by @SpiritedAwayCN, written anew (the PR's patch is not used):
- professions.js bardRegen: the trait is an hpRegen buff per bard refreshed every 0.25 s; 魔王's 微尘 ×1.5 goes through
  its `bardRegen` hook (both 魔王 kits); 浊心斯卡蒂's pulse and the 海嗣 token use it too.
- 调香师 (every ally), 瑕光 S2 (the skill range, removed at its end), 铃兰 S3 (from the first full second, removed at its
  end), 锡人 (per 炼金单元, its cached ATK): hpRegen buffs instead of battle.heal.
- damage.js: a `regen` tick takes no healing multiplier and a heal hook cannot change its amount (no 治疗加成 on any
  生命回复速度); 流明's 凡人之愿 and 华法琳's S1 bonus skip a regen tick of their own.
Direct heals are unchanged (still refused / scaled); 魔王 S3's redistribution and 纯烬's HoT are untouched. Other
per-second recoveries without such a note stay heals (引星棘刺, 塞雷娅 S3, 流明 / 纯烬 HoTs; 余 闲云隐市 and 天马之盔 left open).

Golden moved (every one fields 魔王 / 浊心斯卡蒂 / 调香师 / 瑕光 S2 / 铃兰 / 锡人): roster-004, roster-005, roster-006,
roster-011, roster-013, roster-015, roster-016, roster-018, roster-023, roster-025, roster-030, roster-032, roster-035,
roster-037, roster-039, roster-041, roster-042, roster-045, roster-046; bond-deputShip-high, bond-emptyShip-low,
bond-emptyShip-high, bond-indomShip-high, bond-kazimierzShip-low, bond-kazimierzShip-high, bond-sargonShip-low,
bond-sargonShip-high, bond-skillfulShip-high; boss-boss_1-pair, boss-boss_1-solo, boss-boss_2-solo, boss-boss_3-pair,
boss-boss_3-solo, boss-boss_4-solo, boss-boss_5-pair, boss-boss_5-solo, boss-boss_6-solo, boss-boss_7-pair,
boss-boss_7-solo, hidden-boss_8-solo, hidden-boss_9-pair, hidden-boss_9-solo, hidden-boss_10-solo, unite-1;
solo-NORMAL-1, solo-HARD-1, solo-ABYSS-1, coop4-ABYSS-7, coop2-NORMAL-8-serverrun, coop2-NORMAL-14-standins.
Docs: SIM.md (heal pipeline, bard row), PLAYING.md, kits/README.md (checklist item 11).
This commit is contained in:
sganggs committed 2026-10-05 21:13:15 +08:00
1 parent 696085ac8e
commit 5c6524e1ad
27 files changed
+943 -721

No files matched your search

@@ -3,6 +3,7 @@
import { aggregateMods } from '../../../buffs.js';
import { COLS } from '../../../constants.js';
import { bardRegen } from '../../../professions.js';
import {
num, bv, tbb, tdesc, moduleBb, parseN, live, enemiesIn, isTok, onDefaultSkill, selectedSkill, aura,
} from '../shared/tier6.js';
@@ -37,7 +38,8 @@ function skadi2(bb, chess, def) {
const isDef = onDefaultSkill(chess), sid = selectedSkill(chess, def);
const tokId = def?.talents?.[0]?.tokenKey || (chess?.tokens || [])[0] || 'token_10017_skadi2_dedant';
const auraRatio = num(tb['attack@atk_to_hp_recovery_ratio'], 0.1);
// S1 / S2 raise the trait heal ("特性效果提高至N%") while they run; S3 (default) turns it into the tide
// S1 / S2 raise the trait ("特性效果提高至N%") while they run; S3 (default) turns it into the tide. The trait is a
// 生命回复速度 buff on the allies, not a heal (PRTS 分支特性信息 吟游者; professions.js bardRegen)
const skillRatio = num(bb['attack@atk_to_hp_recovery_ratio'], auraRatio);
const seaborns = (battle, unit) => battle.allyUnits.filter((t) => isTok(t, tokId, unit) && live(t));
const covered = (battle, unit, toks) => { // allies inside her range ∪ the seaborns' ranges
@@ -52,7 +54,7 @@ function skadi2(bb, chess, def) {
return seaborns(battle, unit).some((t) => t.rangeKeySet?.has(k));
};
const skills = {
// S1 同归殊途之吟 (SP_FULL): full self heal, max HP +max_hp, trait heal attack@atk_to_hp_recovery_ratio, and
// S1 同归殊途之吟 (SP_FULL): full self heal, max HP +max_hp, trait attack@atk_to_hp_recovery_ratio, and
// damage_resistance of the damage taken by every ally of her (+ 海嗣) range is transferred to her (install)
skchr_skadi2_1: {
kind: 'duration',
@@ -60,7 +62,7 @@ function skadi2(bb, chess, def) {
onStart({ battle, unit }) { unit.hp = unit.s.maxHp; battle.fx('heal', { x: unit.x, y: unit.y, id: unit.id }); },
},
// S2 同葬无光之愿 (toggle): 鼓舞 ATK / DEF = atk / def × her ATK / DEF on every other ally of her (+ 海嗣) range,
// trait heal attack@atk_to_hp_recovery_ratio (trait pulse). 自动触发 with effects on her allies only (nothing to target):
// trait attack@atk_to_hp_recovery_ratio (trait pulse). 自动触发 with effects on her allies only (nothing to target):
// on as soon as it is ready (SP_FULL, like 魔王 S1 往昔萦绕身旁); until 0.2.0 the data's DEFAULT left it off until an
// enemy came into her (or a 海嗣's) range.
skchr_skadi2_2: { kind: 'toggle', trigger: 'SP_FULL' },
@@ -72,7 +74,7 @@ function skadi2(bb, chess, def) {
onStart({ battle, unit }) { battle.fx('tide', { x: unit.x, y: unit.y, id: unit.id }); },
},
trait: {
install(battle, unit) { // replaces the bard aura: heal normally, tide (true damage + 鼓舞 + self drain) during S3
install(battle, unit) { // replaces the bard aura: 生命回复速度 normally, tide (true damage + 鼓舞 + self drain) during S3
unit.mem.noInspire = true; // 自身不受鼓舞影响
const isInspire = (b) => b.key === 'inspire' || b.status === 'inspire' || b.key.startsWith('inspire:') || b.key.endsWith(':inspire');
// "海嗣的攻击范围视为自身攻击范围的延伸": an enemy in a 海嗣's range also satisfies her DEFAULT trigger
@@ -103,10 +105,9 @@ function skadi2(bb, chess, def) {
const va = unit.s.atk * num(bb.atk), vd = unit.s.def * num(bb.def);
for (const a of allies) if (a !== unit) { inspire(battle, a, va, unit); inspire(battle, a, vd, unit, 'def'); }
}
if (n % 2 === 0) {
const amount = unit.s.atk * (on ? skillRatio : num(unit.profile?.auraRatio, auraRatio));
for (const a of allies) if (a.hp < a.s.maxHp) battle.heal(unit, a, amount, { aura: true });
}
// the trait over her range ∪ the 海嗣' ranges, refreshed every pulse (it lapses 0.75 s after the last one)
const v = unit.s.atk * (on ? skillRatio : num(unit.profile?.auraRatio, auraRatio));
for (const a of allies) bardRegen(battle, unit, a, v, 0.75);
}, { owner: unit });
},
},