feedback5: merge WE1 — fidelity (sim rules): 秘术师 store at the attack check (深靛; 维伊 / 黑键 plug into it), enemy attacks land at their damage frame so a short stun / freeze / sleep / 浮空 / 缴械 / 恐惧 before it cancels the swing, 武者 heal per damage instance through 禁疗, 庇护 the strongest only, PHY-X 不高于 50 %, 链愈师 jumps in the 3×3, a summon readied at its owner's redeploy, Misery's duration skills, 伺夜 S2 in 战术点形态, centurions hit up to block-count targets; merge fixes: 黑键's kit keeps the up() import WE2's S2 cast needs (WE1 dropped it with its tick store — the first regeneration had stored 9288 swallowed errors in diy-114), the 自选 refusal names 集成战略 / 生息演算, tools/golden.mjs prints a missing value, test/golden.test.js fails on any stored engine error; golden: vs WE1 only the W4B / WE2 scenarios differ (roster-042, bond-egirShip-high, coop2-ABYSS-10-boosted, coop2-NORMAL-70-diy, diy-045 / 078 / 114 / 115 / 116)
This commit is contained in:
commit
e2bb090f44
60 files changed
+6888
-6103
No files matched your search
@@ -27,7 +27,7 @@
|
||||
// counter {id} · crit {id} · dp {n, id} · heal {id} · taunt {id} · summon {id, token} · pull {id} · sonic {radius} ·
|
||||
// shield {id} · overload {id} · takeoff {id} · sleep {id} · buff {id, kind} · reveal {id} · dodge (engine kind).
|
||||
|
||||
import { COLS } from '../../../constants.js';
|
||||
import { COLS, TICK } from '../../../constants.js';
|
||||
import { absoluteRangeKeys, sortEnemyTargets } from '../../../targeting.js';
|
||||
import { offsetTile } from '../../../dir.js';
|
||||
import { bodyInKeys, bodyTileReach } from '../../../body.js';
|
||||
@@ -94,6 +94,21 @@ export function onDamagedOn(battle, unit, fn, priority = 0) {
|
||||
return battle.on('damaged', (ctx) => { if (ctx.target === unit) fn(ctx); }, { owner: unit, priority });
|
||||
}
|
||||
|
||||
/**
|
||||
* 庇护 (gamedata_const ba.protect "受到的物理和法术伤害降低相应比例(同名效果取最高)"; PRTS 术语释义 庇护): ONE effect per unit
|
||||
* whoever grants it — battle.applyStrongest under this key, the strongest value holds and a weaker one resumes when it
|
||||
* outlasts it. (遥's bubbles are a separate key, the client's damage_resistance[bonus] — they multiply with it.)
|
||||
*/
|
||||
export const PROTECT = 'protect';
|
||||
/** The mods of a 庇护 value: physical and arts damage taken ×(1 − v). */
|
||||
export const protectMods = (v) => ({ physTakenMul: 1 - v, artsTakenMul: 1 - v });
|
||||
/** A hold that outlives one tick and lapses in the next: refreshed every tick while its condition lasts. */
|
||||
export const PROTECT_TICK_HOLD = 1.5 * TICK;
|
||||
/** Hold 庇护 `value` on `target` for `duration` s (the shared PROTECT effect). */
|
||||
export function holdProtect(battle, target, value, duration, source = null) {
|
||||
if (value > 0) battle.applyStrongest(target, PROTECT, { duration, value, mods: protectMods, source });
|
||||
}
|
||||
|
||||
/** Targetable enemies inside `grid` (relative to the unit; null ⇒ current range), best targets first. */
|
||||
export function enemiesInGrid(battle, unit, grid, { n = 0, priority = null, canHitFly = true, groundOnly = false } = {}) {
|
||||
const keys = grid ? absoluteRangeKeys(grid, unit.tileR, unit.tileC, unit.dir, 0) : unit.rangeKeys;
|
||||
|
||||
@@ -146,10 +146,16 @@ function pullToFront(battle, unit, e, force) {
|
||||
}
|
||||
|
||||
/** Physician module trait (录武官, 华法琳 elites): heals on allies below hp_ratio are ×heal_scale. */
|
||||
function installLowHpHealBonus(battle, unit, tb) {
|
||||
/**
|
||||
* The module trait "治疗生命值低于50%的友方单位时治疗量提升15%" (heal_scale, hp_ratio): the client's module buff filters the
|
||||
* target's HP before the heal with its own comparison — `atOrBelow` for the template heal_scale_up[hpratio][LE] (华法琳's
|
||||
* PHY-X), strictly below otherwise (录武官's reckpr_e_002_tr: LT). [ASSUMED as before: not on herself]
|
||||
*/
|
||||
function installLowHpHealBonus(battle, unit, tb, { atOrBelow = false } = {}) {
|
||||
const s = num(tb.heal_scale, 0), r = num(tb.hp_ratio, 0);
|
||||
if (!(s > 0) || !(r > 0)) return;
|
||||
battle.on('heal', (c) => { if (c.source === unit && c.target !== unit && c.target.hpRatio < r) c.amount *= s; }, { owner: unit });
|
||||
const low = atOrBelow ? (t) => t.hpRatio <= r + 1e-9 : (t) => t.hpRatio < r;
|
||||
battle.on('heal', (c) => { if (c.source === unit && c.target !== unit && low(c.target)) c.amount *= s; }, { owner: unit });
|
||||
}
|
||||
|
||||
// DESIGN §5.6 documents `(bb, chess)`; content/index.js also passes the normalised def — rebuild it when absent.
|
||||
|
||||
@@ -150,13 +150,18 @@ function burstDamageUp(battle, unit, mul) {
|
||||
}, { owner: unit });
|
||||
}
|
||||
|
||||
/** Modules PHY-X / GUA-X: heals on allies below hp_ratio ×heal_scale. */
|
||||
function lowHpHealUp(battle, unit, tb) {
|
||||
/**
|
||||
* Modules PHY-X / GUA-X "治疗生命值低于50%的友方单位时治疗量提升15%": heals on allies below hp_ratio ×heal_scale. The client's
|
||||
* module buff picks its comparison: `atOrBelow` for heal_scale_up[hpratio][LE] (华法琳's PHY-X), strictly below for 塞雷娅's
|
||||
* GUA-X (set_heal_scale_by_hpratio: LT) and 录武官's PHY-X (reckpr_e_002_tr: LT).
|
||||
*/
|
||||
function lowHpHealUp(battle, unit, tb, { atOrBelow = false } = {}) {
|
||||
const mul = num(tb.heal_scale), thr = num(tb.hp_ratio);
|
||||
if (!(mul > 1) || !(thr > 0)) return;
|
||||
const low = atOrBelow ? (t) => t.hpRatio <= thr + 1e-9 : (t) => t.hpRatio < thr;
|
||||
battle.on('heal', (c) => {
|
||||
if (c.source !== unit || c.opts?.regen || !c.target || c.target.side !== 'ally') return;
|
||||
if (c.target.hpRatio < thr) c.amount *= mul;
|
||||
if (low(c.target)) c.amount *= mul;
|
||||
}, { owner: unit });
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user