feedback5 O16: two additive engine rules for the 自选 kits of 机械师 and 凯尔希 — a 屏障 limited to a list of damage types, a healer that heals one ally through its 禁疗
- buffs.js makeBuff / damage.js absorbShields: `shieldType` may be a list of damage types — the shield absorbs those only (机械师's 屏障 absorb physical and arts damage, not true: buff_template_data mcnist_t_2 / mcnist_s_2_shield BlockDamage PHYSICAL_AND_MAGICAL); a single type and an untyped shield work as before. - damage.js heal / Battle.injuredAlliesInKeys: a healer profile's `healThrough(healer, ally)` names allies its heals reach through their 禁疗 (the `noHeal` flag of a summon's 禁疗, the `healFree` flag; a profile `noHeal` — 无法被友方治疗 — still stops it), and its heal selection takes them (凯尔希 on her Mon3tr: PRTS Mon3tr(凯尔希的召唤物) "持有禁疗(可被凯尔希… 无视)"; her charpack attack `_ignoreHealFree`); every other healer still skips them. - docs/SIM.md §3 / §4 / §8, professions.js profile field list. No content uses either yet: golden unchanged. Test: test/sim/feedback5-o16-engine.test.js (2).
This commit is contained in:
1 parent
fef4ea3d4b
commit
5888f153ac
6 files changed
+101
-12
No files matched your search
@@ -54,15 +54,20 @@ export class BattleQueries {
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Allies (not devices) within tiles `keys`, sorted by HP ratio (lowest first) that need healing. */
|
||||
/**
|
||||
* Allies (not devices) within tiles `keys`, sorted by HP ratio (lowest first) that need healing. A `noHeal` (禁疗) ally
|
||||
* is left out unless the healer's profile heals it through its 禁疗 (`healThrough(healer, ally)`: 凯尔希's Mon3tr —
|
||||
* damage.js heal).
|
||||
*/
|
||||
injuredAlliesInKeys(keys, healer, includeElement = false) {
|
||||
const out = [];
|
||||
if (!keys) return out;
|
||||
const set = keys instanceof Set ? keys : (healer && healer.rangeKeys === keys && healer.rangeKeySet ? healer.rangeKeySet : new Set(keys));
|
||||
const through = healer && healer.profile && typeof healer.profile.healThrough === 'function' ? healer.profile.healThrough : null;
|
||||
for (const a of this.allyUnits) {
|
||||
if (!a.alive || !a.deployed || a.hidden || a.kind === 'device') continue;
|
||||
if (!set.has(a.tileR * COLS + a.tileC)) continue;
|
||||
if (a !== healer && (a.s.flags.noHeal || (a.profile && a.profile.noHeal))) continue;
|
||||
if (a !== healer && ((a.s.flags.noHeal && !(through && through(healer, a))) || (a.profile && a.profile.noHeal))) continue;
|
||||
const injured = a.hp < a.s.maxHp - 1e-6;
|
||||
const elem = includeElement && (a.elem.burn + a.elem.neural + a.elem.necrosis + a.elem.apoptosis + a.elem.erosion) > 0;
|
||||
if (injured || elem) out.push(a);
|
||||
|
||||
+3
-2
@@ -155,8 +155,9 @@ export function makeBuff(b) {
|
||||
tags: b.tags ?? [],
|
||||
shield: b.shield ?? (b.mods && b.mods.shield) ?? 0,
|
||||
shieldHits: b.shieldHits ?? 0,
|
||||
// a 屏障 that absorbs one damage type only (damage.js absorbShields): 'phys' | 'arts' | 'true' | 'elemental'; null =
|
||||
// every type (PRTS 术语释义 屏障 "若无特殊说明,屏障可吸收全种类伤害") — 夜莺 S2 法术护盾 "能吸收…法术伤害"
|
||||
// a 屏障 that absorbs one damage type only (damage.js absorbShields): 'phys' | 'arts' | 'true' | 'elemental', or a list
|
||||
// of them (机械师's 屏障: ['phys', 'arts']); null = every type (PRTS 术语释义 屏障 "若无特殊说明,屏障可吸收全种类伤害") —
|
||||
// 夜莺 S2 法术护盾 "能吸收…法术伤害"
|
||||
shieldType: b.shieldType ?? null,
|
||||
persist: !!b.persist,
|
||||
status: b.status ?? null,
|
||||
|
||||
+11
-5
@@ -184,14 +184,16 @@ export function leaderHitCancelled(battle, target, amount) {
|
||||
|
||||
/**
|
||||
* Absorb damage with shields on `target`. Returns the remaining amount. `type` = the damage type: a shield buff with a
|
||||
* `shieldType` absorbs only that type (夜莺 S2 "屏障能吸收…法术伤害"); one without absorbs every type (PRTS 术语释义 屏障
|
||||
* "若无特殊说明,屏障可吸收全种类伤害"). Older shields first (buff order: "优先消耗先生成的屏障").
|
||||
* `shieldType` absorbs only that type (夜莺 S2 "屏障能吸收…法术伤害") — or, a list of types, only those (机械师's 屏障:
|
||||
* BlockDamage PHYSICAL_AND_MAGICAL, buff_template_data mcnist_t_2 / mcnist_s_2_shield: ['phys', 'arts']); one without
|
||||
* absorbs every type (PRTS 术语释义 屏障 "若无特殊说明,屏障可吸收全种类伤害"). Older shields first (buff order:
|
||||
* "优先消耗先生成的屏障").
|
||||
*/
|
||||
export function absorbShields(battle, target, amount, type = null) {
|
||||
if (amount <= 0) return 0;
|
||||
let changed = false;
|
||||
let rest = amount;
|
||||
const absorbs = (b) => !b.shieldType || b.shieldType === type;
|
||||
const absorbs = (b) => !b.shieldType || (Array.isArray(b.shieldType) ? b.shieldType.includes(type) : b.shieldType === type);
|
||||
for (let i = 0; i < target.buffs.length && rest > 0; i++) {
|
||||
const b = target.buffs[i];
|
||||
if (b.shieldHits > 0 && absorbs(b)) {
|
||||
@@ -526,13 +528,17 @@ export function reduceElement(target, amount, el = null) {
|
||||
* with an hpRegen buff, PRTS 备注 "不受治疗加成和禁疗影响") is no 治疗: no 治疗加成 scales it — neither the healing
|
||||
* multipliers nor a `heal` handler (handlers still see it, with `opts.regen`; a change they make to its amount is
|
||||
* ignored).
|
||||
* A healer whose profile names the target in `healThrough(healer, target)` heals it through its 禁疗 — the `noHeal` flag
|
||||
* a summon's 禁疗 sets and the flag `healFree` (not a profile's `noHeal`, 无法被友方治疗): 凯尔希 on her Mon3tr (PRTS
|
||||
* Mon3tr(凯尔希的召唤物) "持有禁疗(可被凯尔希…无视)"; her heal selection takes it too, Battle.injuredAlliesInKeys).
|
||||
*/
|
||||
export function heal(battle, source, target, amount, opts = {}) {
|
||||
if (!target || !target.alive || target.removed || !target.deployed || target.bossPool) return 0;
|
||||
const self = source === target || !!opts.self;
|
||||
if (!self && (target.s.flags.noHeal || (target.profile && target.profile.noHeal))) return 0;
|
||||
const through = !!(source && source.profile && typeof source.profile.healThrough === 'function' && source.profile.healThrough(source, target));
|
||||
if (!self && ((target.s.flags.noHeal && !through) || (target.profile && target.profile.noHeal))) return 0;
|
||||
const regen = !!opts.regen;
|
||||
if (target.s.flags.healFree && !regen && !opts.ignoreHealFree) return 0;
|
||||
if (target.s.flags.healFree && !regen && !opts.ignoreHealFree && !through) return 0;
|
||||
let amt = regen ? amount : amount * (source && source.s ? source.s.healingDealtMul : 1) * target.s.healingTakenMul;
|
||||
if (!(amt > 0) || !Number.isFinite(amt)) return 0;
|
||||
if (battle._hooks.heal) {
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
// dmgMul(battle, unit, target) → number afterHit(battle, unit, target, {dealt,x,y})
|
||||
// canAttack(battle, unit) → bool afterAttack(battle, unit, targets)
|
||||
// skipEnemy(enemy) → bool (an enemy the unit never selects — targeting.js canTargetEnemy; 嵯峨 "不攻击重伤单位")
|
||||
// healThrough(healer, ally) → bool (a healer that selects and heals that ally through its 禁疗 — Battle
|
||||
// injuredAlliesInKeys, damage.js heal; 凯尔希 on her Mon3tr)
|
||||
// hitsFn(battle, unit) → n install(battle, unit) — per-unit hooks, called once at setup
|
||||
// dollNoAttack bool (傀儡师: its <替身> makes no normal attack and casts no skill — 归溟幽灵鲨, kit trait)
|
||||
// tb — the unit's trait blackboard (data `trait.bb`), used for tunables (module upgrades included on elites)
|
||||
|
||||
Reference in new issue
Block a user